You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ja...@apache.org on 2013/11/05 19:10:13 UTC

git commit: updated refs/heads/master to b464a20

Updated Branches:
  refs/heads/master 80813375a -> b464a20a5


CLOUDSTACK-4736: Monitoring services in VR


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b464a20a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b464a20a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b464a20a

Branch: refs/heads/master
Commit: b464a20a5264f043cdeb306cc8ebace608ded6c8
Parents: 8081337
Author: Jayapal <ja...@apache.org>
Authored: Tue Nov 5 23:19:22 2013 +0530
Committer: Jayapal <ja...@apache.org>
Committed: Tue Nov 5 23:39:33 2013 +0530

----------------------------------------------------------------------
 .../cloud/agent/api/to/MonitorServiceTO.java    |  74 ++++++
 .../com/cloud/network/MonitoringService.java    |  42 +++
 .../api/routing/SetMonitorServiceCommand.java   |  56 ++++
 .../spring-engine-schema-core-daos-context.xml  |   1 +
 .../cloud/network/dao/MonitoringServiceDao.java |  31 +++
 .../network/dao/MonitoringServiceDaoImpl.java   |  68 +++++
 .../cloud/network/dao/MonitoringServiceVO.java  | 119 +++++++++
 .../xen/resource/CitrixResourceBase.java        |  55 ++--
 .../VirtualNetworkApplianceManagerImpl.java     |  62 ++++-
 setup/db/db/schema-421to430.sql                 |  15 ++
 .../config/opt/cloud/bin/monitor_service.sh     |  71 +++++
 .../debian/config/root/monitorServices.py       | 263 +++++++++++++++++++
 12 files changed, 822 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/MonitorServiceTO.java b/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
