diff --git a/api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java b/api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
index 79c34d0690f..d2b696d2b6b 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/region/RemoveRegionCmd.java
@@ -33,7 +33,7 @@ import com.cloud.user.Account;
@APICommand(name = "removeRegion", description="Removes specified region", responseObject=SuccessResponse.class)
public class RemoveRegionCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(RemoveRegionCmd.class.getName());
- private static final String s_name = "updateregionresponse";
+ private static final String s_name = "removeregionresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
diff --git a/client/pom.xml b/client/pom.xml
index cda6ab8b4e7..ecf232be7ac 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -65,6 +65,11 @@
cloud-plugin-network-nvp
${project.version}
+
+ org.apache.cloudstack
+ cloud-plugin-snmp-alerts
+ ${project.version}
+
org.apache.cloudstack
cloud-plugin-network-ovs
diff --git a/client/tomcatconf/log4j-cloud.xml.in b/client/tomcatconf/log4j-cloud.xml.in
index 086669376aa..ce4079f9c96 100755
--- a/client/tomcatconf/log4j-cloud.xml.in
+++ b/client/tomcatconf/log4j-cloud.xml.in
@@ -74,6 +74,20 @@ under the License.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -142,6 +156,17 @@ under the License.
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/src/com/cloud/alert/AlertManager.java b/core/src/com/cloud/alert/AlertManager.java
index a24e18c8373..b6d005a5f21 100755
--- a/core/src/com/cloud/alert/AlertManager.java
+++ b/core/src/com/cloud/alert/AlertManager.java
@@ -27,26 +27,27 @@ public interface AlertManager extends Manager {
public static final short ALERT_TYPE_VIRTUAL_NETWORK_PUBLIC_IP = CapacityVO.CAPACITY_TYPE_VIRTUAL_NETWORK_PUBLIC_IP;
public static final short ALERT_TYPE_PRIVATE_IP = CapacityVO.CAPACITY_TYPE_PRIVATE_IP;
public static final short ALERT_TYPE_SECONDARY_STORAGE = CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE;
- public static final short ALERT_TYPE_HOST = 6;
- public static final short ALERT_TYPE_USERVM = 7;
- public static final short ALERT_TYPE_DOMAIN_ROUTER = 8;
- public static final short ALERT_TYPE_CONSOLE_PROXY = 9;
- public static final short ALERT_TYPE_ROUTING = 10; // lost connection to default route (to the gateway)
- public static final short ALERT_TYPE_STORAGE_MISC = 11; // lost connection to default route (to the gateway)
- public static final short ALERT_TYPE_USAGE_SERVER = 12; // lost connection to default route (to the gateway)
- public static final short ALERT_TYPE_MANAGMENT_NODE = 13; // lost connection to default route (to the gateway)
- public static final short ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = 14;
- public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 15;
- public static final short ALERT_TYPE_USERVM_MIGRATE = 16;
- public static final short ALERT_TYPE_VLAN = 17;
- public static final short ALERT_TYPE_SSVM = 18;
- public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 19; // Usage job result
- public static final short ALERT_TYPE_STORAGE_DELETE = 20;
- public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 21; // Generated when we fail to update the resource count
- public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 22;
- public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 23;
- public static final short ALERT_TYPE_LOCAL_STORAGE = 24;
- public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 25; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only
+ public static final short ALERT_TYPE_HOST = 7;
+ public static final short ALERT_TYPE_USERVM = 8;
+ public static final short ALERT_TYPE_DOMAIN_ROUTER = 9;
+ public static final short ALERT_TYPE_CONSOLE_PROXY = 10;
+ public static final short ALERT_TYPE_ROUTING = 11; // lost connection to default route (to the gateway)
+ public static final short ALERT_TYPE_STORAGE_MISC = 12; // lost connection to default route (to the gateway)
+ public static final short ALERT_TYPE_USAGE_SERVER = 13; // lost connection to default route (to the gateway)
+ public static final short ALERT_TYPE_MANAGMENT_NODE = 14; // lost connection to default route (to the gateway)
+ public static final short ALERT_TYPE_DOMAIN_ROUTER_MIGRATE = 15;
+ public static final short ALERT_TYPE_CONSOLE_PROXY_MIGRATE = 16;
+ public static final short ALERT_TYPE_USERVM_MIGRATE = 17;
+ public static final short ALERT_TYPE_VLAN = 18;
+ public static final short ALERT_TYPE_SSVM = 19;
+ public static final short ALERT_TYPE_USAGE_SERVER_RESULT = 20; // Usage job result
+ public static final short ALERT_TYPE_STORAGE_DELETE = 21;
+ public static final short ALERT_TYPE_UPDATE_RESOURCE_COUNT = 22; // Generated when we fail to update the resource
+ // count
+ public static final short ALERT_TYPE_USAGE_SANITY_RESULT = 23;
+ public static final short ALERT_TYPE_DIRECT_ATTACHED_PUBLIC_IP = 24;
+ public static final short ALERT_TYPE_LOCAL_STORAGE = 25;
+ public static final short ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED = 26; // Generated when the resource limit exceeds the limit. Currently used for recurring snapshots only
void clearAlert(short alertType, long dataCenterId, long podId);
diff --git a/plugins/alert-handlers/snmp-alerts/pom.xml b/plugins/alert-handlers/snmp-alerts/pom.xml
new file mode 100644
index 00000000000..b5cebf31b7a
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+ cloudstack-plugins
+ org.apache.cloudstack
+ 4.2.0-SNAPSHOT
+ ../../pom.xml
+
+ 4.0.0
+ Apache CloudStack Plugin - SNMP Alerts
+ cloud-plugin-snmp-alerts
+
+
+
+ org.apache.servicemix.bundles
+ org.apache.servicemix.bundles.snmp4j
+ 2.1.0_1
+
+
+ log4j
+ log4j
+ ${cs.log4j.version}
+
+
+
+
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java
new file mode 100644
index 00000000000..36970a958fd
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/CsSnmpConstants.java
@@ -0,0 +1,45 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+/**
+ *
+ * IMPORTANT
+ *
+ * These OIDs are based on CS-ROOT-MIB MIB file. If there is any change in MIB file
+ * then that should be reflected in this file also *
+ *
+ * suffix 2 due to conflict with SnmpConstants class of snmp4j
+ */
+public class CsSnmpConstants {
+ public static final String CLOUDSTACK = "1.3.6.1.4.1.18060.15";
+
+ public static final String OBJECTS_PREFIX = CLOUDSTACK + ".1.1.";
+
+ public static final String TRAPS_PREFIX = CLOUDSTACK + ".1.2.0.";
+
+ public static final String DATA_CENTER_ID = OBJECTS_PREFIX + 1;
+
+ public static final String POD_ID = OBJECTS_PREFIX + 2;
+
+ public static final String CLUSTER_ID = OBJECTS_PREFIX + 3;
+
+ public static final String MESSAGE = OBJECTS_PREFIX + 4;
+
+ public static final String GENERATION_TIME = OBJECTS_PREFIX + 5;
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java
new file mode 100644
index 00000000000..67420915607
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayout.java
@@ -0,0 +1,107 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import org.apache.log4j.EnhancedPatternLayout;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.util.Date;
+import java.util.StringTokenizer;
+
+public class SnmpEnhancedPatternLayout extends EnhancedPatternLayout {
+ private String _pairDelimiter = "//";
+ private String _keyValueDelimiter = "::";
+
+ private static final int LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER = 9;
+ private static final int LENGTH_OF_STRING_MESSAGE = 8;
+
+ public String getKeyValueDelimeter() {
+ return _keyValueDelimiter;
+ }
+
+ public void setKeyValueDelimiter(String keyValueDelimiter) {
+ this._keyValueDelimiter = keyValueDelimiter;
+ }
+
+ public String getPairDelimiter() {
+ return _pairDelimiter;
+ }
+
+ public void setPairDelimiter(String pairDelimiter) {
+ this._pairDelimiter = pairDelimiter;
+ }
+
+ public SnmpTrapInfo parseEvent(LoggingEvent event) {
+ SnmpTrapInfo snmpTrapInfo = null;
+
+ final String message = event.getRenderedMessage();
+ if (message.contains("alertType") && message.contains("message")) {
+ snmpTrapInfo = new SnmpTrapInfo();
+ final StringTokenizer messageSplitter = new StringTokenizer(message, _pairDelimiter);
+ while (messageSplitter.hasMoreTokens()) {
+ final String pairToken = messageSplitter.nextToken();
+ final StringTokenizer pairSplitter = new StringTokenizer(pairToken, _keyValueDelimiter);
+ String keyToken;
+ String valueToken;
+
+ if (pairSplitter.hasMoreTokens()) {
+ keyToken = pairSplitter.nextToken().trim();
+ } else {
+ break;
+ }
+
+ if (pairSplitter.hasMoreTokens()) {
+ valueToken = pairSplitter.nextToken().trim();
+ } else {
+ break;
+ }
+
+ if (keyToken.equalsIgnoreCase("alertType") && !valueToken.equalsIgnoreCase("null")) {
+ snmpTrapInfo.setAlertType(Short.parseShort(valueToken));
+ } else if (keyToken.equalsIgnoreCase("dataCenterId") && !valueToken.equalsIgnoreCase("null")) {
+ snmpTrapInfo.setDataCenterId(Long.parseLong(valueToken));
+ } else if (keyToken.equalsIgnoreCase("podId") && !valueToken.equalsIgnoreCase("null")) {
+ snmpTrapInfo.setPodId(Long.parseLong(valueToken));
+ } else if (keyToken.equalsIgnoreCase("clusterId") && !valueToken.equalsIgnoreCase("null")) {
+ snmpTrapInfo.setClusterId(Long.parseLong(valueToken));
+ } else if (keyToken.equalsIgnoreCase("message") && !valueToken.equalsIgnoreCase("null")) {
+ snmpTrapInfo.setMessage(getSnmpMessage(message));
+ }
+ }
+
+ snmpTrapInfo.setGenerationTime(new Date(event.getTimeStamp()));
+ }
+ return snmpTrapInfo;
+ }
+
+ private String getSnmpMessage(String message) {
+ int lastIndexOfKeyValueDelimiter = message.lastIndexOf(_keyValueDelimiter);
+ int lastIndexOfMessageInString = message.lastIndexOf("message");
+
+ if (lastIndexOfKeyValueDelimiter - lastIndexOfMessageInString <=
+ LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER) {
+ return message.substring(lastIndexOfKeyValueDelimiter + _keyValueDelimiter.length()).trim();
+ } else if (lastIndexOfMessageInString < lastIndexOfKeyValueDelimiter) {
+ return message.substring(
+ lastIndexOfMessageInString + _keyValueDelimiter.length() + LENGTH_OF_STRING_MESSAGE).trim();
+ }
+
+ return message.substring(message.lastIndexOf("message" + _keyValueDelimiter) +
+ LENGTH_OF_STRING_MESSAGE_AND_KEY_VALUE_DELIMITER).trim();
+ }
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpHelper.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpHelper.java
new file mode 100644
index 00000000000..4bee94bd9d0
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpHelper.java
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.mp.SnmpConstants;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.smi.UnsignedInteger32;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
+
+import java.io.IOException;
+
+public class SnmpHelper {
+ private Snmp _snmp;
+ private CommunityTarget _target;
+
+ public SnmpHelper(String address, String community) {
+ _target = new CommunityTarget();
+ _target.setCommunity(new OctetString(community));
+ _target.setVersion(SnmpConstants.version2c);
+ _target.setAddress(new UdpAddress(address));
+ try {
+ _snmp = new Snmp(new DefaultUdpTransportMapping());
+ } catch (IOException e) {
+ _snmp = null;
+ throw new CloudRuntimeException(" Error in crearting snmp object, " + e.getMessage());
+ }
+ }
+
+ public void sendSnmpTrap(SnmpTrapInfo snmpTrapInfo) {
+ try {
+ if (_snmp != null) {
+ _snmp.send(createPDU(snmpTrapInfo), _target, null, null);
+ }
+ } catch (IOException e) {
+ throw new CloudRuntimeException(" Error in sending SNMP Trap, " + e.getMessage());
+ }
+ }
+
+ private PDU createPDU(SnmpTrapInfo snmpTrapInfo) {
+ PDU trap = new PDU();
+ trap.setType(PDU.TRAP);
+
+ int alertType = snmpTrapInfo.getAlertType() + 1;
+ if (alertType > 0) {
+ trap.add(new VariableBinding(SnmpConstants.snmpTrapOID, getOID(CsSnmpConstants.TRAPS_PREFIX + alertType)));
+ if (snmpTrapInfo.getDataCenterId() != 0) {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.DATA_CENTER_ID),
+ new UnsignedInteger32(snmpTrapInfo.getDataCenterId())));
+ }
+
+ if (snmpTrapInfo.getPodId() != 0) {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.POD_ID), new UnsignedInteger32(snmpTrapInfo
+ .getPodId())));
+ }
+
+ if (snmpTrapInfo.getClusterId() != 0) {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.CLUSTER_ID), new UnsignedInteger32(snmpTrapInfo
+ .getClusterId())));
+ }
+
+ if (snmpTrapInfo.getMessage() != null) {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.MESSAGE), new OctetString(snmpTrapInfo.getMessage
+ ())));
+ } else {
+ throw new CloudRuntimeException(" What is the use of alert without message ");
+ }
+
+ if (snmpTrapInfo.getGenerationTime() != null) {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.GENERATION_TIME),
+ new OctetString(snmpTrapInfo.getGenerationTime().toString())));
+ } else {
+ trap.add(new VariableBinding(getOID(CsSnmpConstants.GENERATION_TIME)));
+ }
+ } else {
+ throw new CloudRuntimeException(" Invalid alert Type ");
+ }
+
+ return trap;
+ }
+
+ private OID getOID(String oidString) {
+ return new OID(oidString);
+ }
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java
new file mode 100644
index 00000000000..eaa4a132b7e
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapAppender.java
@@ -0,0 +1,207 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import com.cloud.utils.net.NetUtils;
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.spi.ErrorCode;
+import org.apache.log4j.spi.LoggingEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class SnmpTrapAppender extends AppenderSkeleton {
+ private String _delimiter = ",";
+ private String _snmpManagerIpAddresses;
+ private String _snmpManagerPorts;
+ private String _snmpManagerCommunities;
+
+ private String _oldSnmpManagerIpAddresses = null;
+ private String _oldSnmpManagerPorts = null;
+ private String _oldSnmpManagerCommunities = null;
+
+ private List _ipAddresses = null;
+ private List _communities = null;
+ private List _ports = null;
+
+ List _snmpHelpers = new ArrayList();
+
+ @Override
+ protected void append(LoggingEvent event) {
+ SnmpEnhancedPatternLayout snmpEnhancedPatternLayout;
+
+ if (getLayout() == null) {
+ errorHandler.error("No layout set for the Appender named [" + getName() + ']', null,
+ ErrorCode.MISSING_LAYOUT);
+ return;
+ }
+
+ if (getLayout() instanceof SnmpEnhancedPatternLayout) {
+ snmpEnhancedPatternLayout = (SnmpEnhancedPatternLayout) getLayout();
+ } else {
+ return;
+ }
+
+ if (!isAsSevereAsThreshold(event.getLevel())) {
+ return;
+ }
+
+ SnmpTrapInfo snmpTrapInfo = snmpEnhancedPatternLayout.parseEvent(event);
+
+ if (snmpTrapInfo != null && !_snmpHelpers.isEmpty()) {
+ for (SnmpHelper helper : _snmpHelpers) {
+ try {
+ helper.sendSnmpTrap(snmpTrapInfo);
+ } catch (Exception e) {
+ errorHandler.error(e.getMessage());
+ }
+ }
+ }
+ }
+
+ void setSnmpHelpers() {
+ if (_snmpManagerIpAddresses == null || _snmpManagerIpAddresses.trim().isEmpty() || _snmpManagerCommunities ==
+ null || _snmpManagerCommunities.trim().isEmpty() || _snmpManagerPorts == null ||
+ _snmpManagerPorts.trim().isEmpty()) {
+ reset();
+ return;
+ }
+
+ if (_oldSnmpManagerIpAddresses != null && _oldSnmpManagerIpAddresses.equals(_snmpManagerIpAddresses) &&
+ _oldSnmpManagerCommunities.equals(_snmpManagerCommunities) &&
+ _oldSnmpManagerPorts.equals(_snmpManagerPorts)) {
+ return;
+ }
+
+ _oldSnmpManagerIpAddresses = _snmpManagerIpAddresses;
+ _oldSnmpManagerPorts = _snmpManagerPorts;
+ _oldSnmpManagerCommunities = _snmpManagerCommunities;
+
+ _ipAddresses = parse(_snmpManagerIpAddresses);
+ _communities = parse(_snmpManagerCommunities);
+ _ports = parse(_snmpManagerPorts);
+
+ if (!(_ipAddresses.size() == _communities.size() && _ipAddresses.size() == _ports.size())) {
+ reset();
+ errorHandler.error(" size of ip addresses , communities, " + "and ports list doesn't match, " +
+ "setting all to null");
+ return;
+ }
+
+ if (!validateIpAddresses() || !validatePorts()) {
+ reset();
+ errorHandler.error(" Invalid format for the IP Addresses or Ports parameter ");
+ return;
+ }
+
+ String address;
+
+ for (int i = 0; i < _ipAddresses.size(); i++) {
+ address = _ipAddresses.get(i) + "/" + _ports.get(i);
+ try {
+ _snmpHelpers.add(new SnmpHelper(address, _communities.get(i)));
+ } catch (Exception e) {
+ errorHandler.error(e.getMessage());
+ }
+ }
+ }
+
+ private void reset() {
+ _ipAddresses = null;
+ _communities = null;
+ _ports = null;
+ _snmpHelpers.clear();
+ }
+
+ @Override
+ public void close() {
+ if (!closed) closed = true;
+ }
+
+ @Override
+ public boolean requiresLayout() {
+ return true;
+ }
+
+ private List parse(String str) {
+ List result = new ArrayList();
+
+ final StringTokenizer tokenizer = new StringTokenizer(str, _delimiter);
+ while (tokenizer.hasMoreTokens()) {
+ result.add(tokenizer.nextToken().trim());
+ }
+ return result;
+ }
+
+ private boolean validatePorts() {
+ for (String port : _ports) {
+ if (!NetUtils.isValidPort(port)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean validateIpAddresses() {
+ for (String ipAddress : _ipAddresses) {
+ if (ipAddress.trim().equalsIgnoreCase("localhost")) {
+ continue;
+ }
+ if (!NetUtils.isValidIp(ipAddress)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public String getSnmpManagerIpAddresses() {
+ return _snmpManagerIpAddresses;
+ }
+
+ public void setSnmpManagerIpAddresses(String snmpManagerIpAddresses) {
+ this._snmpManagerIpAddresses = snmpManagerIpAddresses;
+ setSnmpHelpers();
+ }
+
+ public String getSnmpManagerPorts() {
+ return _snmpManagerPorts;
+ }
+
+ public void setSnmpManagerPorts(String snmpManagerPorts) {
+ this._snmpManagerPorts = snmpManagerPorts;
+ setSnmpHelpers();
+ }
+
+ public String getSnmpManagerCommunities() {
+ return _snmpManagerCommunities;
+ }
+
+ public void setSnmpManagerCommunities(String snmpManagerCommunities) {
+ this._snmpManagerCommunities = snmpManagerCommunities;
+ setSnmpHelpers();
+ }
+
+ public String getDelimiter() {
+ return _delimiter;
+ }
+
+ public void setDelimiter(String delimiter) {
+ this._delimiter = delimiter;
+ }
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java
new file mode 100644
index 00000000000..71bfee02cb6
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/src/org/apache/cloudstack/alert/snmp/SnmpTrapInfo.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import java.util.Date;
+
+public class SnmpTrapInfo {
+ private String message;
+ private long podId;
+ private long dataCenterId;
+ private long clusterId;
+ private Date generationTime;
+ private short alertType;
+
+ public SnmpTrapInfo() {
+ }
+
+ public SnmpTrapInfo(short alertType, long dataCenterId, long podId, long clusterId, String message,
+ Date generationTime) {
+ this.podId = podId;
+ this.alertType = alertType;
+ this.clusterId = clusterId;
+ this.dataCenterId = dataCenterId;
+ this.generationTime = generationTime;
+ this.message = message;
+ }
+
+ public short getAlertType() {
+ return alertType;
+ }
+
+ public void setAlertType(short alertType) {
+ this.alertType = alertType;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public long getPodId() {
+ return podId;
+ }
+
+ public void setPodId(long podId) {
+ this.podId = podId;
+ }
+
+ public long getDataCenterId() {
+ return dataCenterId;
+ }
+
+ public void setDataCenterId(long dataCenterId) {
+ this.dataCenterId = dataCenterId;
+ }
+
+ public long getClusterId() {
+ return clusterId;
+ }
+
+ public void setClusterId(long clusterId) {
+ this.clusterId = clusterId;
+ }
+
+ public Date getGenerationTime() {
+ return generationTime;
+ }
+
+ public void setGenerationTime(Date generationTime) {
+ this.generationTime = generationTime;
+ }
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java b/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java
new file mode 100644
index 00000000000..b903a1e18b9
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpEnhancedPatternLayoutTest.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.naming.ConfigurationException;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SnmpEnhancedPatternLayoutTest {
+ SnmpEnhancedPatternLayout _snmpEnhancedPatternLayout = new SnmpEnhancedPatternLayout();
+
+ @Before
+ public void setUp() throws ConfigurationException {
+ _snmpEnhancedPatternLayout.setKeyValueDelimiter("::");
+ _snmpEnhancedPatternLayout.setPairDelimiter("//");
+ }
+
+ @Test
+ public void parseAlertTest() {
+ LoggingEvent event = mock(LoggingEvent.class);
+ setMessage(" alertType:: 14 // dataCenterId:: 1 // podId:: 1 // " + "clusterId:: null // message:: Management" +
+ " network CIDR is not configured originally. Set it default to 10.102.192.0/22", event);
+ SnmpTrapInfo info = _snmpEnhancedPatternLayout.parseEvent(event);
+ commonAssertions(info, "Management network CIDR is not configured originally. Set it default to 10.102.192" +
+ ".0/22");
+ }
+
+ @Test
+ public void ParseAlertWithPairDelimeterInMessageTest() {
+ LoggingEvent event = mock(LoggingEvent.class);
+ setMessage(" alertType:: 14 // dataCenterId:: 1 // podId:: 1 // " + "clusterId:: null // message:: Management" +
+ " //network CIDR is not configured originally. Set it default to 10.102.192.0/22", event);
+ SnmpTrapInfo info = _snmpEnhancedPatternLayout.parseEvent(event);
+ commonAssertions(info, "Management //network CIDR is not configured originally. Set it default to 10.102.192" +
+ ".0/22");
+ }
+
+ @Test
+ public void ParseAlertWithKeyValueDelimeterInMessageTest() {
+ LoggingEvent event = mock(LoggingEvent.class);
+ setMessage(" alertType:: 14 // dataCenterId:: 1 // podId:: 1 // " + "clusterId:: null // message:: Management" +
+ " ::network CIDR is not configured originally. Set it default to 10.102.192.0/22", event);
+ SnmpTrapInfo info = _snmpEnhancedPatternLayout.parseEvent(event);
+ commonAssertions(info, "Management ::network CIDR is not configured originally. Set it default to 10.102.192" +
+ ".0/22");
+ }
+
+ @Test
+ public void parseRandomTest() {
+ LoggingEvent event = mock(LoggingEvent.class);
+ when(event.getRenderedMessage()).thenReturn("Problem clearing email alert");
+ assertNull(" Null value was expected ", _snmpEnhancedPatternLayout.parseEvent(event));
+ }
+
+ private void commonAssertions(SnmpTrapInfo info, String message) {
+ assertEquals(" alert type not as expected ", 14, info.getAlertType());
+ assertEquals(" data center id not as expected ", 1, info.getDataCenterId());
+ assertEquals(" pod id os not as expected ", 1, info.getPodId());
+ assertEquals(" cluster id is not as expected ", 0, info.getClusterId());
+ assertNotNull(" generation time is set to null", info.getGenerationTime());
+ assertEquals(" message is not as expected ", message, info.getMessage());
+ }
+
+ private void setMessage(String message, LoggingEvent event) {
+ when(event.getRenderedMessage()).thenReturn(message);
+ }
+}
\ No newline at end of file
diff --git a/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java b/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java
new file mode 100644
index 00000000000..2a65d90acc2
--- /dev/null
+++ b/plugins/alert-handlers/snmp-alerts/test/org/apache/cloudstack/alert/snmp/SnmpTrapAppenderTest.java
@@ -0,0 +1,86 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License
+
+package org.apache.cloudstack.alert.snmp;
+
+import org.apache.log4j.spi.LoggingEvent;
+import org.junit.Test;
+import org.mockito.Mock;
+
+import java.util.List;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+public class SnmpTrapAppenderTest {
+ SnmpTrapAppender _appender = new SnmpTrapAppender();
+ LoggingEvent _event = mock(LoggingEvent.class);
+ SnmpEnhancedPatternLayout _snmpEnhancedPatternLayout = mock(SnmpEnhancedPatternLayout.class);
+ @Mock
+ List snmpHelpers;
+
+ @Test
+ public void appendTest() {
+ _appender.setSnmpManagerIpAddresses("10.1.1.1,10.1.1.2");
+ _appender.setSnmpManagerPorts("162,164");
+ _appender.setSnmpManagerCommunities("public,snmp");
+
+ _appender.setSnmpHelpers();
+ assertEquals(" error snmpHelper list size not as expected ", _appender._snmpHelpers.size(), 2);
+ }
+
+ @Test
+ public void InvalidInputTest() {
+ _appender.setSnmpManagerIpAddresses("10.1.1.1,10.1.1.2");
+ _appender.setSnmpManagerPorts("162,164");
+ _appender.setSnmpManagerCommunities("public");
+
+ _appender.setSnmpHelpers();
+ assertTrue(" list was expected to be empty", _appender._snmpHelpers.isEmpty());
+ }
+
+ @Test
+ public void InvalidIpInputTest() {
+ _appender.setSnmpManagerIpAddresses("10.1.1,10.1.1.2");
+ _appender.setSnmpManagerPorts("162,164");
+ _appender.setSnmpManagerCommunities("public,snmp");
+
+ _appender.setSnmpHelpers();
+ assertTrue(" list was expected to be empty", _appender._snmpHelpers.isEmpty());
+ }
+
+ @Test
+ public void InvalidPortInputTest() {
+ _appender.setSnmpManagerIpAddresses("10.1.1,10.1.1.2");
+ _appender.setSnmpManagerPorts("162,164897489978");
+ _appender.setSnmpManagerCommunities("public,snmp");
+
+ _appender.setSnmpHelpers();
+ assertTrue(" list was expected to be empty", _appender._snmpHelpers.isEmpty());
+ }
+
+ @Test
+ public void mismatchListLengthInputTest() {
+ _appender.setSnmpManagerIpAddresses("10.1.1");
+ _appender.setSnmpManagerPorts("162,164");
+ _appender.setSnmpManagerCommunities("public,snmp");
+
+ _appender.setSnmpHelpers();
+ assertTrue(" list was expected to be empty", _appender._snmpHelpers.isEmpty());
+ }
+}
\ No newline at end of file
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 88f617b4560..5d31a72ee91 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -57,6 +57,7 @@
network-elements/dns-notifier
storage/image/s3
storage/volume/solidfire
+ alert-handlers/snmp-alerts
diff --git a/server/src/com/cloud/alert/AlertManagerImpl.java b/server/src/com/cloud/alert/AlertManagerImpl.java
index f8a8fd8b1b9..a45482fd4ef 100755
--- a/server/src/com/cloud/alert/AlertManagerImpl.java
+++ b/server/src/com/cloud/alert/AlertManagerImpl.java
@@ -84,6 +84,7 @@ import com.sun.mail.smtp.SMTPTransport;
@Local(value={AlertManager.class})
public class AlertManagerImpl extends ManagerBase implements AlertManager {
private static final Logger s_logger = Logger.getLogger(AlertManagerImpl.class.getName());
+ private static final Logger s_alertsLogger = Logger.getLogger("org.apache.cloudstack.alerts");
private static final long INITIAL_CAPACITY_CHECK_DELAY = 30L * 1000L; // thirty seconds expressed in milliseconds
@@ -256,6 +257,9 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager {
try {
if (_emailAlert != null) {
_emailAlert.sendAlert(alertType, dataCenterId, podId, null, subject, body);
+ } else {
+ s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: "
+ + podId + " // clusterId:: " + null + " // message:: " + subject );
}
} catch (Exception ex) {
s_logger.error("Problem sending email alert", ex);
@@ -789,6 +793,8 @@ public class AlertManagerImpl extends ManagerBase implements AlertManager {
// TODO: make sure this handles SSL transport (useAuth is true) and regular
public void sendAlert(short alertType, long dataCenterId, Long podId, Long clusterId, String subject, String content) throws MessagingException, UnsupportedEncodingException {
+ s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " +
+ podId + " // clusterId:: " + null + " // message:: " + subject);
AlertVO alert = null;
if ((alertType != AlertManager.ALERT_TYPE_HOST) &&
(alertType != AlertManager.ALERT_TYPE_USERVM) &&
diff --git a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
index 8b2a1441151..0f454cdb582 100755
--- a/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
+++ b/server/src/com/cloud/deploy/HypervisorVmPlannerSelector.java
@@ -18,12 +18,16 @@ package com.cloud.deploy;
import javax.ejb.Local;
+import org.apache.log4j.Logger;
+
import com.cloud.deploy.DeploymentPlanner.AllocationAlgorithm;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.vm.UserVmVO;
@Local(value = {DeployPlannerSelector.class})
public class HypervisorVmPlannerSelector extends AbstractDeployPlannerSelector {
+ private static final Logger s_logger = Logger.getLogger(HypervisorVmPlannerSelector.class);
+
@Override
public String selectPlanner(UserVmVO vm) {
if (vm.getHypervisorType() != HypervisorType.BareMetal) {
@@ -38,6 +42,10 @@ public class HypervisorVmPlannerSelector extends AbstractDeployPlannerSelector {
|| _allocationAlgorithm.equals(AllocationAlgorithm.userconcentratedpod_firstfit.toString())) {
return "UserConcentratedPodPlanner";
}
+ } else {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("The allocation algorithm is null, cannot select the planner");
+ }
}
}
diff --git a/server/src/com/cloud/event/ActionEventInterceptor.java b/server/src/com/cloud/event/ActionEventInterceptor.java
index fb89498ffce..a6c2565510e 100644
--- a/server/src/com/cloud/event/ActionEventInterceptor.java
+++ b/server/src/com/cloud/event/ActionEventInterceptor.java
@@ -19,22 +19,29 @@ package com.cloud.event;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
+import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import com.cloud.user.UserContext;
+import com.cloud.utils.component.ComponentMethodProxyCache;
public class ActionEventInterceptor {
+ private static final Logger s_logger = Logger.getLogger(ActionEventInterceptor.class);
public ActionEventInterceptor() {
}
public Object AroundAnyMethod(ProceedingJoinPoint call) throws Throwable {
MethodSignature methodSignature = (MethodSignature)call.getSignature();
- Method targetMethod = methodSignature.getMethod();
- if(needToIntercept(targetMethod)) {
+
+ // Note: AOP for ActionEvent is triggered annotation, no need to check the annotation on method again
+ Method targetMethod = ComponentMethodProxyCache.getTargetMethod(
+ methodSignature.getMethod(), call.getTarget());
+
+ if(targetMethod != null) {
EventVO event = interceptStart(targetMethod);
-
+
boolean success = true;
Object ret = null;
try {
@@ -49,6 +56,8 @@ public class ActionEventInterceptor {
}
}
return ret;
+ } else {
+ s_logger.error("Unable to find the proxied method behind. Method: " + methodSignature.getMethod().getName());
}
return call.proceed();
}
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java
index 8c665ad1eee..3b0ec0f943b 100755
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -106,10 +106,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.utils.script.Script;
import com.cloud.uuididentity.dao.IdentityDao;
-import org.apache.cloudstack.region.RegionVO;
-import org.apache.cloudstack.region.dao.RegionDao;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
+
@Component
public class ConfigurationServerImpl extends ManagerBase implements ConfigurationServer {
@@ -152,7 +149,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
public void persistDefaultValues() throws InternalErrorException {
fixupScriptFileAttribute();
-
+
// Create system user and admin user
saveUser();
@@ -337,23 +334,20 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
@DB
protected void saveUser() {
- int region_id = _configDao.getRegionId();
// insert system account
- String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, region_id) VALUES (1, UUID(), 'system', '1', '1', ?)";
+ String insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id) VALUES (1, UUID(), 'system', '1', '1')";
Transaction txn = Transaction.currentTxn();
try {
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
- stmt.setInt(1, region_id);
stmt.executeUpdate();
} catch (SQLException ex) {
}
// insert system user
- insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, region_id)" +
- " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now(), ?)";
+ insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created)" +
+ " VALUES (1, UUID(), 'system', RAND(), 1, 'system', 'cloud', now())";
txn = Transaction.currentTxn();
try {
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
- stmt.setInt(1, region_id);
stmt.executeUpdate();
} catch (SQLException ex) {
}
@@ -366,23 +360,21 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
String lastname = "cloud";
// create an account for the admin user first
- insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id, region_id) VALUES (" + id + ", UUID(), '" + username + "', '1', '1', ?)";
+ insertSql = "INSERT INTO `cloud`.`account` (id, uuid, account_name, type, domain_id) VALUES (" + id + ", UUID(), '" + username + "', '1', '1')";
txn = Transaction.currentTxn();
try {
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
- stmt.setInt(1, region_id);
stmt.executeUpdate();
} catch (SQLException ex) {
}
// now insert the user
- insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state, region_id) " +
- "VALUES (" + id + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled', ?)";
+ insertSql = "INSERT INTO `cloud`.`user` (id, uuid, username, password, account_id, firstname, lastname, created, state) " +
+ "VALUES (" + id + ", UUID(), '" + username + "', RAND(), 2, '" + firstname + "','" + lastname + "',now(), 'disabled')";
txn = Transaction.currentTxn();
try {
PreparedStatement stmt = txn.prepareAutoCloseStatement(insertSql);
- stmt.setInt(1, region_id);
stmt.executeUpdate();
} catch (SQLException ex) {
}
@@ -708,15 +700,15 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
}
}
-
+
private void fixupScriptFileAttribute() {
- // TODO : this is a hacking fix to workaround that executable bit is not preserved in WAR package
+ // TODO : this is a hacking fix to workaround that executable bit is not preserved in WAR package
String scriptPath = Script.findScript("", "scripts/vm/systemvm/injectkeys.sh");
if(scriptPath != null) {
File file = new File(scriptPath);
if(!file.canExecute()) {
s_logger.info("Some of the shell script files may not have executable bit set. Fixup...");
-
+
String cmd = "chmod ugo+x " + scriptPath;
s_logger.info("Executing " + cmd);
String result = Script.runSimpleBashScript(cmd);
diff --git a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
index 5bd749fe842..8f9be0f5d57 100755
--- a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
+++ b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java
@@ -162,6 +162,10 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker {
_upgradeMap.put("4.0.0", new DbUpgrade[] { new Upgrade40to41(), new Upgrade410to420() });
+ _upgradeMap.put("4.0.1", new DbUpgrade[] { new Upgrade40to41(), new Upgrade410to420() });
+
+ _upgradeMap.put("4.0.2", new DbUpgrade[] { new Upgrade40to41(), new Upgrade410to420() });
+
_upgradeMap.put("4.1.0", new DbUpgrade[] { new Upgrade410to420() });
}
diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
index 6815b0d43bc..297e71118ad 100644
--- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
+++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java
@@ -53,7 +53,7 @@ public class ConsoleProxyHttpHandlerHelper {
ConsoleProxyClientParam param = encryptor.decryptObject(ConsoleProxyClientParam.class, map.get("token"));
// make sure we get information from token only
- map.clear();
+ guardUserInput(map);
if(param != null) {
if(param.getClientHostAddress() != null)
map.put("host", param.getClientHostAddress());
@@ -72,9 +72,19 @@ public class ConsoleProxyHttpHandlerHelper {
}
} else {
// we no longer accept information from parameter other than token
- map.clear();
+ guardUserInput(map);
}
return map;
}
+
+ private static void guardUserInput(Map map) {
+ map.remove("host");
+ map.remove("port");
+ map.remove("tag");
+ map.remove("sid");
+ map.remove("consoleurl");
+ map.remove("sessionref");
+ map.remove("ticket");
+ }
}
diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql
index 865fbd3181c..0f316a5acdd 100644
--- a/setup/db/db/schema-40to410.sql
+++ b/setup/db/db/schema-40to410.sql
@@ -261,7 +261,7 @@ CREATE TABLE `cloud`.`region` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client/api');
+INSERT INTO `cloud`.`region` values ('1','Local','http://localhost:8080/client');
INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Account Defaults', 'DEFAULT', 'management-server', 'max.account.cpus', '40', 'The default maximum number of cpu cores that can be used for an account');
diff --git a/tools/cli/cloudmonkey/__init__.py b/tools/cli/cloudmonkey/__init__.py
index e4c4e6d24f1..cf689e79480 100644
--- a/tools/cli/cloudmonkey/__init__.py
+++ b/tools/cli/cloudmonkey/__init__.py
@@ -16,6 +16,8 @@
# under the License.
try:
- from config import __version__
+ from config import __version__, __description__
+ from config import __maintainer__, __maintaineremail__
+ from config import __project__, __projecturl__, __projectemail__
except ImportError, e:
print e
diff --git a/tools/cli/cloudmonkey/cachemaker.py b/tools/cli/cloudmonkey/cachemaker.py
index 42a077ad928..8ac123caa4b 100644
--- a/tools/cli/cloudmonkey/cachemaker.py
+++ b/tools/cli/cloudmonkey/cachemaker.py
@@ -21,7 +21,7 @@ try:
import os
import types
- from config import cache_file
+ from config import config_fields
except ImportError, e:
import sys
print "ImportError", e
@@ -168,6 +168,7 @@ def main(json_file):
f.close()
if __name__ == "__main__":
+ cache_file = config_fields['core']['cache_file']
print "[cachemaker] Pre-caching using user's cloudmonkey cache", cache_file
if os.path.exists(cache_file):
main(cache_file)
diff --git a/tools/cli/cloudmonkey/cloudmonkey.py b/tools/cli/cloudmonkey/cloudmonkey.py
index 25422412613..f750c3afa8d 100644
--- a/tools/cli/cloudmonkey/cloudmonkey.py
+++ b/tools/cli/cloudmonkey/cloudmonkey.py
@@ -29,8 +29,9 @@ try:
import types
from cachemaker import loadcache, savecache, monkeycache, splitverbsubject
- from config import __version__, cache_file
- from config import read_config, write_config
+ from config import __version__, __description__, __projecturl__
+ from config import read_config, write_config, config_file
+ from optparse import OptionParser
from prettytable import PrettyTable
from printer import monkeyprint
from requester import monkeyrequest
@@ -63,13 +64,14 @@ class CloudMonkeyShell(cmd.Cmd, object):
intro = ("☁ Apache CloudStack 🐵 cloudmonkey " + __version__ +
". Type help or ? to list commands.\n")
ruler = "="
- cache_file = cache_file
config_options = []
verbs = []
- def __init__(self, pname):
+ def __init__(self, pname, cfile):
self.program_name = pname
- self.config_options = read_config(self.get_attr, self.set_attr)
+ self.config_file = cfile
+ self.config_options = read_config(self.get_attr, self.set_attr,
+ self.config_file)
self.loadcache()
self.prompt = self.prompt.strip() + " " # Cosmetic fix for prompt
@@ -364,7 +366,7 @@ class CloudMonkeyShell(cmd.Cmd, object):
key, value = (args[0], args[2])
setattr(self, key, value) # keys and attributes should have same names
self.prompt = self.prompt.strip() + " " # prompt fix
- write_config(self.get_attr)
+ write_config(self.get_attr, self.config_file)
def complete_set(self, text, line, begidx, endidx):
mline = line.partition(" ")[2]
@@ -458,10 +460,37 @@ class CloudMonkeyShell(cmd.Cmd, object):
return self.do_EOF(args)
+class MonkeyParser(OptionParser):
+ def format_help(self, formatter=None):
+ if formatter is None:
+ formatter = self.formatter
+ result = []
+ if self.usage:
+ result.append("Usage: cloudmonkey [options] [cmds] [params]\n\n")
+ if self.description:
+ result.append(self.format_description(formatter) + "\n")
+ result.append(self.format_option_help(formatter))
+ result.append("\nTry cloudmonkey [help|?]\n")
+ return "".join(result)
+
+
def main():
- shell = CloudMonkeyShell(sys.argv[0])
+ parser = MonkeyParser()
+ parser.add_option("-c", "--config-file",
+ dest="cfile", default=config_file,
+ help="config file for cloudmonkey", metavar="FILE")
+ parser.add_option("-v", "--version",
+ action="store_true", dest="version", default=False,
+ help="prints cloudmonkey version information")
+
+ (options, args) = parser.parse_args()
+ if options.version:
+ print "cloudmonkey", __version__
+ print __description__, "(%s)" % __projecturl__
+
+ shell = CloudMonkeyShell(sys.argv[0], options.cfile)
if len(sys.argv) > 1:
- shell.onecmd(' '.join(sys.argv[1:]))
+ shell.onecmd(' '.join(args))
else:
shell.cmdloop()
diff --git a/tools/cli/cloudmonkey/config.py b/tools/cli/cloudmonkey/config.py
index 6a5feab8d12..4a4aa99cdc8 100644
--- a/tools/cli/cloudmonkey/config.py
+++ b/tools/cli/cloudmonkey/config.py
@@ -19,6 +19,12 @@
# Use following rules for versioning:
# -
__version__ = "4.1.0-0"
+__description__ = "Command Line Interface for Apache CloudStack"
+__maintainer__ = "Rohit Yadav"
+__maintaineremail__ = "bhaisaab@apache.org"
+__project__ = "The Apache CloudStack Team"
+__projectemail__ = "cloudstack-dev@incubator.apache.org"
+__projecturl__ = "http://incubator.apache.org/cloudstack"
try:
import os
@@ -36,14 +42,14 @@ iterable_type = ['set', 'list', 'object']
config_dir = expanduser('~/.cloudmonkey')
config_file = expanduser(config_dir + '/config')
-cache_file = expanduser(config_dir + '/cache')
# cloudmonkey config fields
-config_fields = {'core': {}, 'ui': {}, 'server': {}, 'user': {}}
+config_fields = {'core': {}, 'server': {}, 'user': {}, 'ui': {}}
# core
config_fields['core']['asyncblock'] = 'true'
config_fields['core']['paramcompletion'] = 'false'
+config_fields['core']['cache_file'] = expanduser(config_dir + '/cache')
config_fields['core']['history_file'] = expanduser(config_dir + '/history')
config_fields['core']['log_file'] = expanduser(config_dir + '/log')
@@ -64,8 +70,8 @@ config_fields['user']['apikey'] = ''
config_fields['user']['secretkey'] = ''
-def write_config(get_attr, first_time=False):
- global config_fields, config_file
+def write_config(get_attr, config_file, first_time=False):
+ global config_fields
config = ConfigParser()
for section in config_fields.keys():
config.add_section(section)
@@ -79,8 +85,8 @@ def write_config(get_attr, first_time=False):
return config
-def read_config(get_attr, set_attr):
- global config_fields, config_dir, config_file
+def read_config(get_attr, set_attr, config_file):
+ global config_fields, config_dir
if not os.path.exists(config_dir):
os.makedirs(config_dir)
@@ -95,7 +101,7 @@ def read_config(get_attr, set_attr):
except IOError, e:
print "Error: config_file not found", e
else:
- config = write_config(get_attr, True)
+ config = write_config(get_attr, config_file, True)
print "Welcome! Using `set` configure the necessary settings:"
print " ".join(sorted(config_options))
print "Config file:", config_file
diff --git a/tools/cli/setup.py b/tools/cli/setup.py
index 9624115ed5f..4c7b2978b2f 100644
--- a/tools/cli/setup.py
+++ b/tools/cli/setup.py
@@ -22,13 +22,9 @@ except ImportError:
use_setuptools()
from setuptools import setup, find_packages
-from cloudmonkey import __version__
-
-name = 'cloudmonkey'
-version = __version__
-requires = ['Pygments>=1.5',
- 'prettytable>=0.6',
- ]
+from cloudmonkey import __version__, __description__
+from cloudmonkey import __maintainer__, __maintaineremail__
+from cloudmonkey import __project__, __projecturl__, __projectemail__
try:
import readline
@@ -36,20 +32,22 @@ except ImportError:
requires.append('readline')
setup(
- name = name,
- version = version,
- author = "The Apache CloudStack Team",
- author_email = "cloudstack-dev@incubator.apache.org",
- maintainer = "Rohit Yadav",
- maintainer_email = "bhaisaab@apache.org",
- url = "http://incubator.apache.org/cloudstack",
- description = "Command Line Interface for Apache CloudStack",
- long_description = "cloudmonkey is a command line interface for Apache "
- "CloudStack powered by CloudStack Marvin",
+ name = 'cloudmonkey',
+ version = __version__,
+ author = __project__,
+ author_email = __projectemail__,
+ maintainer = __maintainer__,
+ maintainer_email = __maintaineremail__,
+ url = __projecturl__,
+ description = __description__,
+ long_description = "cloudmonkey is a CLI for Apache CloudStack",
platforms = ("Any",),
license = 'ASL 2.0',
packages = find_packages(),
- install_requires = requires,
+ install_requires = [
+ 'Pygments>=1.5',
+ 'prettytable>=0.6',
+ ],
include_package_data = True,
zip_safe = False,
classifiers = [
diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js
index ad26b34196e..8bcdff91574 100644
--- a/ui/scripts/sharedFunctions.js
+++ b/ui/scripts/sharedFunctions.js
@@ -400,20 +400,28 @@ cloudStack.converters = {
case 4 : return _l('label.public.ips');
case 5 : return _l('label.management.ips');
case 6 : return _l('label.secondary.storage');
- case 7 : return _l('label.vlan');
- case 8 : return _l('label.direct.ips');
- case 9 : return _l('label.local.storage');
+ case 7 : return _l('label.host');
+ case 9 : return _l('label.domain.router');
+ case 10 : return _l('label.console.proxy');
- // These are old values -- can be removed in the future
- case 10 : return "Routing Host";
- case 11 : return "Storage";
- case 12 : return "Usage Server";
- case 13 : return "Management Server";
- case 14 : return "Domain Router";
- case 15 : return "Console Proxy";
- case 16 : return "User VM";
- case 17 : return "VLAN";
- case 18 : return "Secondary Storage VM";
+ // These are old values -- can be removed in the future
+ case 8 : return "User VM";
+ case 11 : return "Routing Host";
+ case 12 : return "Storage";
+ case 13 : return "Usage Server";
+ case 14 : return "Management Server";
+ case 15 : return "Domain Router";
+ case 16 : return "Console Proxy";
+ case 17 : return "User VM";
+ case 18 : return "VLAN";
+ case 19 : return "Secondary Storage VM";
+ case 20 : return "Usage Server";
+ case 21 : return "Storage";
+ case 22 : return "Update Resource Count";
+ case 23 : return "Usage Sanity Result";
+ case 24 : return "Direct Attached Public IP";
+ case 25 : return "Local Storage";
+ case 26 : return "Resource Limit Exceeded";
}
},
convertByType: function(alertCode, value) {
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 4d529aeb04e..c0a5d141700 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -7597,7 +7597,7 @@
if(vSwitchEnabled) {
- items.push({ id:" nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
+ items.push({ id:"nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
items.push({id: "vmwaresvs", description: "VMware vNetwork Standard Virtual Switch"});
items.push({id: "vmwaredvs", description: "VMware vNetwork Distributed Virtual Switch"});
@@ -7610,7 +7610,7 @@
else{
items.push({id: "vmwaredvs", description: "VMware vNetwork Distributed Virtual Switch"});
items.push({id: "vmwaresvs", description: "VMware vNetwork Standard Virtual Switch"});
- items.push({ id:" nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
+ items.push({ id:"nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
}
args.response.success({data: items});
diff --git a/ui/scripts/ui-custom/healthCheck.js b/ui/scripts/ui-custom/healthCheck.js
index c4c84e5236b..ebb7e5a8903 100644
--- a/ui/scripts/ui-custom/healthCheck.js
+++ b/ui/scripts/ui-custom/healthCheck.js
@@ -73,7 +73,7 @@
form: {
title: '',
fields:{
- pingpath: {label: 'Ping Path', docID:'helpAccountUsername' , validation: {required: false}, defaultValue: pingpath1}
+ pingpath: {label: 'Ping Path', validation: {required: false}, defaultValue: pingpath1}
}
}
});
diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js
index 47932664927..5108c5c0c3b 100755
--- a/ui/scripts/zoneWizard.js
+++ b/ui/scripts/zoneWizard.js
@@ -897,7 +897,7 @@
if(vSwitchEnabled) {
- items.push({ id:" nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
+ items.push({ id:"nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
items.push({id: "vmwaresvs", description: "VMware vNetwork Standard Virtual Switch"});
items.push({id: "vmwaredvs", description: "VMware vNetwork Distributed Virtual Switch"});
@@ -909,9 +909,9 @@
// items.push({id: " ", description: " "});
else{
- items.push({id: "vmwaredvs", description: "VMware vNetwork Distributed Virtual Switch"});
- items.push({id: "vmwaresvs", description: "VMware vNetwork Standard Virtual Switch"});
- items.push({ id:" nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
+ items.push({id:"vmwaredvs", description: "VMware vNetwork Distributed Virtual Switch"});
+ items.push({ id: "vmwaresvs", description: "VMware vNetwork Standard Virtual Switch"});
+ items.push({ id:"nexusdvs" , description: "Cisco Nexus 1000v Distributed Virtual Switch"});
}
args.response.success({data: items});
diff --git a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java
index a0765b2b272..dc918b83b6d 100644
--- a/usage/src/com/cloud/usage/UsageAlertManagerImpl.java
+++ b/usage/src/com/cloud/usage/UsageAlertManagerImpl.java
@@ -50,11 +50,12 @@ import com.sun.mail.smtp.SMTPTransport;
@Local(value={AlertManager.class})
public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
private static final Logger s_logger = Logger.getLogger(UsageAlertManagerImpl.class.getName());
+ private static final Logger s_alertsLogger = Logger.getLogger("org.apache.cloudstack.alerts");
private EmailAlert _emailAlert;
@Inject private AlertDao _alertDao;
@Inject private ConfigurationDao _configDao;
-
+
@Override
public boolean configure(String name, Map params) throws ConfigurationException {
Map configs = _configDao.getConfiguration("management-server", params);
@@ -101,6 +102,9 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
try {
if (_emailAlert != null) {
_emailAlert.sendAlert(alertType, dataCenterId, podId, subject, body);
+ } else {
+ s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: "
+ + podId + " // clusterId:: " + null + " // message:: " + subject );
}
} catch (Exception ex) {
s_logger.error("Problem sending email alert", ex);
@@ -171,18 +175,19 @@ public class UsageAlertManagerImpl extends ManagerBase implements AlertManager {
// TODO: make sure this handles SSL transport (useAuth is true) and regular
public void sendAlert(short alertType, long dataCenterId, Long podId, String subject, String content) throws MessagingException, UnsupportedEncodingException {
+ s_alertsLogger.warn(" alertType:: " + alertType + " // dataCenterId:: " + dataCenterId + " // podId:: " +
+ podId + " // clusterId:: " + null + " // message:: " + subject);
AlertVO alert = null;
-
if ((alertType != AlertManager.ALERT_TYPE_HOST) &&
(alertType != AlertManager.ALERT_TYPE_USERVM) &&
(alertType != AlertManager.ALERT_TYPE_DOMAIN_ROUTER) &&
(alertType != AlertManager.ALERT_TYPE_CONSOLE_PROXY) &&
- (alertType != AlertManager.ALERT_TYPE_SSVM) &&
+ (alertType != AlertManager.ALERT_TYPE_SSVM) &&
(alertType != AlertManager.ALERT_TYPE_STORAGE_MISC) &&
(alertType != AlertManager.ALERT_TYPE_MANAGMENT_NODE)) {
alert = _alertDao.getLastAlert(alertType, dataCenterId, podId);
}
-
+
if (alert == null) {
// set up a new alert
AlertVO newAlert = new AlertVO();
diff --git a/utils/src/com/cloud/utils/component/AdapterBase.java b/utils/src/com/cloud/utils/component/AdapterBase.java
index a8f4f468090..ea5e9611ab6 100644
--- a/utils/src/com/cloud/utils/component/AdapterBase.java
+++ b/utils/src/com/cloud/utils/component/AdapterBase.java
@@ -22,8 +22,10 @@ import java.util.List;
public class AdapterBase extends ComponentLifecycleBase implements Adapter {
public AdapterBase() {
+ // set default run level for adapter components
+ setRunLevel(ComponentLifecycle.RUN_LEVEL_COMPONENT);
}
-
+
public static T getAdapterByName(List adapters, String name) {
for(T adapter : adapters) {
if(adapter.getName() != null && adapter.getName().equalsIgnoreCase(name))
diff --git a/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java b/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java
new file mode 100644
index 00000000000..ea3b68573cf
--- /dev/null
+++ b/utils/src/com/cloud/utils/component/ComponentMethodProxyCache.java
@@ -0,0 +1,90 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package com.cloud.utils.component;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Method;
+import java.util.WeakHashMap;
+
+public class ComponentMethodProxyCache {
+
+ private static WeakHashMap> s_cache = new WeakHashMap>();
+
+ public ComponentMethodProxyCache() {
+ }
+
+ public static Method getTargetMethod(Method method, Object target) {
+ synchronized(s_cache) {
+ WeakReference targetMethod = s_cache.get(new TargetKey(method, target));
+ if(targetMethod != null && targetMethod.get() != null)
+ return targetMethod.get();
+
+ Class> clazz = target.getClass();
+ for(Method m : clazz.getMethods()) {
+ if(isMethodMatched(method, m)) {
+ s_cache.put(new TargetKey(method, target), new WeakReference(m));
+ return m;
+ }
+ }
+
+ return method;
+ }
+ }
+
+ private static boolean isMethodMatched(Method m1, Method m2) {
+ if(!m1.getName().equals(m2.getName()))
+ return false;
+
+ Class>[] params1 = m1.getParameterTypes();
+ Class>[] params2 = m2.getParameterTypes();
+
+ if(params1.length != params2.length)
+ return false;
+
+ for(int i = 0; i < params1.length; i++) {
+ if(!params1[i].isAssignableFrom(params2[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ public static class TargetKey {
+ Method _method;
+ Object _target;
+
+ public TargetKey(Method method, Object target) {
+ _method = method;
+ _target = target;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(!(obj instanceof TargetKey))
+ return false;
+
+ // for target object, we just check the reference
+ return _method.equals(((TargetKey)obj)._method) &&
+ _target == ((TargetKey)obj)._target;
+ }
+
+ public int hashCode() {
+ return _target.hashCode() ^ _target.hashCode();
+ }
+ }
+}
diff --git a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java b/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
index fda11b74609..9a85c79fa80 100644
--- a/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
+++ b/utils/src/com/cloud/utils/component/SpringComponentScanUtils.java
@@ -38,5 +38,4 @@ public class SpringComponentScanUtils {
}
return false;
}
-
}
diff --git a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
index e03b25f912d..7ca33ab5f5d 100644
--- a/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
+++ b/utils/src/com/cloud/utils/db/TransactionContextBuilder.java
@@ -22,9 +22,10 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;
+import com.cloud.utils.component.ComponentMethodProxyCache;
+
public class TransactionContextBuilder implements MethodInterceptor {
private static final Logger s_logger = Logger.getLogger(TransactionContextBuilder.class);
public TransactionContextBuilder() {
@@ -72,14 +73,9 @@ public class TransactionContextBuilder implements MethodInterceptor {
Class> clazz = method.getDeclaringClass();
if(clazz.isInterface()) {
clazz = target.getClass();
- for(Method m : clazz.getMethods()) {
- // it is supposed that we need to check against type arguments,
- // this can be simplified by just checking method name
- if(m.getName().equals(method.getName())) {
- if(m.getAnnotation(DB.class) != null)
- return true;
- }
- }
+ Method targetMethod = ComponentMethodProxyCache.getTargetMethod(method, target);
+ if(targetMethod != null && targetMethod.getAnnotation(DB.class) != null)
+ return true;
}
do {