new file mode 100644
index 0000000..deced16
--- /dev/null
+++ b/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
@@ -0,0 +1,74 @@
+// 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 com.cloud.agent.api.to;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+public class MonitorServiceTO implements InternalIdentity {
+    long id;
+    String service;
+    String processname;
+    String serviceName;
+    String servicePath;
+    String pidFile;
+    boolean isDefault;
+
+    protected MonitorServiceTO() {
+    }
+
+    public MonitorServiceTO (String service, String processname, String serviceName, String servicepath, String pidFile, boolean isDefault) {
+        this.service = service;
+        this.processname = processname;
+        this.serviceName = serviceName;
+        this.servicePath = servicepath;
+        this.pidFile = pidFile;
+        this.isDefault = isDefault;
+    }
+
+
+
+    public boolean isDefault() {
+        return isDefault;
+    }
+
+    public String getPidFile() {
+        return pidFile;
+    }
+
+    @Override
+    public long getId() {
+        return id;
+    }
+
+
+    public String getService() {
+        return service;
+    }
+
+    public String getServiceName() {
+        return serviceName;
+    }
+
+    public String getServicePath() {
+        return servicePath;
+    }
+
+    public String getProcessname() {
+        return processname;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/api/src/com/cloud/network/MonitoringService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/MonitoringService.java b/api/src/com/cloud/network/MonitoringService.java
new file mode 100644
index 0000000..2a1754a
--- /dev/null
+++ b/api/src/com/cloud/network/MonitoringService.java
@@ -0,0 +1,42 @@
+// 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 com.cloud.network;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+
+/**
+ * Nic represents one nic on the VM.
+ */
+public interface MonitoringService  extends ControlledEntity, Identity, InternalIdentity {
+    /**
+     * @return id in the CloudStack database
+     */
+    enum Service {
+        Dhcp,
+        LoadBalancing,
+        Ssh,
+        Webserver,
+    }
+    long getId();
+    String getService();
+    String getServiceName();
+    String getPidFile();
+    String getServicePath();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java b/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
new file mode 100644
index 0000000..109daf2
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
@@ -0,0 +1,56 @@
+// 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 com.cloud.agent.api.routing;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import com.cloud.agent.api.to.MonitorServiceTO;
+
+/**
+ *
+ * AccessDetails allow different components to put in information about
+ * how to access the components inside the command.
+ */
+public class SetMonitorServiceCommand extends NetworkElementCommand {
+    MonitorServiceTO[] services;
+
+    protected SetMonitorServiceCommand() {
+    }
+
+    public SetMonitorServiceCommand(List<MonitorServiceTO> services) {
+        this.services = services.toArray(new MonitorServiceTO[services.size()]);
+    }
+
+    public MonitorServiceTO[] getRules() {
+        return services;
+    }
+
+    public String getConfiguration() {
+
+        StringBuilder sb = new StringBuilder();
+        for (MonitorServiceTO service: services) {
+            sb.append("[").append(service.getService()).append("]").append(":");
+            sb.append("processname=").append(service.getProcessname()).append(":");
+            sb.append("servicename=").append(service.getServiceName()).append(":");
+            sb.append("pidfile=").append(service.getPidFile()).append(":");
+            sb.append(",");
+        }
+
+        return sb.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index e811cce..98ef018 100644
--- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -155,6 +155,7 @@
   <bean id="externalPublicIpStatisticsDaoImpl" class="com.cloud.usage.dao.ExternalPublicIpStatisticsDaoImpl" />
   <bean id="firewallRulesCidrsDaoImpl" class="com.cloud.network.dao.FirewallRulesCidrsDaoImpl" />
   <bean id="firewallRulesDaoImpl" class="com.cloud.network.dao.FirewallRulesDaoImpl" />
+  <bean id="MonitoringServiceDaoImpl" class="com.cloud.network.dao.MonitoringServiceDaoImpl" />
   <bean id="globalLoadBalancerDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerDaoImpl" />
   <bean id="globalLoadBalancerLbRuleMapDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerLbRuleMapDaoImpl" />
   <bean id="guestOSCategoryDaoImpl" class="com.cloud.storage.dao.GuestOSCategoryDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
new file mode 100644
index 0000000..7cc7cc0
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
@@ -0,0 +1,31 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.utils.db.GenericDao;
+
+import java.util.List;
+
+public interface MonitoringServiceDao extends GenericDao<MonitoringServiceVO, Long> {
+
+    List<MonitoringServiceVO> listAllServices();
+    List<MonitoringServiceVO> listDefaultServices(boolean isDefault);
+
+    MonitoringServiceVO getServiceByName(String service);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
new file mode 100644
index 0000000..53dc7d4
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
@@ -0,0 +1,68 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import java.util.List;
+
+@Component
+@Local(value=MonitoringServiceDao.class)
+public class MonitoringServiceDaoImpl extends GenericDaoBase<MonitoringServiceVO, Long> implements MonitoringServiceDao {
+    private final SearchBuilder<MonitoringServiceVO> AllFieldsSearch;
+
+    public MonitoringServiceDaoImpl() {
+        super();
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().getDefault(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("service", AllFieldsSearch.entity().getService(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("processname", AllFieldsSearch.entity().getProcessname(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("servicename", AllFieldsSearch.entity().getServiceName(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("servicepath", AllFieldsSearch.entity().getServicePath(), SearchCriteria.Op.EQ);
+        AllFieldsSearch.and("servicePidFile", AllFieldsSearch.entity().getPidFile(), SearchCriteria.Op.EQ);
+
+        AllFieldsSearch.done();
+    }
+
+
+
+    @Override
+    public List<MonitoringServiceVO> listAllServices() {
+        return null;
+    }
+
+    @Override
+    public List<MonitoringServiceVO> listDefaultServices(boolean isDefault) {
+        SearchCriteria<MonitoringServiceVO> sc = AllFieldsSearch.create();
+        sc.setParameters("isDefault", isDefault);
+        return listBy(sc);
+    }
+
+    @Override
+    public MonitoringServiceVO getServiceByName(String service) {
+        SearchCriteria<MonitoringServiceVO> sc = AllFieldsSearch.create();
+        sc.setParameters("service", service);
+        return findOneBy(sc);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
new file mode 100644
index 0000000..3f9122c
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
@@ -0,0 +1,119 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.network.MonitoringService;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@Table(name = "monitoring_services")
+public class MonitoringServiceVO implements MonitoringService {
+
+    public MonitoringServiceVO(String service, String processname, String serviceName, String servicePath,
+                            String pidFile) {
+        this.service = service;
+        this.processname = processname;
+        this.servicename = serviceName;
+        this.servicePath = servicePath;
+        this.servicePidFile= pidFile;
+
+    }
+
+    protected MonitoringServiceVO() {
+    }
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Column(name = "id")
+    long id;
+
+    @Column(name = "service")
+    String service;
+
+    @Column(name="process_name", updatable=false)
+    String processname;
+
+    @Column(name="service_name", updatable=false)
+    String servicename;
+
+    @Column(name="service_path", updatable=false)
+    private String servicePath;
+
+    @Column(name="pidFile", updatable=false)
+    private String servicePidFile;
+
+    @Column(name="isDefault")
+    private boolean isDefault;
+
+
+    @Column(name = "uuid")
+    String uuid = UUID.randomUUID().toString();
+
+    public long getId() {
+        return id;
+    }
+
+    @Override
+    public String getService() {
+        return this.service;
+    }
+
+    @Override
+    public String getServiceName() {
+        return this.servicename;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public String getPidFile() {
+        return this.servicePidFile;
+
+    }
+
+    @Override
+    public String getServicePath() {
+        return this.servicePidFile;
+    }
+
+    @Override
+    public String getUuid() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public long getAccountId() {
+        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public long getDomainId() {
+        return 0;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public boolean getDefault() {
+        return isDefault;
+    }
+
+    public void setDefault(boolean isDefault) {
+        isDefault = isDefault;
+    }
+
+    public String getProcessname() {
+        return processname;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 5c9f4e5..69b7c9e 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -118,34 +118,7 @@ import com.cloud.agent.api.check.CheckSshCommand;
 import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
 import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
 import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
-import com.cloud.agent.api.routing.CreateIpAliasCommand;
-import com.cloud.agent.api.routing.DeleteIpAliasCommand;
-import com.cloud.agent.api.routing.DhcpEntryCommand;
-import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.api.routing.IpAssocAnswer;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SavePasswordCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetNetworkACLAnswer;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
-import com.cloud.agent.api.routing.SetSourceNatAnswer;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SetStaticRouteAnswer;
-import com.cloud.agent.api.routing.SetStaticRouteCommand;
-import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.VmDataCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.routing.*;
 import com.cloud.agent.api.storage.CopyVolumeAnswer;
 import com.cloud.agent.api.storage.CopyVolumeCommand;
 import com.cloud.agent.api.storage.CreateAnswer;
@@ -633,6 +606,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((ScaleVmCommand) cmd);
         } else if (clazz == PvlanSetupCommand.class) {
             return execute((PvlanSetupCommand) cmd);
+        } else if (clazz == SetMonitorServiceCommand.class) {
+            return execute((SetMonitorServiceCommand) cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
@@ -8121,6 +8096,30 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return new Answer(cmd, success, "");
     }
 
+    private Answer execute(SetMonitorServiceCommand cmd) {
+        boolean success = true;
+
+        String config = cmd.getConfiguration();
+
+        Connection conn = getConnection();
+        String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+
+        if (routerIp == null) {
+            return new Answer(cmd);
+        }
+
+        String args = "monitor_service.sh " + routerIp;
+        args += " -c " + config;
+
+        String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file.");
+        }
+
+        return new Answer(cmd, success, "");
+
+    }
+
     protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
         String[] results = new String[cmd.getRules().length];
         String callResult;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index a93480b..9b35a4b 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -41,6 +41,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.agent.api.to.*;
 import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -82,17 +83,12 @@ import com.cloud.agent.api.routing.NetworkElementCommand;
 import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
 import com.cloud.agent.api.routing.SavePasswordCommand;
 import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetMonitorServiceCommand;
 import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
 import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.to.DhcpTO;
-import com.cloud.agent.api.to.FirewallRuleTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.agent.manager.Commands;
 import com.cloud.alert.AlertManager;
 import com.cloud.cluster.ClusterManager;
@@ -164,6 +160,7 @@ import com.cloud.network.dao.IPAddressVO;
 import com.cloud.network.dao.LoadBalancerDao;
 import com.cloud.network.dao.LoadBalancerVMMapDao;
 import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.MonitoringServiceVO;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
 import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
@@ -175,6 +172,7 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDao;
 import com.cloud.network.dao.UserIpv6AddressDao;
 import com.cloud.network.dao.VirtualRouterProviderDao;
 import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.dao.MonitoringServiceDao;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRule.LbDestination;
 import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
@@ -183,6 +181,7 @@ import com.cloud.network.lb.LoadBalancingRulesManager;
 import com.cloud.network.router.VirtualRouter.RedundantState;
 import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.MonitoringService;
 import com.cloud.network.rules.FirewallRule.Purpose;
 import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.network.rules.PortForwardingRule;
@@ -369,8 +368,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
     IpAddressManager _ipAddrMgr;
     @Inject
     ConfigDepot _configDepot;
+    @Inject
+    MonitoringServiceDao _monitorServiceDao;
+
+
 
-    
     int _routerRamSize;
     int _routerCpuMHz;
     int _retry = 2;
@@ -2332,10 +2334,56 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
 
             finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
         }
+        finalizeMonitorServiceOnStrat(cmds, router, provider, routerGuestNtwkIds.get(0));
 
         return true;
     }
 
+    private void finalizeMonitorServiceOnStrat(Commands cmds, DomainRouterVO router, Provider provider, long networkId) {
+
+        NetworkVO network = _networkDao.findById(networkId);
+
+        s_logger.debug("Creating  monitoring services on "+ router +" start...");
+
+
+        // get the list of sevices for this network to monitor
+        List <MonitoringServiceVO> services = new ArrayList<MonitoringServiceVO>();
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter) ||
+                _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter)) {
+            MonitoringServiceVO dhcpService = _monitorServiceDao.getServiceByName(MonitoringService.Service.Dhcp.toString());
+            if (dhcpService != null) {
+                services.add(dhcpService);
+            }
+        }
+
+        if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, Provider.VirtualRouter)) {
+            MonitoringServiceVO lbService = _monitorServiceDao.getServiceByName(MonitoringService.Service.LoadBalancing.toString());
+            if (lbService != null) {
+                services.add(lbService);
+            }
+        }
+        List<MonitoringServiceVO> defaultServices = _monitorServiceDao.listDefaultServices(true);
+        services.addAll(defaultServices);
+
+        List<MonitorServiceTO> servicesTO = new ArrayList<MonitorServiceTO>();
+        for (MonitoringServiceVO service: services) {
+            MonitorServiceTO serviceTO = new MonitorServiceTO( service.getService(), service.getProcessname(), service.getServiceName(), service.getServicePath(),
+                    service.getPidFile(), service.getDefault());
+            servicesTO.add(serviceTO);
+        }
+
+        SetMonitorServiceCommand command = new SetMonitorServiceCommand(servicesTO);
+        command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
+        command.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(networkId, router.getId()));
+        command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+        cmds.addCommand("monitor", command);
+    }
+
+
+
+
+
     protected NicProfile getControlNic(VirtualMachineProfile profile) {
         DomainRouterVO router = _routerDao.findById(profile.getId());
         DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql
index 9fe56c0..26e4abf 100644
--- a/setup/db/db/schema-421to430.sql
+++ b/setup/db/db/schema-421to430.sql
@@ -561,3 +561,18 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag
 'Sets the attribute for uniquemembers within a group','uniquemember',NULL,NULL,0);
 
 UPDATE `cloud`.`volumes` SET display_volume=1 where id>0;
+
+create table `cloud`.`monitoring_services` (
+`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+`uuid` varchar(40), `service` varchar(255) COMMENT 'Service name',
+`process_name` varchar(255) COMMENT 'running process name',
+`service_name` varchar(255) COMMENT 'exact name of the running service',
+`service_path` varchar(255) COMMENT 'path of the service in system',
+`pidfile` varchar(255) COMMENT 'path of the pid file of the service',
+`isDefault` boolean COMMENT 'Default service', PRIMARY KEY (`id`)
+);
+
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(1,'ssh','sshd', 'ssh','/etc/init.d/ssh','/var/run/sshd.pid',true);
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(2,'dhcp','dnsmasq','dnsmasq','/etc/init.d/dnsmasq','/var/run/dnsmasq/dnsmasq.pid',false);
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(3,'loadbalancing','haproxy','haproxy','/etc/init.d/haproxy','/var/run/haproxy.pid',false);
+insert into cloud.monitoring_services(id, service, process_name,  service_name, service_path, pidfile, isDefault) values(4,'webserver','apache2','apache2','/etc/init.d/apache2','/var/run/apache2.pid', true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
new file mode 100755
index 0000000..a2b789c
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+# 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.
+
+source /root/func.sh
+
+lock="biglock"
+locked=$(getLockFile $lock)
+if [ "$locked" != "1" ]
+then
+    exit 1
+fi
+
+set -x
+usage() {
+  printf "Usage: %s: -c config string \n" $(basename $0) >&2
+}
+
+configFile='/etc/monitor.conf'
+
+create_config() {
+services=$1;
+services_list=$(echo $services | cut -d, -f1- --output-delimiter=" ");
+
+echo "#Monitor services config" >$configFile
+
+for s in $services_list
+do
+service=$(echo $s | cut -d: -f1);
+processname=$(echo $s | cut -d: -f2);
+service_name=$(echo $s | cut -d: -f3);
+pidfile=$(echo $s | cut -d: -f4);
+
+echo $service >> $configFile;
+echo $processname >> $configFile
+echo $service_name >> $configFile
+echo $pidfile >> $configFile
+
+
+
+done
+
+}
+
+config=$2
+
+#delete cron job before updating config file
+crontab -l | grep -v  monitorServices.py | crontab -
+
+create_config $config
+
+#add cron job
+(crontab -l ; echo "*/3 * * * * python /root/monitorServices.py") | crontab -
+
+
+unlock_exit 0 $lock $locked
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/systemvm/patches/debian/config/root/monitorServices.py
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/root/monitorServices.py b/systemvm/patches/debian/config/root/monitorServices.py
new file mode 100755
index 0000000..358c9dc
--- /dev/null
+++ b/systemvm/patches/debian/config/root/monitorServices.py
@@ -0,0 +1,263 @@
+#!/usr/bin/python
+# 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.
+
+
+
+
+__author__ = 'jayapalreddy'
+
+from ConfigParser import SafeConfigParser
+from subprocess import *
+from os import path
+import time
+
+monitor_log='/var/log/monitor.log'
+class StatusCodes:
+    SUCCESS      = 0
+    FAILED       = 1
+    INVALID_INP  = 2
+    RUNNING      = 3
+    STOPPED      = 4
+    STARTING     = 5
+
+class log:
+    INFO = 'INFO'
+    ALERT = 'ALERT'
+    CRIT  = 'CRIT'
+    NOTIF = 'NOTIF'
+
+
+
+
+def getConfig( config_file_path = "/etc/monitor.conf" ):
+    process_dict = {}
+    parser = SafeConfigParser()
+    parser.read( config_file_path )
+
+    #print 'Read values:\n'
+
+    for section in parser.sections():
+        #   print section
+        process_dict[section] = {}
+
+        for name, value in parser.items(section):
+            process_dict[section][name] = value
+#           print '  %s = %r' % (name, value)
+
+    return  process_dict
+
+def printd (msg):
+    return 0
+    print msg
+
+def raisealert(severity, msg, process_name=None):
+    #timeStr=str(time.ctime())
+    if process_name is not None:
+        log = '['+severity +']'+" " + '['+process_name+']' + " " + msg +"\n"
+    else:
+        log = '['+severity+']' + " " + msg +"\n"
+
+    msg = 'logger -t monit '+ log
+    pout = Popen(msg, shell=True, stdout=PIPE)
+
+
+    #f= open(monitor_log,'r+')
+    #f.seek(0, 2)
+    #f.write(str(log))
+    #f.close()
+
+
+def isPidMatchPidFile(pidfile, pids):
+
+    if pids is None or isinstance(pids,list) != True or len(pids) == 0:
+        print "Invalid Arguments"
+        return StatusCodes.FAILED
+    if not path.isfile(pidfile):
+        #It seems there is no pid file for this service
+        printd("The pid file "+pidfile+" is not there for this process")
+        return StatusCodes.FAILED
+
+    fd=None
+    try:
+        fd = open(pidfile,'r')
+    except:
+        printd("pid file: "+ pidfile +" open failed")
+        return StatusCodes.FAILED
+
+
+    inp = fd.read()
+    printd("file content "+str(inp))
+    printd(pids)
+    tocheck_pid  =  inp.strip()
+    for item in pids:
+        if str(tocheck_pid) ==  item.strip():
+            printd("pid file matched")
+            return StatusCodes.SUCCESS
+
+    fd.close()
+    return StatusCodes.FAILED
+
+
+
+def checkProcessStatus( process ):
+    process_name = process.get('processname')
+    service_name = process.get('servicename')
+    pidfile = process.get('pidfile')
+    #temp_out = None
+    restartFailed=0
+    pidFileMatched=1
+    cmd=''
+    if process_name is None:
+        print "\n Invalid Process Name"
+        return StatusCodes.INVALID_INP
+    else:
+        msg="checking the process " + process_name
+        printd(msg)
+        cmd = 'pidof ' + process_name
+        printd(cmd)
+        #cmd = 'service ' + process_name + ' status'
+        pout = Popen(cmd, shell=True, stdout=PIPE)
+        exitStatus = pout.wait()
+        temp_out = pout.communicate()[0]
+
+    #check there is only one pid or not
+    if exitStatus == 0:
+        msg="pids: " +temp_out;
+        printd(msg)
+        pids = temp_out.split(' ')
+
+        #there is more than one process so match the pid file
+        #if not matched set pidFileMatched=0
+        printd("Checking pid file")
+        if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS:
+            pidFileMatched = 1;
+        else:
+            pidFileMatched = 0;
+
+    printd(pidFileMatched)
+    if exitStatus == 0 and pidFileMatched == 1:
+        printd("The process is running ....")
+        return  StatusCodes.RUNNING
+    else:
+        printd('exit status:'+str(exitStatus))
+        msg="The process " + process_name +" is not running trying recover "
+        printd(msg)
+        #Retry the process state for few seconds
+        for i in range(1,10):
+            pout = Popen(cmd, shell=True, stdout=PIPE)
+            exitStatus = pout.wait()
+            temp_out = pout.communicate()[0]
+
+            if i < 5: # this is just for trying few more times
+                if exitStatus == 0:
+                    pids = temp_out.split(' ')
+
+                    if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS:
+                        pidFileMatched = 1;
+                        printd("pid file is matched ...")
+                        raisealert(log.INFO, "The process detected as running", process_name)
+                        break
+                    else:
+                        printd("pid file is not matched ...")
+                        pidFileMatched = 0;
+                        continue
+                    time.sleep(1)
+            else:
+                msg="The process " +process_name+" is not running trying recover "
+                raisealert(log.INFO,process_name,msg)
+
+                if service_name == 'apache2':
+                    # Killing apache2 process with this the main service will not start
+                    for pid in pids:
+                        cmd = 'kill -9 '+pid;
+                        printd(cmd)
+                        Popen(cmd, shell=True, stdout=PIPE)
+
+                cmd = 'service ' + service_name + ' restart'
+                try:
+                    time.sleep(1)
+                    return_val= check_call(cmd , shell=True)
+                except CalledProcessError:
+                    restartFailed=1
+                    msg="service "+ process_name +" restart failed"
+                    printd(msg)
+                    continue
+
+                if return_val == 0:
+                    printd("The process" + process_name +" recovered successfully ")
+                    msg="The process " +process_name+" is recovered successfully "
+                    raisealert(log.ALERT,process_name,msg)
+
+                    break;
+                else:
+                    #retry restarting the process for few tries
+                    printd("process restart failing trying again ....")
+                    restartFailed=1
+                    time.sleep(1)
+                    continue
+        #for end here
+
+        if restartFailed == 1:
+            msg="The process %s recover failed ", process_name;
+            raisealert(log.ALERT,process_name,msg)
+
+            printd("Restart failed after number of retries")
+            return StatusCodes.STOPPED
+
+    return  StatusCodes.RUNNING
+
+def raiseAlert( process_name ):
+    print "process name %s is raised "%process_name
+
+def monitProcess( processes_info ):
+    if len( processes_info ) == 0:
+        print "Invalid Input"
+        return  StatusCodes.INVALID_INP
+    for process,properties in processes_info.items():
+        if checkProcessStatus( properties) != StatusCodes.RUNNING:
+            print "\n Process %s is not Running"%process
+
+
+def main():
+    '''
+    Step1 : Get Config
+    '''
+
+    printd("monitoring started")
+    temp_dict  = getConfig()
+
+    '''
+    Step2: Get Previous Run Log
+    '''
+
+    '''
+    Step3: Monitor and Raise Alert
+    '''
+    #raisealert(log.INFO, 'Monit started')
+    monitProcess( temp_dict )
+
+
+if __name__ == "__main__":
+    main()
+
+
+
+
+
+
+