You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by hu...@apache.org on 2013/11/01 17:55:56 UTC

[1/6] OpenContrail network plugin

Updated Branches:
  refs/heads/master 1e417994d -> 6b5fab2f5


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
new file mode 100644
index 0000000..e214eb0
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTest.java
@@ -0,0 +1,147 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.ApiConnectorFactory;
+import net.juniper.contrail.api.ApiObjectBase;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.VirtualNetwork;
+
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.db.Merovingian2;
+import com.cloud.utils.mgmt.JmxUtil;
+
+import junit.framework.TestCase;
+import static org.mockito.Mockito.*;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/publicNetworkContext.xml")
+
+public class PublicNetworkTest extends TestCase {
+    private static final Logger s_logger =
+            Logger.getLogger(PublicNetworkTest.class);
+
+    @Inject public ContrailManager _contrailMgr;
+    @Inject public NetworkDao _networksDao;
+
+    private static boolean _initDone = false;
+    private static int _mysql_server_port;
+    private static long _msId;
+    private static Merovingian2 _lockMaster;
+    private ManagementServerMock _server;
+    private ApiConnector _spy;
+    
+
+    @BeforeClass
+    public static void globalSetUp() throws Exception {
+        ApiConnectorFactory.setImplementation(ApiConnectorMockito.class);
+        s_logger.info("mysql server is getting launched ");
+        _mysql_server_port = TestDbSetup.init(null);
+        s_logger.info("mysql server launched on port " + _mysql_server_port);
+        _msId = ManagementServerNode.getManagementServerId();
+        _lockMaster = Merovingian2.createLockMaster(_msId);
+    }
+
+    @AfterClass
+    public static void globalTearDown() throws Exception {
+        _lockMaster.cleanupForServer(_msId);
+        JmxUtil.unregisterMBean("Locks", "Locks");
+        _lockMaster = null;
+
+        AbstractApplicationContext ctx = (AbstractApplicationContext) ComponentContext.getApplicationContext();
+        Map<String, ComponentLifecycle> lifecycleComponents = ctx.getBeansOfType(ComponentLifecycle.class);
+        for (ComponentLifecycle bean: lifecycleComponents.values()) {
+            bean.stop();
+        }
+        ctx.close();
+
+        s_logger.info("destroying mysql server instance running at port <" + _mysql_server_port + ">");
+        TestDbSetup.destroy(_mysql_server_port, null);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        try {
+            ComponentContext.initComponentsLifeCycle();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            s_logger.error(ex.getMessage());
+        }
+        _server = ComponentContext.inject(new ManagementServerMock());
+
+        _server.initialize(!_initDone);
+        _initDone = false;
+        _spy = ((ApiConnectorMockito)_contrailMgr.getApiConnector()).getSpy();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        _server.shutdown();
+    }
+
+    @Test
+    public void testPublicNetwork() throws IOException {
+    	DataCenter zone = _server.getZone();
+        List<NetworkVO> networks = _networksDao.listByZoneAndTrafficType(zone.getId(), TrafficType.Public);
+        assertNotNull(networks);
+        assertFalse(networks.isEmpty());
+        UserVm vm1 = _server.createVM("test", networks.get(0));
+
+        ArgumentCaptor<ApiObjectBase> createArg = ArgumentCaptor.forClass(ApiObjectBase.class);
+        verify(_spy, times(4)).create(createArg.capture());
+        
+        List<ApiObjectBase> argumentList = createArg.getAllValues();
+        ApiObjectBase vmObj = argumentList.get(0);
+        assertEquals(VirtualNetwork.class, vmObj.getClass());
+        assertEquals("__default_Public__", vmObj.getName());
+        
+        String vmiName = null;
+        for (ApiObjectBase obj: argumentList) {
+            if (obj.getClass() == VirtualMachineInterface.class) {
+                vmiName = obj.getName();
+            }
+        }
+        assertEquals("test-0", vmiName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
new file mode 100644
index 0000000..a184b14
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/PublicNetworkTestConfiguration.java
@@ -0,0 +1,13 @@
+package org.apache.cloudstack.network.contrail.management;
+
+import org.mockito.Mockito;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class PublicNetworkTestConfiguration {
+	@Bean
+	ServerDBSync getServerDBSync() {
+		return Mockito.mock(ServerDBSync.class);
+	}
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
new file mode 100644
index 0000000..460f780
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/TestDbSetup.java
@@ -0,0 +1,151 @@
+// 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.network.contrail.management;
+
+import java.net.ServerSocket;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.File;
+import java.util.Properties;
+import org.apache.commons.configuration.PropertiesConfiguration;
+
+import org.apache.log4j.Logger;
+
+public class TestDbSetup {
+
+    public static int findFreePort() throws Exception {
+
+       int port;
+       ServerSocket socket= new ServerSocket(0);
+       port = socket.getLocalPort();
+       socket.close();
+
+       return port;
+    }
+
+    public static void startMysqlServer(int port, String startMysqlScript) throws Exception {
+
+       try {
+	   String cwd = new java.io.File(".").getCanonicalPath();
+            Runtime r = Runtime.getRuntime();
+            String script = startMysqlScript;
+            if (script == null) {
+                script = "test/resources/mysql_db_start.sh "  + port; 
+            }
+            Process process = r.exec("sh " + cwd + "/" + script);
+            process.waitFor();
+            System.out.println("new sql server instance launched on port: " + port);
+       } catch (Exception e) {
+
+            String cause = e.getMessage();
+            if (cause.equals("sh: not found"))
+                System.out.println("No sh interpreter found.");
+            throw e;
+       }
+    }
+
+    public static void stopMysqlServer(int port, String stopMysqlScript) throws Exception {
+
+       try {
+            Runtime r = Runtime.getRuntime();
+            String script = stopMysqlScript;
+            if (script == null) {
+                script = "test/resources/mysql_db_stop.sh "  + port; 
+            }
+            Process process = r.exec("sh " + script);
+            process.waitFor();
+            System.out.println("sql server instance running at port " + port + " stopped");
+       } catch (Exception e) {
+
+            String cause = e.getMessage();
+            if (cause.equals("sh: not found"))
+                System.out.println("No sh interpreter found.");
+            throw e;
+       }
+    }
+
+    /* this is required for deploying db with new set of sql server parameters */
+    public static void copyDbPropertiesFile() throws Exception {
+       Runtime.getRuntime().exec("cp ../../../utils/conf/db.properties ../../../utils/conf/db.properties.override");
+    }
+
+    public static void updateSqlPort(int port, String propertyFileOverride) throws Exception {
+
+       PropertiesConfiguration config = new PropertiesConfiguration(propertyFileOverride);
+       System.out.println("File: " + propertyFileOverride + "; old: db.properties port: " + 
+                            config.getProperty("db.cloud.port") + ", new port: " + port);
+       config.setProperty("db.cloud.port", "" + port);
+       config.setProperty("db.cloud.username", System.getProperty("user.name"));
+       config.setProperty("db.cloud.password", "");
+
+       config.setProperty("db.usage.port", "" + port);
+       config.setProperty("db.usage.username", System.getProperty("user.name"));
+       config.setProperty("db.usage.password", "");
+
+       config.setProperty("db.awsapi.port", "" + port);
+       config.setProperty("db.awsapi.username", System.getProperty("user.name"));
+       config.setProperty("db.awsapi.password", "");
+
+       config.setProperty("db.simulator.port", "" + port);
+       config.setProperty("db.simulator.username", System.getProperty("user.name"));
+       config.setProperty("db.simulator.password", "");
+
+       config.save();
+    }
+    
+    public static void initCloudstackDb() throws Exception {
+        try {
+            File dir = new File("../../../");
+            Runtime r = Runtime.getRuntime();
+            Process process = r.exec("mvn -P developer -pl developer -Ddeploydb ", null, dir);
+            dumpProcessOutput(process);
+            process.waitFor();
+        } catch (Exception e) {
+            String cause = e.getMessage();
+            System.out.println("e: " + cause);
+            throw e;
+        }
+    }
+
+
+    public static void dumpProcessOutput(Process p) throws Exception {
+
+       BufferedReader istream = null;
+       istream = new BufferedReader(new InputStreamReader(p.getInputStream()));
+       String line = null;
+       while ((line = istream.readLine()) != null) {
+            System.out.println(line);
+       }
+    }
+
+    public static int init(String startScript) throws Exception {
+        int port = TestDbSetup.findFreePort();
+        TestDbSetup.startMysqlServer(port, startScript);
+        copyDbPropertiesFile();  
+        /* both of these files needs to have mysql port, username password details */
+        TestDbSetup.updateSqlPort(port, "db.properties");  /* for cloudstack runtime */
+        TestDbSetup.updateSqlPort(port, "../../../utils/conf/db.properties.override"); /* for deploying db */
+        TestDbSetup.initCloudstackDb();
+        return port;
+    } 
+
+    public static void destroy(int port, String stopScript) throws Exception {
+        TestDbSetup.stopMysqlServer(port, stopScript);
+    } 
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/VirtualNetworkModelTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/VirtualNetworkModelTest.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/VirtualNetworkModelTest.java
new file mode 100644
index 0000000..02835e5
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/VirtualNetworkModelTest.java
@@ -0,0 +1,62 @@
+// 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.network.contrail.management;
+
+import java.util.UUID;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.cloudstack.network.contrail.management.ModelDatabase;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.log4j.Logger;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+
+import junit.framework.TestCase;
+
+public class VirtualNetworkModelTest extends TestCase {
+    private static final Logger s_logger =
+            Logger.getLogger(VirtualNetworkModelTest.class);
+
+    @Test
+    public void testDBLookup() {
+        ModelDatabase db = new ModelDatabase();
+        NetworkVO network = Mockito.mock(NetworkVO.class);
+        VirtualNetworkModel storageModel = new VirtualNetworkModel(network, null, ContrailManager.managementNetworkName,
+                TrafficType.Storage);
+        db.getVirtualNetworks().add(storageModel);
+        VirtualNetworkModel mgmtModel = new VirtualNetworkModel(network, null, ContrailManager.managementNetworkName,
+                TrafficType.Management);
+        db.getVirtualNetworks().add(mgmtModel);
+        VirtualNetworkModel guestModel1 = new VirtualNetworkModel(network, UUID.randomUUID().toString(), "test",
+                TrafficType.Guest);
+        db.getVirtualNetworks().add(guestModel1);
+        VirtualNetworkModel guestModel2 = new VirtualNetworkModel(network, UUID.randomUUID().toString(), "test",
+                TrafficType.Guest);
+        db.getVirtualNetworks().add(guestModel2);
+        s_logger.debug("networks: " + db.getVirtualNetworks().size());
+        assertEquals(4, db.getVirtualNetworks().size());
+        assertSame(storageModel, db.lookupVirtualNetwork(null, storageModel.getName(), TrafficType.Storage));
+        assertSame(mgmtModel, db.lookupVirtualNetwork(null, mgmtModel.getName(), TrafficType.Management));
+        assertSame(guestModel1, db.lookupVirtualNetwork(guestModel1.getUuid(), null, TrafficType.Guest));
+        assertSame(guestModel2, db.lookupVirtualNetwork(guestModel2.getUuid(), null, TrafficType.Guest));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml
new file mode 100644
index 0000000..c577513
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml
@@ -0,0 +1,172 @@
+<!-- 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. -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/tx 
+                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+                      http://www.springframework.org/schema/aop
+                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+  <context:annotation-config />
+<!--
+  <context:component-scan base-package="org.apache.cloudstack, com.cloud" />
+-->
+  <!--
+    @DB support
+  -->
+
+   <bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
+   <bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
+  <bean id="contrailEventInterceptor" class="org.apache.cloudstack.network.contrail.management.EventUtils.EventInterceptor" />
+
+  <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
+    <property name="Interceptors">
+      <list>
+        <ref bean="transactionContextBuilder" />
+        <ref bean="actionEventInterceptor" />
+	<ref bean="contrailEventInterceptor" />
+      </list>
+    </property>
+  </bean>
+
+  <bean id="eventBus" class = "org.apache.cloudstack.framework.messagebus.MessageBusBase" />
+
+  <bean id="eventDaoImpl" class="com.cloud.event.dao.EventDaoImpl" />
+
+  <bean id="actionEventUtils" class="com.cloud.event.ActionEventUtils" />
+  <bean id="usageEventDaoImpl" class="com.cloud.event.dao.UsageEventDaoImpl" />
+
+  <!--<bean id="eventUtils" class="com.cloud.event.EventUtils" />-->
+
+  <bean id="accountDaoImpl" class="com.cloud.user.dao.AccountDaoImpl" />
+  <bean id="accountDetailsDaoImpl" class="com.cloud.user.AccountDetailsDaoImpl" />
+  <bean id="accountJoinDaoImpl" class="com.cloud.api.query.dao.AccountJoinDaoImpl" />
+  <bean id="accountVlanMapDaoImpl" class="com.cloud.dc.dao.AccountVlanMapDaoImpl" />
+  <bean id="launchPermissionDaoImpl" class="com.cloud.storage.dao.LaunchPermissionDaoImpl" />
+  <bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />
+  <bean id="iPAddressDaoImpl" class="com.cloud.network.dao.IPAddressDaoImpl" />
+  <bean id="apiResponseHelper" class="com.cloud.api.ApiResponseHelper" />
+  <bean id="nicDaoImpl" class="com.cloud.vm.dao.NicDaoImpl" />
+
+  <bean id="componentContext" class="com.cloud.utils.component.ComponentContext"/>
+
+  <bean id="IntegrationTestConfiguration"
+	class="org.apache.cloudstack.network.contrail.management.IntegrationTestConfiguration"/>
+
+  <bean id="HypervisorGuru"
+       class="com.cloud.hypervisor.XenServerGuru"/>
+
+  <!-- Management traffic -->
+  <bean id="PodBasedNetworkGuru"
+	class="com.cloud.network.guru.PodBasedNetworkGuru"/>
+
+  <bean id="ControlNetworkGuru"
+	class="com.cloud.network.guru.ControlNetworkGuru"/>
+
+  <bean id="PublicNetworkGuru"
+	class="com.cloud.network.guru.PublicNetworkGuru"/>
+
+  <bean id="StorageNetworkGuru"
+	class="com.cloud.network.guru.StorageNetworkGuru"/>
+
+  <bean id="DirectNetworkGuru"
+	class="com.cloud.network.guru.DirectNetworkGuru"/>
+
+  <bean id="VpcVirtualRouterElement"
+	class="com.cloud.network.element.VpcVirtualRouterElement"/>
+
+  <bean id="VirtualRouterElement"
+	class="com.cloud.network.element.VirtualRouterElement"/>
+
+  <!--
+  <bean id="Ipv6AddressManager"
+	class="com.cloud.network.Ipv6AddressManagerImpl"/>
+  -->
+
+
+  <bean id="com.cloud.network.security.SecurityGroupManager"
+	class="com.cloud.network.security.SecurityGroupManagerImpl"/>
+
+  <bean id="SecurityGroupElement"
+	class="com.cloud.network.element.SecurityGroupElement"/>
+	
+  <bean id="InternalLbVm" class="org.apache.cloudstack.network.element.InternalLoadBalancerElement">
+      <property name="name" value="InternalLbVm"/>
+  </bean>
+  <!--
+
+  <bean id="UserAuthenticator"
+	class="com.cloud.server.auth.PlainTextUserAuthenticator"/>
+  <bean id="ManagementServer"
+	class="com.cloud.server.ManagementServerImpl"/>
+
+  <bean id="SecondaryStorageVmManager"
+	class="com.cloud.storage.secondary.SecondaryStorageManagerImpl"/>
+
+  <bean id="PodAllocator"
+	class="com.cloud.agent.manager.allocator.impl.UserConcentratedAllocator"/>
+  -->
+  <bean id="com.cloud.vm.UserVmManager"
+	class="com.cloud.vm.UserVmManagerImpl"/>
+
+  <bean id="com.cloud.vm.VirtualMachineManager"
+	class="com.cloud.vm.VirtualMachineManagerImpl"/>
+
+  <!--
+  <bean id="com.cloud.vm.dao.UserVmDao"
+	class="com.cloud.vm.dao.UserVmDaoImpl"/>
+  -->
+  <bean id="ContrailElement"
+        class="org.apache.cloudstack.network.contrail.management.ContrailElementImpl"/>
+
+  <bean id="ContrailGuru"
+        class="org.apache.cloudstack.network.contrail.management.ContrailGuru"/>
+
+  <bean id="networkElements" class="com.cloud.utils.component.AdapterList">
+    <property name="Adapters">
+      <list>
+          <ref bean="ContrailElement"/>
+          <ref bean="VirtualRouterElement"/>
+          <ref bean="SecurityGroupElement"/>
+          <ref bean="VpcVirtualRouterElement"/>
+          <ref bean="InternalLbVm"/>
+      </list>
+    </property>
+  </bean>
+
+  <bean id="networkGurus" class="com.cloud.utils.component.AdapterList">
+    <property name="Adapters">
+      <list>
+          <ref bean="ContrailGuru"/>
+          <ref bean="PublicNetworkGuru"/>
+          <ref bean="PodBasedNetworkGuru"/>
+          <ref bean="ControlNetworkGuru"/>
+          <ref bean="StorageNetworkGuru"/>
+      </list>
+    </property>
+  </bean>
+
+
+  <bean id="networkModelImpl" class="com.cloud.network.NetworkModelImpl">
+    <property name="NetworkElements" value="#{networkElements.Adapters}" />
+  </bean>
+
+  <bean id="networkOrchestrator" class="org.apache.cloudstack.engine.orchestration.NetworkOrchestrator" >
+    <property name="NetworkElements" value="#{networkElements.Adapters}" />
+    <property name="NetworkGurus" value="#{networkGurus.Adapters}" />
+  </bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/contrail.properties
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/contrail.properties b/plugins/network-elements/juniper-contrail/test/resources/contrail.properties
new file mode 100644
index 0000000..0c5207e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/contrail.properties
@@ -0,0 +1,19 @@
+# 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.
+
+api.hostname = 
+api.port = 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/db.properties
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/db.properties b/plugins/network-elements/juniper-contrail/test/resources/db.properties
new file mode 100644
index 0000000..e07d80c
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/db.properties
@@ -0,0 +1,66 @@
+# 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.
+
+cluster.servlet.port=9090
+
+# CloudStack database settings
+db.cloud.username=cloud
+db.cloud.password=cloud
+db.root.password=
+db.cloud.host=localhost
+db.cloud.port=3306
+db.cloud.name=cloud
+
+# CloudStack database tuning parameters
+db.cloud.maxActive=250
+db.cloud.maxIdle=30
+db.cloud.maxWait=10000
+db.cloud.autoReconnect=true
+db.cloud.validationQuery=SELECT 1
+db.cloud.testOnBorrow=true
+db.cloud.testWhileIdle=true
+db.cloud.timeBetweenEvictionRunsMillis=40000
+db.cloud.minEvictableIdleTimeMillis=240000
+db.cloud.poolPreparedStatements=false
+db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLimit=4096
+
+# usage database settings
+db.usage.username=cloud
+db.usage.password=cloud
+db.usage.host=localhost
+db.usage.port=3306
+db.usage.name=cloud_usage
+
+# usage database tuning parameters
+db.usage.maxActive=100
+db.usage.maxIdle=30
+db.usage.maxWait=10000
+db.usage.autoReconnect=true
+
+# awsapi database settings
+db.awsapi.name=cloudbridge
+
+# Simulator database settings
+db.simulator.username=cloud
+db.simulator.password=cloud
+db.simulator.host=localhost
+db.simulator.port=3306
+db.simulator.name=simulator
+db.simulator.maxActive=250
+db.simulator.maxIdle=30
+db.simulator.maxWait=10000
+db.simulator.autoReconnect=true

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/log4j.properties b/plugins/network-elements/juniper-contrail/test/resources/log4j.properties
new file mode 100644
index 0000000..138a961
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/log4j.properties
@@ -0,0 +1,35 @@
+# 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.
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+log4j.appender.stdout.threshold=INFO
+log4j.rootLogger=INFO, stdout, rolling
+log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.rolling.layout=org.apache.log4j.PatternLayout
+log4j.appender.rolling.layout.ConversionPattern=%d %-5p [%c{3}] (%t:%x) %m%n
+log4j.appender.rolling.file.threshold=DEBUG
+log4j.appender.rolling.File=./logs/testclient.log
+log4j.appender.rolling.DatePattern='.'yyy-MM-dd
+log4j.appender.rolling.file.append=false
+log4j.category.org.apache=INFO, rolling, stdout
+#log4j.category.com.cloud.utils.db.Transaction=ALL
+log4j.category.org.apache.cloudstack.network.contrail=ALL
+log4j.category.com.cloud.network=ALL
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh b/plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh
new file mode 100644
index 0000000..265cdea
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/mysql_db_start.sh
@@ -0,0 +1,51 @@
+# 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.
+
+if [ "$#" -ne 1 ] ; then
+   echo "Usage: $0 <port>" >&2
+   exit 1
+fi
+
+PORT=$1
+echo "starting mysql on port: "$PORT
+
+echo "creating temporary mysql db directories /tmp/mysql"$PORT
+mkdir /tmp/mysql$PORT
+mkdir /tmp/mysql$PORT/data
+
+echo "install db";
+
+mysql_install_db --user=$USER --datadir=/tmp/mysql$PORT/data
+mysqld_safe --datadir=/tmp/mysql$PORT/data --socket=/tmp/mysql$PORT/mysqld.sock --port=$PORT --log-error=/tmp/mysql$PORT/mysql.log --pid-file=/tmp/mysql$PORT/mysql.pid --user=$USER &
+
+attempts=0
+while [ $attempts -lt 30 ]; do
+    db=$(mysql -h 127.0.0.1 -P $PORT --user=$USER -e "show databases;")
+    status=$?
+    if [ $status == 0 ]; then
+	break
+    fi
+    attempts=`expr $attempts + 1`
+    sleep 1
+done
+
+echo "new mysql server is started on port "$PORT
+echo $db
+
+echo "commands ...."
+echo "to connect(from local host): mysql -h 127.0.0.1 -P "$PORT 
+echo "to stop: mysqladmin -S /tmp/mysql"$PORT"/mysqld.sock shutdown -u root"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh b/plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh
new file mode 100644
index 0000000..62d70d3
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/mysql_db_stop.sh
@@ -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.
+
+if [ "$#" -ne 1 ] ; then
+   echo "Usage: $0 <port>" >&2
+   exit 1
+fi
+
+echo "Stopping mysql server on port "$1
+
+mysqladmin -S /tmp/mysql$1/mysqld.sock shutdown -u root
+
+rm -rf /tmp/mysql$1
+
+echo "Deleting db directories"
+
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/providerContext.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/providerContext.xml b/plugins/network-elements/juniper-contrail/test/resources/providerContext.xml
new file mode 100644
index 0000000..f412bc0
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/providerContext.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/tx 
+                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+                      http://www.springframework.org/schema/aop
+                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+    <import resource="commonContext.xml"/>
+    <bean id="ProviderTestConfiguration"
+    	class="org.apache.cloudstack.network.contrail.management.ProviderTestConfiguration"/>
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml b/plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml
new file mode 100644
index 0000000..3b67b51
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/resources/publicNetworkContext.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/tx 
+                      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
+                      http://www.springframework.org/schema/aop
+                      http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+    <import resource="commonContext.xml"/>
+    <bean id="PublicNetworkTestConfiguration"
+    	class="org.apache.cloudstack.network.contrail.management.PublicNetworkTestConfiguration"/>
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index ca41dff..e33ebd8 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -42,6 +42,7 @@
     <module>hypervisors/ucs</module>
     <module>network-elements/elastic-loadbalancer</module>
     <module>network-elements/ovs</module>
+    <module>network-elements/juniper-contrail</module>
     <module>network-elements/nicira-nvp</module>
     <module>network-elements/bigswitch-vns</module>
     <module>network-elements/midonet</module>


[5/6] OpenContrail network plugin

Posted by hu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
new file mode 100644
index 0000000..ae9bba9
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
@@ -0,0 +1,769 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.ApiConnectorFactory;
+import net.juniper.contrail.api.ApiPropertyBase;
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.FloatingIp;
+import net.juniper.contrail.api.types.FloatingIpPool;
+import net.juniper.contrail.api.types.VirtualNetwork;
+
+import org.apache.cloudstack.network.contrail.model.FloatingIpModel;
+import org.apache.cloudstack.network.contrail.model.FloatingIpPoolModel;
+import org.apache.cloudstack.network.contrail.model.ModelController;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.ConfigurationService;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.Domain;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.projects.ProjectVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.Account;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.offering.NetworkOffering.State;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offering.NetworkOffering.Availability;
+import com.cloud.offerings.NetworkOfferingVO;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.google.common.collect.ImmutableList;
+
+import java.util.Properties;
+
+import com.cloud.utils.PropertiesUtil;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+@Component
+public class ContrailManagerImpl extends ManagerBase implements ContrailManager {
+    @Inject public ConfigurationService _configService;
+    @Inject NetworkOfferingDao _networkOfferingDao;
+
+    @Inject DomainDao _domainDao;
+    @Inject NetworkDao _networksDao;
+    @Inject VMInstanceDao _vmInstanceDao;
+    @Inject ProjectDao _projectDao;
+    @Inject AccountDao _accountDao;
+    @Inject DataCenterDao _dcDao;
+    @Inject PhysicalNetworkDao _physicalNetworkDao;
+    @Inject PhysicalNetworkServiceProviderDao _physProviderDao;
+    @Inject NicDao _nicDao;
+    @Inject ServerDBSync  _dbSync;
+    @Inject ServerEventHandler  _eventHandler;    
+    @Inject IPAddressDao _ipAddressDao;
+    @Inject VlanDao _vlanDao;
+    @Inject UserVmDao _vmDao;
+
+    private static final Logger s_logger = Logger.getLogger(ContrailManager.class);
+
+    private ApiConnector _api;
+
+    private NetworkOffering _offering;
+    private Timer _dbSyncTimer;
+    private int   _dbSyncInterval = DB_SYNC_INTERVAL_DEFAULT;
+    private final String configuration = "contrail.properties";
+    private ModelDatabase _database;
+    private ModelController _controller;
+    
+    ContrailManagerImpl() {
+        setRunLevel(ComponentLifecycle.RUN_LEVEL_COMPONENT);
+        _database = new ModelDatabase();
+    }
+
+    @Override
+    public boolean start() {
+        /* Start background task */
+        _dbSyncTimer = new Timer("DBSyncTimer");
+        try {
+            _dbSyncTimer.schedule(new DBSyncTask(), 0, _dbSyncInterval);
+        } catch (Exception ex) {
+            s_logger.debug("Unable to start DB Sync timer " + ex.getMessage());
+            s_logger.debug("timer start", ex);
+        }
+        return true;
+    }
+    @Override
+    public boolean stop() {
+         _dbSyncTimer.cancel();
+         return true;
+    }
+    
+    public ModelDatabase getDatabase() {
+        return _database;
+    }
+    
+    private NetworkOffering LocateOffering() {
+        List<? extends NetworkOffering> offerList = _configService.listNetworkOfferings(TrafficType.Guest, false);
+        for (NetworkOffering offer: offerList) {
+            if (offer.getName().equals(offeringName)) {
+                if (offer.getState() != State.Enabled) {
+                    return EnableNetworkOffering(offer.getId());
+                }
+                return offer;
+            }
+        }
+        Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
+        // Map<Service, Map<Capability, String>> serviceCapabilityMap = new HashMap<Service, Map<Capability, String>>();
+        Set<Provider> providerSet = new HashSet<Provider>();
+        providerSet.add(Provider.JuniperContrail);
+        final Service[] services = {
+                Service.Connectivity,
+                Service.Dhcp,
+                Service.NetworkACL,
+                Service.StaticNat,
+                Service.SourceNat
+        };
+        for (Service svc: services) {
+            serviceProviderMap.put(svc, providerSet);
+        }
+        ConfigurationManager configMgr = (ConfigurationManager) _configService;
+        NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText,
+                TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true,
+                Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false);
+
+        voffer.setState(State.Enabled);
+        long id = voffer.getId();
+        _networkOfferingDao.update(id, voffer);
+        return _networkOfferingDao.findById(id);
+    }
+
+    private NetworkOffering EnableNetworkOffering(long id) {
+        NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id);
+        offering.setState(State.Enabled);
+        _networkOfferingDao.update(id, offering);
+        return _networkOfferingDao.findById(id);                
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+
+        File configFile = PropertiesUtil.findConfigFile(configuration);
+        final Properties configProps = new Properties();
+        try {
+            configProps.load(new FileInputStream(configFile));
+            String value = configProps.getProperty("management.db_sync_interval");
+            if (value != null) {
+                _dbSyncInterval = Integer.valueOf(value);
+            }
+
+            String hostname = configProps.getProperty("api.hostname");
+            String portStr = configProps.getProperty("api.port");
+            int port = 0;
+            if (portStr != null && portStr.length() > 0) {
+                port = Integer.parseInt(portStr);
+            }
+            _api = ApiConnectorFactory.build(hostname, port);
+        } catch (IOException ex) {
+            s_logger.warn("Unable to read " + configuration, ex);
+            throw new ConfigurationException();
+        }
+
+        _controller = new ModelController(this, _api, _vmDao, _networksDao, _nicDao, _vlanDao, _ipAddressDao);
+
+        _offering = LocateOffering();
+
+        _eventHandler.subscribe();
+
+        initializeDefaultVirtualNetworkModels();
+
+        return true;
+    }
+
+    @Override
+    public NetworkOffering getOffering() {
+        return _offering;
+    }
+
+    @Override
+    public String getPhysicalNetworkName(PhysicalNetworkVO phys_net) {
+        String physname = phys_net.getName();
+        physname = physname.replaceAll("\\s", "");
+        physname.replace("_", "");
+        return physname;
+    }
+
+    @Override
+    public String getDomainCanonicalName(DomainVO domain) {
+        if (domain.getId() == Domain.ROOT_DOMAIN) {
+            return VNC_ROOT_DOMAIN;
+        }
+        return domain.getName();
+    }
+
+    @Override
+    public String getProjectCanonicalName(ProjectVO project) {
+        return project.getName();
+    }
+
+    @Override
+    public String getCanonicalName(Network net) {
+        String netname;
+        if (net.getTrafficType() == TrafficType.Guest) {
+            return net.getName();
+        } else if (net.getTrafficType() == TrafficType.Management || net.getTrafficType() == TrafficType.Storage) {
+            return managementNetworkName;
+        } else if (net.getTrafficType() == TrafficType.Control) {
+            return "__link_local__";
+        } else {
+            DataCenter zone = _dcDao.findById(net.getDataCenterId());
+            String zonename = zone.getName();
+            zonename = zonename.replaceAll("\\s", "");
+            zonename = zonename.replace("-", "_");
+            netname = "__" + zonename + "_" + net.getTrafficType().toString() + "__";
+        }
+        return netname;
+    }
+
+    @Override
+    public String getDomainName(long domainId) {
+        if (domainId != Domain.ROOT_DOMAIN) {
+            DomainVO domain = _domainDao.findById(domainId);
+            return domain.getName();
+        }
+        return VNC_ROOT_DOMAIN;
+    }
+
+    @Override
+    public String getProjectName(long accountId) {
+        Account account = _accountDao.findById(accountId);
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            ProjectVO project = _projectDao.findByProjectAccountId(account.getId());
+            if (project != null) {
+                return project.getName();
+            }
+        }
+        return VNC_DEFAULT_PROJECT;
+    }
+
+    @Override
+    public String getDefaultPublicNetworkFQN() {
+        String name = VNC_ROOT_DOMAIN + ":" + VNC_DEFAULT_PROJECT + ":" + "__default_Public__";
+        return name; 
+    }
+
+    private ProjectVO getProject(long accountId) {
+        Account account = _accountDao.findById(accountId);
+        if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            return _projectDao.findByProjectAccountId(account.getId());
+        }
+        return null;
+    }
+
+    @Override
+    public String getProjectId(long domainId, long accountId) throws IOException {
+        ProjectVO project = getProject(accountId);
+        if (project != null) {
+            return project.getUuid();
+        }
+        DomainVO domain = _domainDao.findById(domainId);
+        if (domain.getId() != Domain.ROOT_DOMAIN) {
+            net.juniper.contrail.api.types.Domain vncDomain = (net.juniper.contrail.api.types.Domain)
+                    _api.findById(net.juniper.contrail.api.types.Domain.class, domain.getUuid());
+            return _api.findByName(net.juniper.contrail.api.types.Project.class, vncDomain, VNC_DEFAULT_PROJECT);
+        }
+        return null;
+    }
+    
+    @Override
+    public net.juniper.contrail.api.types.Project getVncProject(long domainId, long accountId) throws IOException {
+        String projectId = getProjectId(domainId, accountId);
+        if (projectId == null) {
+            return null;
+        }
+        return (net.juniper.contrail.api.types.Project)
+                _api.findById(net.juniper.contrail.api.types.Project.class, projectId);
+    }
+
+    @Override
+    public String getFQN(Network net) {
+        // domain, project, name
+        String fqname = getDomainName(net.getDomainId());
+        fqname += ":" + getProjectName(net.getAccountId()) + ":";
+        return fqname + getCanonicalName(net);
+    }
+
+    public void findInfrastructureNetworks(PhysicalNetworkVO phys, List<NetworkVO> dbList) {
+        final TrafficType[] ttypes = {
+                TrafficType.Control,    // maps to __link_local__
+                TrafficType.Management, // maps to ip-fabric
+                TrafficType.Public,
+                TrafficType.Storage        // maps to ip-fabric
+        };
+
+        for (int i = 0; i < ttypes.length; i++) {
+            List<NetworkVO> phys_nets;
+            phys_nets = _networksDao.listByZoneAndTrafficType(phys.getDataCenterId(), ttypes[i]);
+            dbList.addAll(phys_nets);
+        }
+
+    }
+
+    public void syncNetworkDB(short syncMode) throws IOException {
+        if (_dbSync.syncAll(syncMode) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
+             if (syncMode == DBSyncGeneric.SYNC_MODE_CHECK) {
+                s_logger.info("# Cloudstack DB & VNC are out of sync #");
+             } else {
+                s_logger.info("# Cloudstack DB & VNC were out of sync, performed re-sync operation #"); 
+             }
+        } else {
+            s_logger.info("# Cloudstack DB & VNC are in sync #");
+        }
+    }
+
+    public class DBSyncTask extends TimerTask {
+        private short _syncMode = DBSyncGeneric.SYNC_MODE_UPDATE;
+        @Override
+        public void run() {
+            try {
+                s_logger.debug("DB Sync task is running");
+                syncNetworkDB(_syncMode);
+                // Change to check mode
+                _syncMode = DBSyncGeneric.SYNC_MODE_CHECK;
+            } catch (Exception ex) {
+                s_logger.debug(ex);
+                s_logger.info("Unable to sync network db");
+            }
+        }
+    }
+
+
+    @Override
+    public boolean isManagedPhysicalNetwork(Network network) {
+        List<PhysicalNetworkVO> net_list = _physicalNetworkDao.listByZone(network.getDataCenterId());
+        for (PhysicalNetworkVO phys : net_list) {
+            if(_physProviderDao.findByServiceProvider(phys.getId(), Network.Provider.JuniperContrail.getName()) != null) {
+                return true;
+            }  
+        }
+        return false;
+    }
+
+    public String findVirtualNetworkId(Network net) throws IOException {
+        if (net.getTrafficType() == TrafficType.Guest) {
+            return net.getUuid();
+        }
+        String netname = getDomainName(net.getDomainId()) + ":" + getProjectName(net.getAccountId()) + ":";
+
+        if (net.getTrafficType() == TrafficType.Control) {
+            netname += "__link_local__";
+        } else if (net.getTrafficType() == TrafficType.Management || net.getTrafficType() == TrafficType.Storage) {
+            netname += managementNetworkName;
+        } else {
+            netname = getFQN(net);
+        }
+        List<String> fqn = ImmutableList.copyOf(StringUtils.split(netname, ':'));
+        return _api.findByName(VirtualNetwork.class, fqn);
+    }
+    
+    @Override
+    public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType) throws IOException {
+        if (trafficType == TrafficType.Guest ||
+                trafficType == TrafficType.Public) {
+            return null;
+        }
+        String netname = VNC_ROOT_DOMAIN + ":" + VNC_DEFAULT_PROJECT + ":";
+        if (trafficType == TrafficType.Control) {
+            netname += "__link_local__";
+        } else if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) {
+            netname += managementNetworkName;
+        }
+        return (VirtualNetwork)_api.findByFQN(VirtualNetwork.class, netname);
+    }
+    
+    /*
+     * Returns list of networks managed by Juniper VRouter filtered by traffic types 
+     */
+    @Override
+    public List<NetworkVO> findJuniperManagedNetworks(List<TrafficType> types) {
+
+        SearchBuilder<NetworkVO> searchBuilder = _networksDao.createSearchBuilder();
+        searchBuilder.and("trafficType", searchBuilder.entity().getTrafficType(), Op.IN);
+        searchBuilder.and("networkOfferingId", searchBuilder.entity().getNetworkOfferingId(), Op.EQ);
+
+        SearchCriteria<NetworkVO> sc = searchBuilder.create();
+        sc.setParameters("networkOfferingId", getOffering().getId());
+
+        if (types == null || types.isEmpty()) {
+            types = new ArrayList<TrafficType>();
+            types.add(TrafficType.Control);    
+            types.add(TrafficType.Management);
+            types.add(TrafficType.Public);
+            types.add(TrafficType.Storage);
+            types.add(TrafficType.Guest);            
+        } 
+        sc.setParameters("trafficType", types.toArray());
+
+        List<NetworkVO> dbNets = _networksDao.search(sc, null);
+        if (dbNets == null) {
+            s_logger.debug("no juniper managed networks for the given traffic types: " + types.toString());
+            dbNets = new ArrayList<NetworkVO>();
+        }
+
+        List<PhysicalNetworkVO> phys_list = _physicalNetworkDao.listAll();
+        final String provider = Network.Provider.JuniperContrail.getName();
+        for (Iterator<PhysicalNetworkVO> iter = phys_list.iterator(); iter.hasNext(); ) {
+            PhysicalNetworkVO phys = iter.next();
+            if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null) {
+                List<NetworkVO> infraNets = new ArrayList<NetworkVO>();
+                findInfrastructureNetworks(phys, infraNets);
+                for (NetworkVO net:infraNets) {
+                    if (types == null || types.isEmpty()) {
+                        dbNets.add(net);
+                        continue;
+                    }
+                    for(TrafficType type:types) {
+                        if (net.getTrafficType() == type) {
+                            dbNets.add(net);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return dbNets; 
+    }
+
+    /*
+     * Returns list of public ip addresses managed by Juniper VRouter 
+     */
+    @Override
+    public List<IPAddressVO> findJuniperManagedPublicIps() {
+
+        List<NetworkVO> dbNets = findJuniperManagedNetworks(null);
+
+        if (dbNets == null || dbNets.isEmpty()) {
+            s_logger.debug("Juniper managed networks is empty");
+            return null;
+        }
+
+        SearchBuilder<IPAddressVO> searchBuilder = _ipAddressDao.createSearchBuilder();
+        searchBuilder.and("sourceNat", searchBuilder.entity().isSourceNat(), Op.EQ);
+        searchBuilder.and("network", searchBuilder.entity().getAssociatedWithNetworkId(), Op.IN);
+        searchBuilder.and("oneToOneNat", searchBuilder.entity().isOneToOneNat(), Op.EQ);
+        searchBuilder.and("associatedWithVmId", searchBuilder.entity().getAssociatedWithVmId(), Op.NNULL);
+
+        List<Long> netIds = new ArrayList<Long>();
+        for (NetworkVO net:dbNets) {
+            netIds.add(net.getId());
+        }
+
+        SearchCriteria<IPAddressVO> sc = searchBuilder.create();
+        sc.setParameters("oneToOneNat", true);
+        sc.setParameters("sourceNat", false);
+        sc.setParameters("network", netIds.toArray());
+
+        List<IPAddressVO> publicIps = _ipAddressDao.search(sc, null);
+        if (publicIps == null) {
+            s_logger.debug("no public ips");
+            return null;
+        } 
+
+        return publicIps;
+    }
+    
+    private void initializeDefaultVirtualNetworkModels() {
+        List<TrafficType> types = new ArrayList<TrafficType>();
+        types.add(TrafficType.Management);
+        types.add(TrafficType.Storage); 
+        types.add(TrafficType.Control); 
+
+        List<NetworkVO> dbNets = findJuniperManagedNetworks(types);
+        for (NetworkVO net:dbNets) {
+            
+            VirtualNetworkModel vnModel = getDatabase().lookupVirtualNetwork(null, getCanonicalName(net), net.getTrafficType());
+            if (vnModel == null) {
+                vnModel = new VirtualNetworkModel(net, null, getCanonicalName(net), net.getTrafficType());
+                vnModel.build(getModelController(), net);
+                try {
+                    if (!vnModel.verify(getModelController())) {
+                        vnModel.update(getModelController());
+                    }
+                } catch (Exception ex) {
+                    s_logger.warn("virtual-network update: ", ex);
+                }
+                getDatabase().getVirtualNetworks().add(vnModel);
+            }
+        }
+    }
+
+    @Override
+    public boolean isSystemDefaultNetwork(VirtualNetwork vnet) {
+        List<String> fqn = vnet.getQualifiedName();
+        if (fqn.size() < 3) {
+            return false;
+        }
+        List<String> default_parent = vnet.getDefaultParent();
+        int index = 0;
+        for (Iterator<String> iter = default_parent.iterator(); iter.hasNext(); index++) {
+            String piece = iter.next();
+            if (!piece.equals(fqn.get(index))) {
+                return false;
+            }
+        }
+        List<String> default_networks = ImmutableList.of("__link_local__", "default-virtual-network", managementNetworkName);
+        for (Iterator<String> iter = default_networks.iterator(); iter.hasNext();) {
+            String name = iter.next();
+            if (name.equals(fqn.get(index))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSystemDefaultNetwork(NetworkVO net) {
+        if (net.getTrafficType() == TrafficType.Management || net.getTrafficType() == TrafficType.Storage
+                || net.getTrafficType() == TrafficType.Control) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSystemRootDomain(net.juniper.contrail.api.types.Domain domain) {
+        if (domain.getName().compareTo(VNC_ROOT_DOMAIN) == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSystemRootDomain(DomainVO domain) {
+        if (domain.getId() == Domain.ROOT_DOMAIN || domain.getName().compareTo("ROOT") == 0 ||
+                domain.getParent() == null) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSystemDefaultProject(net.juniper.contrail.api.types.Project project) {
+        if (project.getName().compareTo(VNC_DEFAULT_PROJECT) == 0) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSystemDefaultProject(ProjectVO project) {
+        return false;
+    }
+
+    @Override
+    public String getVifNameByVmName(String vm_name, Integer device_id) {
+        String vif_name = vm_name + "-" + device_id.toString();
+        return vif_name;
+    }
+
+    @Override
+    public String getVifNameByVmUuid(String vm_uuid, Integer device_id) {
+        VMInstanceVO vm = _vmInstanceDao.findByUuid(vm_uuid);   
+        if (vm != null) {
+            return vm.getInstanceName() + "-" + device_id.toString();
+        }
+        return null;
+    }
+
+    @Override
+    public ModelController getModelController() {
+        return _controller;
+    }
+
+    @Override
+    public ApiConnector getApiConnector() {
+        return _api;
+    }
+
+    public VirtualNetworkModel lookupPublicNetworkModel() {
+        List<TrafficType> types = new ArrayList<TrafficType>();
+        types.add(TrafficType.Public);
+        List<NetworkVO> dbNets = findJuniperManagedNetworks(types);
+        if (dbNets == null) {
+            return null;
+        }
+        NetworkVO net = dbNets.get(0);
+
+        VirtualNetworkModel vnModel = getDatabase().lookupVirtualNetwork(net.getUuid(), getCanonicalName(net), TrafficType.Public);
+        return vnModel;
+    }
+    
+    @Override
+    public void createPublicNetworks() {
+    	List<TrafficType> types = new ArrayList<TrafficType>(Arrays.asList(TrafficType.Public));
+    	List<NetworkVO> dbNets = findJuniperManagedNetworks(types);
+    	if (dbNets == null) {
+    	    return;
+    	}
+    	for (NetworkVO net: dbNets) {
+    	    VirtualNetworkModel vnModel = _database.lookupVirtualNetwork(net.getUuid(), getCanonicalName(net),
+    	            TrafficType.Public);
+    	    if (vnModel != null) {
+    	        continue;
+    	    }
+            vnModel = new VirtualNetworkModel(net, net.getUuid(), getCanonicalName(net), net.getTrafficType());
+            vnModel.build(_controller, net);
+            try {
+                vnModel.update(_controller);
+            } catch (InternalErrorException ex) {
+                s_logger.warn("virtual-network update", ex);
+                continue;
+            } catch (IOException ex) {
+                s_logger.warn("virtual-network update", ex);
+                continue;
+            }
+            _database.getVirtualNetworks().add(vnModel);
+            
+            // Add the Contrail NetworkElement to the Public network.
+            Map<String, String> providerMap = new HashMap<String, String>();
+            providerMap.put(Service.Connectivity.getName(), Provider.JuniperContrail.getName());
+            _networksDao.update(net.getId(), net, providerMap);
+    	}
+    }
+
+    public boolean createFloatingIp(PublicIpAddress ip) {
+        VirtualNetworkModel vnModel = lookupPublicNetworkModel();
+        assert vnModel != null : "public network vn model is null";
+        FloatingIpPoolModel fipPoolModel = vnModel.getFipPoolModel();
+
+        /* create only, no updates */
+        if (fipPoolModel == null) {
+            fipPoolModel = new FloatingIpPoolModel();
+            fipPoolModel.addToVirtualNetwork(vnModel);
+            fipPoolModel.build(getModelController());
+            try {
+                fipPoolModel.update(getModelController());
+                vnModel.setFipPoolModel(fipPoolModel);
+            } catch (Exception ex) {
+                s_logger.warn("floating-ip-pool create: ", ex);
+                return false;
+            }
+        }
+
+        FloatingIpModel fipModel = fipPoolModel.getFloatingIpModel(ip.getUuid());
+        /* create only, no updates*/
+        if (fipModel == null) {
+            fipModel = new FloatingIpModel(ip.getUuid());
+            fipModel.addToFloatingIpPool(fipPoolModel);
+            fipModel.build(getModelController(), ip);
+            try {
+                fipModel.update(getModelController());
+            } catch (Exception ex) {
+                s_logger.warn("floating-ip create: ", ex);
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean deleteFloatingIp(PublicIpAddress ip) {
+        VirtualNetworkModel vnModel = lookupPublicNetworkModel();
+        assert vnModel != null : "public network model is null";
+        FloatingIpPoolModel fipPoolModel = vnModel.getFipPoolModel();
+        FloatingIpModel fipModel = fipPoolModel.getFloatingIpModel(ip.getUuid());
+        if (fipModel != null) {
+            try {
+                fipModel.destroy(getModelController());
+            } catch (IOException ex) {
+                s_logger.warn("floating ip delete", ex);
+                return false;
+            }
+            fipPoolModel.removeSuccessor(fipModel);
+            if (!fipPoolModel.hasDescendents()) {
+                try {
+                    fipPoolModel.delete(getModelController());
+                    vnModel.setFipPoolModel(null);
+                } catch (IOException e) {
+                    return false;
+                }
+            }
+        }
+        return true;        
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<FloatingIp> getFloatingIps() {
+        String fipPoolName = getDefaultPublicNetworkFQN() + ":PublicIpPool";
+        FloatingIpPool fipPool = null;
+        try {
+            fipPool = (FloatingIpPool)_api.findByFQN(FloatingIpPool.class, fipPoolName);
+        } catch (Exception ex) {
+            s_logger.debug(ex);
+        }
+        if (fipPool == null) {
+            return null;
+        }
+        List<ObjectReference<ApiPropertyBase>> ips = fipPool.getFloatingIps();
+        if (ips != null) {
+            try {
+                return (List<FloatingIp>) _api.getObjects(FloatingIp.class, ips);
+            } catch(IOException ex) {
+                s_logger.debug(ex);
+                return null;
+            }
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
new file mode 100644
index 0000000..7be9c55
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/DBSyncGeneric.java
@@ -0,0 +1,322 @@
+// 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.network.contrail.management;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.cloudstack.api.Identity;
+
+import net.juniper.contrail.api.ApiObjectBase;
+
+import org.apache.log4j.Logger;
+
+public class DBSyncGeneric {
+
+    private static final Logger s_logger = Logger.getLogger(DBSyncGeneric.class);
+
+    /* for each synchronization VNC class, following methods
+     * needs to be defined. 
+     * For e.q : VirtualNetwork class should have createMethodPrefix+"VirtualNetwork" etc
+     */ 
+    private final String createMethodPrefix = "create";
+    private final String deleteMethodPrefix = "delete";
+    private final String compareMethodPrefix = "compare";
+    private final String filterMethodPrefix = "filter";
+    private final String equalMethodPrefix = "equal";
+    private final String syncMethodPrefix = "sync";
+    /* default db, vnc comparators are implemented based on uuid values, 
+     * if user defined comparators are required, then only add these methods 
+     */
+    private final String dbComparatorMethodPrefix = "dbComparator";
+    private final String vncComparatorMethodPrefix = "vncComparator";
+
+    /* sync methods implementation object, if implemented in seperate class 
+     * set the scope object
+     */
+    private Object _scope;
+    private HashMap<String, Method> _methodMap;
+    private short  _syncMode;
+
+    public static final short SYNC_MODE_UPDATE = 0;
+    public static final short SYNC_MODE_CHECK = 1;
+    
+    public DBSyncGeneric(Object scope) {
+        this._scope = scope;
+        this._syncMode = SYNC_MODE_UPDATE;
+        setMethodMap();
+    }
+
+    public DBSyncGeneric() {
+        this._scope = this;
+        this._syncMode = SYNC_MODE_UPDATE;
+        setMethodMap();
+    }
+
+    public void setSyncMode(short mode) {
+        this._syncMode = mode;
+    }
+    
+    public short getSyncMode() {
+        return this._syncMode;
+    }
+    
+    public void setScope(Object scope) {
+        this._scope = scope;
+        setMethodMap();
+    }
+
+    public void setMethodMap() {
+        _methodMap = new HashMap<String, Method>();
+        Method methods[] = _scope.getClass().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            _methodMap.put(methods[i].getName(),  methods[i]); 
+        }
+    }
+
+    public static String getClassName(Class<?> cls) {
+        String clsname = cls.getName();
+        int loc = clsname.lastIndexOf('.');
+        if (loc > 0) {
+            clsname = clsname.substring(loc + 1);
+        }
+        return clsname;
+    }
+
+    /*
+     *  This API can be used to sync a particular vnc class
+     */
+    public Boolean sync(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String syncMethod = syncMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(syncMethod);
+        if (method == null) throw new NoSuchMethodException(getClassName(_scope.getClass()) + ":" + syncMethod);
+        return (Boolean)method.invoke(_scope, parameters);
+    }
+
+    private void create(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String createMethod = createMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(createMethod);
+        if (method == null) throw new NoSuchMethodException(getClassName(_scope.getClass()) + ":" + createMethod);
+        method.invoke(_scope, parameters);
+    }
+
+    private void delete(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String deleteMethod = deleteMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(deleteMethod);
+        if (method == null) throw new NoSuchMethodException(getClassName(_scope.getClass()) + ":" + deleteMethod);
+        method.invoke(_scope, parameters);
+    }
+
+    private Integer compare(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String compareMethod = compareMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(compareMethod);
+        if (method == null) throw new NoSuchMethodException(getClassName(_scope.getClass()) + ":" + compareMethod);
+        return (Integer)method.invoke(_scope, parameters);
+    }
+
+    private Boolean filter(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String filterMethod = filterMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(filterMethod);
+        if (method == null) { 
+            s_logger.debug("Method not implemented: " + getClassName(_scope.getClass()) + ":" + filterMethod);
+            return false;
+        }
+        return (Boolean)method.invoke(_scope, parameters);
+    }
+
+    private Boolean equal(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String equalMethod = equalMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(equalMethod);
+        if (method == null) { 
+            s_logger.debug("Method not implemented: " + getClassName(_scope.getClass()) + ":" + equalMethod);
+            return true; 
+        }
+        return (Boolean)method.invoke(_scope, parameters);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private Comparator dbComparator(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String dbComparatorMethod = dbComparatorMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(dbComparatorMethod);
+        if (method == null) return dbComparatorDefault();
+        return (Comparator)method.invoke(_scope, parameters);
+    }
+
+    @SuppressWarnings("rawtypes")
+    private Comparator vncComparator(Class<?> cls, Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        String vncComparatorMethod = vncComparatorMethodPrefix + getClassName(cls);
+        Method method = _methodMap.get(vncComparatorMethod);
+        if (method == null) return vncComparatorDefault();
+        return (Comparator)method.invoke(_scope, parameters);
+    }
+
+
+    @SuppressWarnings("rawtypes")
+    public Comparator dbComparatorDefault() {
+        Comparator comparator = new Comparator<Identity>() {
+            public int compare(Identity u1, Identity u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    @SuppressWarnings("rawtypes")
+    public Comparator vncComparatorDefault() {
+        Comparator comparator = new Comparator<ApiObjectBase>() {
+            public int compare(ApiObjectBase u1, ApiObjectBase u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+
+    public static class SyncStats {
+        public int create;
+        public int delete;
+        public int equal;
+        public int diff;
+        public int filter;
+        public StringBuffer logMsg;
+        SyncStats() {
+            logMsg = new StringBuffer();
+        }
+        void log(String str) {
+            logMsg.append(str);
+            logMsg.append('\n');
+        }
+        public boolean isSynchronized() {
+            return create == 0 && delete == 0 && diff == 0;
+        }
+        public String toString() {
+            StringBuffer str = new StringBuffer();
+            str.append("create: " + create);
+            str.append(", delete: " + delete);
+            if (filter > 0) {
+                str.append(", filter: " + filter);
+            }
+            str.append(", equal: " + equal);
+            str.append(", diff:" + diff);
+            return str.toString();
+        }
+    }
+    
+    public void syncCollections(Class<?> cls, Collection<?> lhsList, Collection<?> rhsList, boolean modifyMode,
+            SyncStats stats) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
+        java.util.Iterator<?> lhsIter = lhsList.iterator();
+        java.util.Iterator<?> rhsIter =  rhsList.iterator();
+      
+        Object lhsItem = lhsIter.hasNext() ? lhsIter.next() : null;
+        Object rhsItem = rhsIter.hasNext() ? rhsIter.next() : null;
+
+        while (lhsItem != null && rhsItem != null) {
+            Integer cmp = this.compare(cls, lhsItem, rhsItem, stats.logMsg);
+            if (cmp < 0) {
+                // Create
+                if (modifyMode) {
+                    this.create(cls, lhsItem, stats.logMsg);
+                }
+                stats.create++;
+                lhsItem = lhsIter.hasNext() ? lhsIter.next() : null;
+            } else if (cmp > 0) {
+                // Delete
+                if (!this.filter(cls, rhsItem, stats.logMsg)) {
+                    if (modifyMode) {
+                        this.delete(cls, rhsItem, stats.logMsg);
+                    }
+                    stats.delete++;
+                } else {
+                    stats.filter++;
+                }
+                rhsItem = rhsIter.hasNext() ? rhsIter.next() : null;
+            } else {
+                // Equal 
+                if (this.equal(cls, lhsItem, rhsItem, stats.logMsg)) {
+                    stats.equal++;
+                } else {
+                    stats.diff++;
+                }
+                lhsItem = lhsIter.hasNext() ? lhsIter.next() : null;
+                rhsItem = rhsIter.hasNext() ? rhsIter.next() : null;
+            }
+        }
+
+        while (lhsItem != null) {
+            // Create
+            if (modifyMode) {
+               this.create(cls, lhsItem, stats.logMsg);
+            }
+            stats.create++;
+            lhsItem = lhsIter.hasNext() ? lhsIter.next() : null;
+        }
+
+        while (rhsItem != null) {
+            // Delete
+            if (!this.filter(cls, rhsItem, stats.logMsg)) {
+                if (modifyMode) {
+                    this.delete(cls, rhsItem, stats.logMsg);
+                }
+                stats.delete++;
+            } else {
+                stats.filter++;
+            }
+            rhsItem = rhsIter.hasNext() ? rhsIter.next() : null;
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    public boolean syncGeneric(Class<?> cls, List<?> dbList, List<?> vncList) throws Exception {
+        SyncStats stats = new SyncStats();
+        stats.log("Sync log for <" + getClassName(cls) + ">");
+
+        s_logger.debug("Generic db sync : " + getClassName(cls));
+
+        java.util.Collections.sort(dbList, this.dbComparator(cls));
+        java.util.Collections.sort(vncList, this.vncComparator(cls));
+
+        syncCollections(cls, dbList, vncList, _syncMode != SYNC_MODE_CHECK, stats);
+        
+        if (_syncMode != SYNC_MODE_CHECK) {
+            s_logger.debug("Sync stats<" + getClassName(cls) + ">:  " + stats.toString());
+            s_logger.debug(stats.logMsg);
+            s_logger.debug("Generic db sync : " + getClassName(cls) + " done");
+        } else {
+            s_logger.debug("Sync state checking stats<" + getClassName(cls) + ">: " + stats.toString());
+            if (!stats.isSynchronized()) {
+                s_logger.debug("DB and VNC objects out of sync is detected : " + getClassName(cls));
+                s_logger.debug("Log message: \n" + stats.logMsg);
+            } else {
+                s_logger.debug("DB and VNC objects are in sync : " + getClassName(cls));            
+            }
+        }
+        
+        /* return value of this method indicates state of the db & vnc before sync
+         * false: out of sync, true: in sync; 
+         * it does not indicate whether sync operation is performed or not;
+         * Actual sync is done only if _syncMode is UPDATE 
+         */
+        return stats.isSynchronized();
+    }
+
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java
new file mode 100644
index 0000000..dd18ca6
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/EventUtils.java
@@ -0,0 +1,120 @@
+// 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.network.contrail.management;
+
+import com.cloud.event.ActionEvent;
+import com.cloud.event.Event;
+import com.cloud.event.EventCategory;
+import com.cloud.event.EventTypes;
+import com.cloud.server.ManagementServer;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ComponentMethodInterceptor;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.messagebus.MessageBusBase;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class EventUtils {
+    private static final Logger s_logger = Logger.getLogger(EventUtils.class);
+
+    protected static MessageBus _messageBus = null;
+
+    public EventUtils() {
+    }
+
+    private static void publishOnMessageBus(String eventCategory,
+            String eventType, String details, Event.State state) {
+
+        if (state != com.cloud.event.Event.State.Completed) {
+            return;
+        }
+
+        try {
+            _messageBus =  (MessageBus)ComponentContext.getComponent(MessageBusBase.class);
+        } catch(NoSuchBeanDefinitionException nbe) {
+            return; // no provider is configured to provide events bus, so just return
+        }
+
+        org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event(
+                ManagementServer.Name,
+                eventCategory,
+                eventType,
+                EventTypes.getEntityForEvent(eventType), null);
+
+        Map<String, String> eventDescription = new HashMap<String, String>();
+        eventDescription.put("event", eventType);
+        eventDescription.put("status", state.toString());
+        eventDescription.put("details", details);
+        event.setDescription(eventDescription);
+        try {
+            _messageBus.publish(EventTypes.getEntityForEvent(eventType), eventType, null, event);
+        } catch (Exception e) {
+            s_logger.warn("Failed to publish action event on the the event bus.");
+        }
+
+    }
+
+    public static class EventInterceptor implements ComponentMethodInterceptor {
+
+        private static final Logger s_logger = Logger.getLogger(EventInterceptor.class);
+
+        public EventInterceptor() {
+
+        }
+
+        @Override
+        public Object interceptStart(Method method, Object target) {
+            return null;
+        }
+
+        @Override
+        public void interceptComplete(Method method, Object target, Object event) {
+            ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+            if (actionEvent != null) {
+                CallContext ctx = CallContext.current();
+                if (!actionEvent.create()) {
+                    publishOnMessageBus(EventCategory.ACTION_EVENT.getName(), 
+                            actionEvent.eventType(), ctx.getEventDetails(), com.cloud.event.Event.State.Completed);
+                }
+            }
+        }
+
+        @Override
+        public void interceptException(Method method, Object target, Object event) {
+            s_logger.debug("interceptException");
+        }
+
+        @Override
+        public boolean needToIntercept(Method method) {
+            ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+            if (actionEvent != null) {
+                return true;
+            }
+
+            return false;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
new file mode 100644
index 0000000..e457023
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ManagementNetworkGuru.java
@@ -0,0 +1,114 @@
+// 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.network.contrail.management;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.PropertiesUtil;
+
+/**
+ * ManagementNetworkGuru
+ * 
+ * Replace the default management network strategy (PodBasedNetworkGuru) by using a Isolated network for management
+ * traffic.
+ */
+@Component
+public class ManagementNetworkGuru extends ContrailGuru {
+    private static final Logger s_logger = Logger.getLogger(ManagementNetworkGuru.class);
+    private static final TrafficType[] _trafficTypes = {TrafficType.Management};
+
+    private final String configuration = "contrail.properties";
+    private String _mgmt_cidr;
+    private String _mgmt_gateway;
+
+    @Override
+    public String getName() {
+        return "ManagementNetworkGuru";
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        File configFile = PropertiesUtil.findConfigFile(configuration);
+        final Properties configProps = new Properties();
+        try {
+            configProps.load(new FileInputStream(configFile));
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new ConfigurationException(ex.getMessage());
+        }
+        _mgmt_cidr = configProps.getProperty("management.cidr");
+        _mgmt_gateway = configProps.getProperty("management.gateway");
+        s_logger.info("Management network " + _mgmt_cidr + " gateway: " + _mgmt_gateway);
+        return true;
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return _trafficTypes;
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : _trafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean canHandle(NetworkOffering offering) {
+        TrafficType type = offering.getTrafficType();
+        return (isMyTrafficType(type));
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan,
+            Network userSpecified, Account owner) {
+        
+        if (!canHandle(offering)) {
+            return null;
+        }
+        NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch,
+                offering.getId(), Network.State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId());
+        if (_mgmt_cidr != null) {
+            network.setCidr(_mgmt_cidr);
+            network.setGateway(_mgmt_gateway);
+        }
+        s_logger.debug("Allocated network " + userSpecified.getName() +
+                (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
+        return network;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
new file mode 100644
index 0000000..f705f07
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ModelDatabase.java
@@ -0,0 +1,89 @@
+// 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.network.contrail.management;
+
+import java.util.TreeSet;
+
+import org.apache.cloudstack.network.contrail.model.ModelObjectBase;
+import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+
+import com.cloud.network.Networks.TrafficType;
+
+public class ModelDatabase {
+    TreeSet<ServiceInstanceModel> _serviceInstanceTable;
+    TreeSet<VirtualMachineModel> _vmTable;
+    TreeSet<VirtualNetworkModel> _vnTable;
+    
+    ModelDatabase() {
+        initDb();
+    }
+
+    public void initDb() {
+        _serviceInstanceTable = new TreeSet<ServiceInstanceModel>(new ModelObjectBase.UuidComparator());
+        _vmTable = new TreeSet<VirtualMachineModel>(new ModelObjectBase.UuidComparator());
+        _vnTable = new TreeSet<VirtualNetworkModel>(new ModelObjectBase.UuidComparator());
+    }
+    
+    public TreeSet<ServiceInstanceModel> getServiceInstances() {
+        return _serviceInstanceTable;
+    }
+    
+    public ServiceInstanceModel lookupServiceInstance(String uuid) {
+        ServiceInstanceModel siKey = new ServiceInstanceModel(uuid);
+        ServiceInstanceModel current = _serviceInstanceTable.ceiling(siKey);
+        if  (current != null && current.getUuid().equals(uuid)) {
+            return current;
+        }
+        return null;
+    }
+    
+    public TreeSet<VirtualMachineModel> getVirtualMachines() {
+        return _vmTable;
+    }
+    
+    public VirtualMachineModel lookupVirtualMachine(String uuid) {
+        VirtualMachineModel vmKey = new VirtualMachineModel(null, uuid);
+        VirtualMachineModel current = _vmTable.ceiling(vmKey);
+        if (current != null && current.getUuid().equals(uuid)) {
+            return current;
+        }
+        return null;
+    }
+    
+    public TreeSet<VirtualNetworkModel> getVirtualNetworks() {
+        return _vnTable;
+    }
+    
+    public VirtualNetworkModel lookupVirtualNetwork(String uuid, String name, TrafficType ttype) {
+        VirtualNetworkModel vnKey = new VirtualNetworkModel(null, uuid, name, ttype);
+        VirtualNetworkModel current = _vnTable.ceiling(vnKey);
+        if (current != null) {
+            if (ttype == TrafficType.Management || ttype == TrafficType.Storage
+                    || ttype == TrafficType.Control) {
+                if (current.getName().equals(name)) {
+                    return current;
+                }
+            } else if (current.getUuid().equals(uuid)) {
+                return current;
+            } 
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
new file mode 100644
index 0000000..fea9a95
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java
@@ -0,0 +1,39 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+
+import com.cloud.domain.DomainVO;
+import com.cloud.projects.ProjectVO;
+
+public interface ServerDBSync {
+
+
+    public final static short SYNC_STATE_IN_SYNC = 0;
+    public final static short SYNC_STATE_OUT_OF_SYNC = 1;
+    public final static short SYNC_STATE_UNKNOWN = -1;
+    /*
+     * API for syncing all classes of vnc objects with cloudstack
+     * Sync cloudstack and vnc objects.
+     */
+    public short syncAll(short syncMode);
+    public void syncClass(Class<?> cls);
+    public void createProject(ProjectVO project, StringBuffer syncLogMesg) throws IOException;
+    public void createDomain(DomainVO domain, StringBuffer logMesg)throws IOException;
+}


[4/6] OpenContrail network plugin

Posted by hu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
new file mode 100644
index 0000000..8cb4e8d
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java
@@ -0,0 +1,965 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import java.lang.reflect.Method;
+
+import net.juniper.contrail.api.types.FloatingIp;
+import net.juniper.contrail.api.types.FloatingIpPool;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VirtualMachine;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.InstanceIp;
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.ApiObjectBase;
+import net.juniper.contrail.api.ApiPropertyBase;
+import net.juniper.contrail.api.ObjectReference;
+
+import org.apache.cloudstack.network.contrail.model.FloatingIpModel;
+import org.apache.cloudstack.network.contrail.model.FloatingIpPoolModel;
+import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel;
+import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.projects.ProjectVO;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.network.IpAddress;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.VMInstanceDao;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.NicVO;
+import com.cloud.network.addr.PublicIp;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
+
+import javax.inject.Inject;
+
+@Component
+public class ServerDBSyncImpl implements ServerDBSync {
+
+    @Inject DomainDao _domainDao;
+    @Inject ProjectDao _projectDao;
+    @Inject NetworkDao _networksDao;
+    @Inject VMInstanceDao _vmInstanceDao;
+    @Inject NicDao _nicDao;
+    @Inject VlanDao _vlanDao;
+    @Inject PhysicalNetworkDao _physicalNetworkDao;
+    @Inject PhysicalNetworkServiceProviderDao _physProviderDao;
+    @Inject ContrailManager _manager;
+    DBSyncGeneric _dbSync;
+    Class<?>[] _vncClasses;
+    // Read-Write (true) or Read-Only mode.
+    boolean _rw_mode;
+    private final ReentrantLock _lockSyncMode = new ReentrantLock(); 
+
+    ServerDBSyncImpl() {
+        _vncClasses = new Class[] {
+                net.juniper.contrail.api.types.Domain.class,
+                net.juniper.contrail.api.types.Project.class,
+                VirtualNetwork.class,
+                VirtualMachine.class,
+                ServiceInstance.class,
+                FloatingIp.class
+        };
+        _dbSync = new DBSyncGeneric(this);
+    }
+
+    private static final Logger s_logger = Logger.getLogger(ServerDBSync.class);
+
+    /*
+     * API for syncing all classes of vnc objects with cloudstack
+     *
+     * Sync cloudstack and vnc objects.
+     * Order has to be maintained 
+     */
+    @Override
+    public short syncAll(short syncMode) {
+        short syncState = SYNC_STATE_IN_SYNC;
+        
+        /* vnc classes need to be synchronized with cloudstack */
+        s_logger.debug("syncing cloudstack db with vnc");
+        try {
+            for(Class<?> cls : _vncClasses) {
+                
+                /* lock the sync mode*/
+                _lockSyncMode.lock();
+                _rw_mode = syncMode == DBSyncGeneric.SYNC_MODE_UPDATE;
+                _dbSync.setSyncMode(syncMode);
+                
+                if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
+                    s_logger.debug("sync check start: " + DBSyncGeneric.getClassName(cls));
+                } else {
+                    s_logger.debug("sync start: " + DBSyncGeneric.getClassName(cls));
+                }
+
+                if (_dbSync.sync(cls) == false) {
+                    if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
+                        s_logger.info("out of sync detected: " + DBSyncGeneric.getClassName(cls));
+                    } else {
+                        s_logger.info("out of sync detected and re-synced: " + DBSyncGeneric.getClassName(cls));
+                    }
+                    syncState = SYNC_STATE_OUT_OF_SYNC;
+                }
+                if (_dbSync.getSyncMode() == DBSyncGeneric.SYNC_MODE_CHECK) {
+                    s_logger.debug("sync check finish: " + DBSyncGeneric.getClassName(cls));
+                } else {
+                    s_logger.debug("sync finish: " + DBSyncGeneric.getClassName(cls));
+                }
+                /* unlock the sync mode */
+                _lockSyncMode.unlock();
+            } 
+        } catch(Exception ex) {
+            s_logger.warn("DB Synchronization", ex);
+            syncState = SYNC_STATE_UNKNOWN;
+            if (_lockSyncMode.isLocked()) {
+                _lockSyncMode.unlock();
+            }
+        }
+
+        return syncState;
+    } 
+    
+    @Override
+    public void syncClass(Class<?> cls) {
+
+        s_logger.debug("syncClass: " + cls.getName());
+        try {
+            s_logger.debug("sync start: " + DBSyncGeneric.getClassName(cls));
+            _lockSyncMode.lock();
+            _dbSync.setSyncMode(DBSyncGeneric.SYNC_MODE_UPDATE);
+            _dbSync.sync(cls);
+            _lockSyncMode.unlock();
+            s_logger.debug("sync finish: " + DBSyncGeneric.getClassName(cls));
+        } catch(Exception ex) {
+            s_logger.warn("Sync error: " + cls.getName(), ex);
+            if (_lockSyncMode.isLocked()) {
+                _lockSyncMode.unlock();
+            }            
+        }        
+    }
+
+    public <T extends ApiPropertyBase> void deleteChildren(List<ObjectReference<T>> childs,  Class<?> childCls, StringBuffer syncLogMesg) throws Exception {
+        final ApiConnector api = _manager.getApiConnector();
+        if (childs == null) {
+            syncLogMesg.append("no children of type: " + childCls.getName() + "\n");
+            return;
+        }
+        
+        syncLogMesg.append("delete children of type : " + DBSyncGeneric.getClassName(childCls) + "\n");
+        String deleteChildMethod = "delete" + DBSyncGeneric.getClassName(childCls);
+        Method method = null;
+        Method methods[] = this.getClass().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            if(methods[i].getName().equalsIgnoreCase(deleteChildMethod)) {
+                method = methods[i];
+                break;
+            }
+        }
+        int count = 0;
+        for (ObjectReference<T> childRef: childs) {
+            @SuppressWarnings("unchecked")
+            ApiObjectBase child = (ApiObjectBase) api.findById((Class<? extends ApiObjectBase>)childCls, childRef.getUuid());
+            if (method != null) { 
+               method.invoke(this, child, syncLogMesg);
+            } else {
+                deleteDefault(child, childCls, syncLogMesg);
+            }
+            count ++;
+        }
+        syncLogMesg.append("deleted children count : " + count + "\n"); 
+    }
+
+    public void deleteDefault(ApiObjectBase vnc, Class<?> cls, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        api.delete(vnc);
+        syncLogMesg.append(cls.getCanonicalName() + "# VNC: " + vnc.getName() + " deleted\n");
+    }
+
+    /*
+     *  Domain Synchronization methods
+     */
+    public boolean syncDomain() throws Exception {
+        final ApiConnector api = _manager.getApiConnector();
+        try {
+            List<?> dbList = _domainDao.listAll();
+            @SuppressWarnings("unchecked")
+            List<?> vncList = (List<net.juniper.contrail.api.types.Domain>) api.list(net.juniper.contrail.api.types.Domain.class, null);
+            return _dbSync.syncGeneric(net.juniper.contrail.api.types.Domain.class, dbList, vncList);
+        } catch (Exception ex) {
+            s_logger.warn("syncDomain", ex);
+            throw ex;
+        }
+    }
+
+    @Override
+    public void createDomain(DomainVO db, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        net.juniper.contrail.api.types.Domain vnc = new net.juniper.contrail.api.types.Domain();
+        vnc.setName(db.getName());
+        vnc.setUuid(db.getUuid());
+        if (!api.create(vnc)) {
+            s_logger.error("Unable to create domain " + vnc.getName());
+            syncLogMesg.append("Error: Virtual domain# VNC : Unable to create domain: " + 
+                    vnc.getName() + "\n");
+            return;
+        }
+        syncLogMesg.append("Domain# VNC: " + vnc.getName() + " created \n");
+    }
+
+    public void deleteDomain(net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        api.read(vnc);
+        syncLogMesg.append("Domain# DB: none; VNC: " + vnc.getName() + "(" + 
+                vnc.getUuid() + "); action: delete\n");
+
+        /* delete all projects under this domain */
+        try {
+            deleteChildren(vnc.getProjects(), net.juniper.contrail.api.types.Project.class, syncLogMesg);
+        } catch (Exception ex) {
+            s_logger.warn("deleteDomain", ex);
+        }
+
+        api.delete(vnc);
+        syncLogMesg.append("Domain# VNC: " + vnc.getName() + " deleted\n");
+    }
+
+    public Integer compareDomain(DomainVO db, net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) {
+        if (_manager.isSystemRootDomain(db) && _manager.isSystemRootDomain(vnc)) {
+            return _manager.getDomainCanonicalName(db).compareTo(vnc.getName());
+        } else if (_manager.isSystemRootDomain(db)) {
+            return -1;
+        } else if (_manager.isSystemRootDomain(vnc)) {
+            return 1;
+        }
+        return db.getUuid().compareTo(vnc.getUuid());
+    }
+
+    public Boolean filterDomain(net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg)  {
+        if (_manager.isSystemRootDomain(vnc)) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean equalDomain(DomainVO db, net.juniper.contrail.api.types.Domain vnc, StringBuffer syncLogMesg) {
+        syncLogMesg.append("Domain# DB: " + db.getName() + "; VNC: " + 
+                vnc.getName() + "; action: equal, no action\n");
+        return true;
+    }
+
+    public Comparator<?> dbComparatorDomain() {
+        Comparator<?> comparator = new Comparator<DomainVO>() {
+            public int compare(DomainVO u1, DomainVO u2) {
+                if (_manager.isSystemRootDomain(u1)) {
+                    return -1;
+                }
+                if (_manager.isSystemRootDomain(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public Comparator<?> vncComparatorDomain() {
+        Comparator<?> comparator = new Comparator<net.juniper.contrail.api.types.Domain> () {
+            public int compare(net.juniper.contrail.api.types.Domain u1, net.juniper.contrail.api.types.Domain u2) {
+                if (_manager.isSystemRootDomain(u1)) {
+                    return -1;
+                }
+                if (_manager.isSystemRootDomain(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    /*
+     *  Project Synchronization methods
+     */
+    @SuppressWarnings("unchecked")
+    public boolean syncProject() throws Exception {
+        final ApiConnector api = _manager.getApiConnector();
+        try {
+            List<?> dbList = _projectDao.listAll();
+            List<?> vncList = (List<net.juniper.contrail.api.types.Project>) api.list(net.juniper.contrail.api.types.Project.class, null);
+            return _dbSync.syncGeneric(net.juniper.contrail.api.types.Project.class, dbList, vncList);
+        } catch (Exception ex) {
+            s_logger.warn("syncProject", ex);
+            throw ex;
+        }
+    }
+
+    @Override
+    public void createProject(ProjectVO db, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        net.juniper.contrail.api.types.Project vnc = new net.juniper.contrail.api.types.Project();
+        vnc.setName(db.getName());
+        vnc.setUuid(db.getUuid());
+        if (!api.create(vnc)) {
+            s_logger.error("Unable to create project: " + vnc.getName());
+            syncLogMesg.append("Error: Virtual project# VNC : Unable to create project: " + 
+                    vnc.getName() + "\n");
+            return;
+        }
+        syncLogMesg.append("Project# VNC: " + vnc.getName() + " created \n");
+    }
+
+    public void deleteProject(net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        api.read(vnc);
+        syncLogMesg.append("Project# DB: none; VNC: " + vnc.getName() + "(" + 
+                vnc.getUuid() + "); action: delete\n");
+
+        try {
+            deleteChildren(vnc.getVirtualNetworks(), VirtualNetwork.class, syncLogMesg);
+            deleteChildren(vnc.getSecurityGroups(), net.juniper.contrail.api.types.SecurityGroup.class, syncLogMesg);
+            deleteChildren(vnc.getNetworkIpams(), net.juniper.contrail.api.types.NetworkIpam.class, syncLogMesg);
+            deleteChildren(vnc.getNetworkPolicys(), net.juniper.contrail.api.types.NetworkPolicy.class, syncLogMesg);
+        } catch (Exception ex) {
+            s_logger.warn("deleteProject", ex);
+        }
+
+        api.delete(vnc);
+        syncLogMesg.append("Project# VNC: " + vnc.getName() + " deleted\n");
+    }
+
+    public Integer compareProject(ProjectVO db, net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) {
+        if (_manager.isSystemDefaultProject(db) && _manager.isSystemDefaultProject(vnc)) {
+            return _manager.getProjectCanonicalName(db).compareTo(vnc.getName());
+        } else if (_manager.isSystemDefaultProject(db)) {
+            return -1;
+        } else if (_manager.isSystemDefaultProject(vnc)) {
+            return 1;
+        }
+        return db.getUuid().compareTo(vnc.getUuid());
+    }
+
+    public Boolean filterProject(net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg)  {
+        if (_manager.isSystemDefaultProject(vnc)) {
+            syncLogMesg.append("VNC: " + vnc.getName() + " filtered; action: don't delete\n");
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean equalProject(ProjectVO db, net.juniper.contrail.api.types.Project vnc, StringBuffer syncLogMesg) {
+        syncLogMesg.append("Project# DB: " + db.getName() + "; VNC: " + 
+                vnc.getName() + "; action: equal, no action\n");
+        return true;
+    }
+
+    public Comparator<?> dbComparatorProject() {
+        Comparator<?> comparator = new Comparator<ProjectVO>() {
+            public int compare(ProjectVO u1, ProjectVO u2) {
+                if (_manager.isSystemDefaultProject(u1)) {
+                    return -1;
+                } 
+                if (_manager.isSystemDefaultProject(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public Comparator<?> vncComparatorProject() {
+        Comparator<?> comparator = new Comparator<net.juniper.contrail.api.types.Project> () {
+            public int compare(net.juniper.contrail.api.types.Project u1, net.juniper.contrail.api.types.Project u2) {
+                if (_manager.isSystemDefaultProject(u1)) {
+                    return -1;
+                }
+                if (_manager.isSystemDefaultProject(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    /*
+     * Security Groups
+     */
+    
+    public void deleteSecurityGroup(net.juniper.contrail.api.types.SecurityGroup vnc, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        api.delete(vnc);
+        syncLogMesg.append("SecurityGroup# VNC: " + vnc.getName() + " deleted\n");
+    }
+    
+    /*
+     *  Virtual Network Synchronization methods
+     */
+    @SuppressWarnings({ "unchecked" })
+    public boolean syncVirtualNetwork() throws Exception {
+        final ApiConnector api = _manager.getApiConnector();
+        try {
+
+            List<TrafficType> types = new ArrayList<TrafficType>();
+            types.add(TrafficType.Public);
+            types.add(TrafficType.Guest);            
+            List<NetworkVO> dbNets = _manager.findJuniperManagedNetworks(types);
+
+            List<VirtualNetwork> vList = (List<VirtualNetwork>) api.list(VirtualNetwork.class, null);
+            List<VirtualNetwork> vncList = new ArrayList<VirtualNetwork>(); 
+            for (VirtualNetwork vn:vList) {
+                if (!_manager.isSystemDefaultNetwork(vn)) {
+                    vncList.add(vn);
+                }
+            }
+            s_logger.debug("sync VN - DB size: " + dbNets.size() + " VNC Size: " + vncList.size());
+            return _dbSync.syncGeneric(VirtualNetwork.class, dbNets, vncList);
+        } catch (Exception ex) {
+            s_logger.warn("sync virtual-networks", ex);
+            throw ex;
+        }
+    }
+
+    public Comparator<NetworkVO> dbComparatorVirtualNetwork() {
+        Comparator<NetworkVO> comparator = new Comparator<NetworkVO>() {
+            public int compare(NetworkVO u1, NetworkVO u2) {
+                if (_manager.isSystemDefaultNetwork(u1) && _manager.isSystemDefaultNetwork(u2)) {
+                    return _manager.getCanonicalName(u1).compareTo(_manager.getCanonicalName(u2));
+                } else if (_manager.isSystemDefaultNetwork(u1)) {
+                    return -1;
+                } else if (_manager.isSystemDefaultNetwork(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public Comparator<?> vncComparatorVirtualNetwork() {
+        Comparator<?> comparator = new Comparator<VirtualNetwork>() {
+            public int compare(VirtualNetwork u1, VirtualNetwork u2) {
+                if (_manager.isSystemDefaultNetwork(u1) && _manager.isSystemDefaultNetwork(u2)) {
+                    return u1.getName().compareTo(u2.getName());
+                } else if (_manager.isSystemDefaultNetwork(u1)) {
+                    return -1;
+                } else if (_manager.isSystemDefaultNetwork(u2)) {
+                    return 1;
+                }
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public void createVirtualNetwork(NetworkVO dbNet, StringBuffer syncLogMesg) throws IOException {
+        syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbNet) +
+                "(" + dbNet.getUuid() + "); VNC: none;  action: create\n");
+        
+        if (_manager.getDatabase().lookupVirtualNetwork(dbNet.getUuid(), 
+                _manager.getCanonicalName(dbNet), dbNet.getTrafficType()) != null) {
+             s_logger.warn("VN model object is already present in DB: " + 
+                                   dbNet.getUuid() + ", name: " + dbNet.getName());      
+        }
+        
+        VirtualNetworkModel vnModel = new VirtualNetworkModel(dbNet, 
+                dbNet.getUuid(), _manager.getCanonicalName(dbNet), dbNet.getTrafficType());
+        vnModel.build(_manager.getModelController(), dbNet);
+
+        if (_rw_mode) {
+            try {
+                if (!vnModel.verify(_manager.getModelController())) {
+                    vnModel.update(_manager.getModelController());
+                }
+            } catch (InternalErrorException ex) {
+                s_logger.warn("create virtual-network", ex);
+                syncLogMesg.append("Error: VN# VNC : Unable to create network " + 
+                    dbNet.getName() + "\n");
+                return;
+            }
+            s_logger.debug("add model " + vnModel.getName());
+            _manager.getDatabase().getVirtualNetworks().add(vnModel);
+            syncLogMesg.append("VN# VNC: " + dbNet.getUuid() + ", " + vnModel.getName() + " created\n");
+        } else {
+            syncLogMesg.append("VN# VNC: " + vnModel.getName() + " created \n");
+        }
+    }
+
+
+    public void deleteVirtualNetwork(VirtualNetwork vnet, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        if (_manager.isSystemDefaultNetwork(vnet)) {
+            syncLogMesg.append("VN# System default virtual Network# VNC: " + vnet.getName() + " can not be deleted\n");
+            return;
+        }
+        api.read(vnet);
+
+        deleteInstanceIps(vnet.getInstanceIpBackRefs(), syncLogMesg);
+        
+        List<ObjectReference<ApiPropertyBase>> fipPools = vnet.getFloatingIpPools();
+        if (fipPools != null && !fipPools.isEmpty()) {
+            FloatingIpPool floatingIpPool = (FloatingIpPool) api.findById(FloatingIpPool.class, fipPools.get(0).getUuid());
+            if (floatingIpPool != null ) {
+                deleteFloatingIps(floatingIpPool.getFloatingIps(), syncLogMesg);
+            } 
+        }
+        
+        deleteVirtualMachineInterfaces(vnet.getVirtualMachineInterfaceBackRefs(), syncLogMesg);
+
+        syncLogMesg.append("VN# DB: none; VNC: " + vnet.getName() + "(" + vnet.getUuid() + "); action: delete\n");
+        api.delete(vnet);
+        syncLogMesg.append("VN# VNC: " + vnet.getName() + " deleted\n");
+    }
+
+    public Integer compareVirtualNetwork(NetworkVO dbn, VirtualNetwork vnet, StringBuffer syncLogMesg) {
+        if (_manager.isSystemDefaultNetwork(dbn) && _manager.isSystemDefaultNetwork(vnet)) {
+            return _manager.getCanonicalName(dbn).compareTo(vnet.getName());
+        } else if (_manager.isSystemDefaultNetwork(dbn)) {
+            return -1;
+        } else if (_manager.isSystemDefaultNetwork(vnet)) {
+            return 1;
+        }
+        return dbn.getUuid().compareTo(vnet.getUuid());
+    }
+
+    public Boolean filterVirtualNetwork(VirtualNetwork vnet, StringBuffer syncLogMesg)  {
+        if (_manager.isSystemDefaultNetwork(vnet)) {
+            syncLogMesg.append("VN# VNC: " + vnet.getName() + " filtered; action: don't delete\n");
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean equalVirtualNetwork(NetworkVO dbn, VirtualNetwork vnet, StringBuffer syncLogMesg) {
+        syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbn) + 
+                "; VNC: " + vnet.getName() + "; action: equal\n");
+        
+        VirtualNetworkModel current = _manager.getDatabase().lookupVirtualNetwork(vnet.getUuid(),
+                _manager.getCanonicalName(dbn), dbn.getTrafficType());
+
+        VirtualNetworkModel vnModel = new VirtualNetworkModel(dbn, vnet.getUuid(), 
+                _manager.getCanonicalName(dbn), dbn.getTrafficType());
+        vnModel.build(_manager.getModelController(), dbn);
+
+        if (_rw_mode) {
+            if (current != null) {
+                FloatingIpPoolModel fipPoolModel = current.getFipPoolModel();
+                if (fipPoolModel != null) {
+                   vnModel.setFipPoolModel(fipPoolModel);  
+                   fipPoolModel.addToVirtualNetwork(vnModel);
+                }
+                _manager.getDatabase().getVirtualNetworks().remove(current);
+            }
+            s_logger.debug("add model " + vnModel.getName());
+            _manager.getDatabase().getVirtualNetworks().add(vnModel);   
+            try {
+                if (!vnModel.verify(_manager.getModelController())) {
+                    vnModel.update(_manager.getModelController());
+                }
+            } catch (Exception ex) {
+                s_logger.warn("update virtual-network", ex);
+            }
+        } else {
+            //compare 
+            if (current != null && current.compare(_manager.getModelController(), vnModel) == false) {
+                syncLogMesg.append("VN# DB: " + _manager.getCanonicalName(dbn) + 
+                        "; VNC: " + vnet.getName() + "; attributes differ\n");
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*
+     *  Virtual Machine Synchronization methods
+     */
+
+    public boolean syncVirtualMachine() {
+        final ApiConnector api = _manager.getApiConnector();
+        try {
+            List<VMInstanceVO> vmDbList = _vmInstanceDao.listAll(); 
+            @SuppressWarnings("unchecked")
+            List<VirtualMachine> vncVmList = (List<VirtualMachine>) api.list(VirtualMachine.class, null);
+            s_logger.debug("sync VM:  CS size: " + vmDbList.size() + " VNC size: " + vncVmList.size());
+            return _dbSync.syncGeneric(VirtualMachine.class, vmDbList, vncVmList);
+        } catch (Exception ex) {
+            s_logger.warn("sync virtual-machines", ex);
+        }
+        return false;
+    }
+
+    public Comparator<?> dbComparatorVirtualMachine() {
+        Comparator<?> comparator = new Comparator<VMInstanceVO>() {
+            public int compare(VMInstanceVO u1, VMInstanceVO u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public Comparator<?> vncComparatorVirtualMachine() {
+        Comparator<?> comparator = new Comparator<VirtualMachine> () {
+            public int compare(VirtualMachine u1, VirtualMachine u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public void createVirtualMachine(VMInstanceVO dbVm, StringBuffer syncLogMesg) throws IOException {
+        syncLogMesg.append("VM# DB: " + dbVm.getInstanceName() + "/" + dbVm.getUuid() + "; VNC: none; action: create\n");
+        VirtualMachineModel vmModel = new VirtualMachineModel(dbVm, dbVm.getUuid());
+        vmModel.build(_manager.getModelController(), dbVm);
+        buildNicResources(vmModel, dbVm, syncLogMesg);
+
+        if (_rw_mode) {
+            try {
+                vmModel.update(_manager.getModelController());
+            } catch (InternalErrorException ex) {
+                s_logger.warn("create virtual-machine", ex);
+                return;
+            }
+            _manager.getDatabase().getVirtualMachines().add(vmModel);
+            syncLogMesg.append("VM# VNC: " + dbVm.getUuid() + " created\n");
+        }
+    }
+
+    private void deleteVirtualMachineInterfaces(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
+        if (list == null) {
+            return;
+        }
+        final ApiConnector api = _manager.getApiConnector();
+        for (ObjectReference<ApiPropertyBase> vmiRef: list) {
+            VirtualMachineInterface vmi = (VirtualMachineInterface) api.findById(VirtualMachineInterface.class, vmiRef.getUuid());
+            deleteInstanceIps(vmi.getInstanceIpBackRefs(), syncLogMesg);
+            deleteFloatingIps(vmi.getFloatingIpBackRefs(), syncLogMesg);
+            api.delete(VirtualMachineInterface.class, vmiRef.getUuid());
+            syncLogMesg.append("VNC vmi: " + vmi.getUuid() + " deleted\n");
+        }        
+    }
+
+    private void deleteInstanceIps(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
+        if (list == null) {
+            return;
+        }
+        final ApiConnector api = _manager.getApiConnector();
+        for (ObjectReference<ApiPropertyBase> instIp: list) {
+            api.delete(InstanceIp.class, instIp.getUuid());
+            syncLogMesg.append("VNC instance ip: " + instIp.getUuid() + " deleted\n");
+        }
+        
+    }
+    
+    private void deleteFloatingIps(List<ObjectReference<ApiPropertyBase>> list, StringBuffer syncLogMesg) throws IOException {
+        if (list == null) {
+            return;
+        }
+        final ApiConnector api = _manager.getApiConnector();
+        for (ObjectReference<?> floatingIp: list) {
+            api.delete(FloatingIp.class, floatingIp.getUuid());
+            syncLogMesg.append("VNC instance ip: " + floatingIp.getUuid() + " deleted\n");
+        }
+    }
+
+    public void deleteVirtualMachine(VirtualMachine vncVm, StringBuffer syncLogMesg) {
+        final ApiConnector api = _manager.getApiConnector();
+        syncLogMesg.append("VM# DB:none; VNC: " + vncVm.getName() + "/" + vncVm.getUuid() + "; action: delete\n");
+        if (!_rw_mode) {
+            return;
+        }
+        try {
+            if (!api.read(vncVm)) {
+                 return;
+            }
+            deleteVirtualMachineInterfaces(vncVm.getVirtualMachineInterfaces(), syncLogMesg);
+            api.delete(VirtualMachine.class, vncVm.getUuid());
+        } catch (IOException ex) {
+            s_logger.warn("delete virtual-machine", ex);
+            return;
+        }
+        syncLogMesg.append("VM# VNC: " + vncVm.getName() + " deleted\n");
+    }
+
+    public Integer compareVirtualMachine(VMInstanceVO dbVm, VirtualMachine vncVm, StringBuffer syncLogMesg) {
+        String dbVmId = dbVm.getUuid();
+        String vncVmId = vncVm.getUuid();
+        return dbVmId.compareTo(vncVmId);
+    }    
+
+    public boolean filterVirtualMachine(VirtualMachine vncVm, StringBuffer syncLogMesg) {
+        return false;
+    }
+
+    private void buildNicResources(VirtualMachineModel vmModel, VMInstanceVO dbVm, StringBuffer syncLogMsg)
+            throws IOException {
+        List<NicVO> nics = _nicDao.listByVmId(dbVm.getId());
+        for (NicVO nic : nics) {
+            VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+            if (vmiModel == null) {
+                vmiModel = new VMInterfaceModel(nic.getUuid());
+                NetworkVO network = _networksDao.findById(nic.getNetworkId());
+                VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(
+                        network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+                if (vnModel == null)  {
+                    s_logger.warn("Unable to locate virtual-network for network id " + network.getId());
+                    continue;
+                }
+                vmiModel.addToVirtualMachine(vmModel);
+                vmiModel.addToVirtualNetwork(vnModel);
+            }
+            vmiModel.build(_manager.getModelController(), dbVm, nic);            
+        }        
+    }
+
+    public Boolean equalVirtualMachine(VMInstanceVO dbVm, VirtualMachine vncVm, StringBuffer syncLogMsg) {
+
+        syncLogMsg.append("VM# DB: " + dbVm.getInstanceName() + "/" + dbVm.getUuid() + 
+                "; VNC: " + vncVm.getUuid() + "; action: equal; DB VM State: " + dbVm.getState() + "\n");
+
+        VirtualMachineModel vmModel = new VirtualMachineModel(dbVm, dbVm.getUuid());
+        vmModel.build(_manager.getModelController(), dbVm);
+
+        if (vmModel.isActive()) {
+            try {
+                buildNicResources(vmModel, dbVm, syncLogMsg);
+            } catch (IOException ex) {
+                s_logger.warn("build nic information for " + dbVm.getInstanceName(), ex);
+            }
+        }
+
+        VirtualMachineModel current = _manager.getDatabase().lookupVirtualMachine(vncVm.getUuid());
+        if (_rw_mode) {
+            if (current != null) {
+                _manager.getDatabase().getVirtualMachines().remove(current);
+            }
+            _manager.getDatabase().getVirtualMachines().add(vmModel);   
+            try {
+                vmModel.update(_manager.getModelController());
+            } catch (Exception ex) {
+                s_logger.warn("update virtual-machine", ex);
+            }
+        } else {
+            //compare 
+            if (current != null && current.compare(_manager.getModelController(), vmModel) == false) {
+                syncLogMsg.append("VM # DB: " + dbVm.getInstanceName() + 
+                        "; VNC: " + vncVm.getName() + "; attributes differ\n");
+                return false;
+            }
+        }
+        return true;
+    }
+    
+     
+    public boolean syncFloatingIp() throws Exception {
+        
+        List<IPAddressVO> ipList = _manager.findJuniperManagedPublicIps();
+        List<FloatingIp> vncList = _manager.getFloatingIps();  
+        if (ipList == null) {
+            ipList = new ArrayList<IPAddressVO>();
+        }        
+        if (vncList == null) {
+            vncList = new ArrayList<FloatingIp>();
+        }
+        
+        boolean status = false;
+        try {
+            status =  _dbSync.syncGeneric(FloatingIp.class, ipList, vncList);
+        } catch (Exception ex) {
+            s_logger.warn("sync floating-ips", ex);
+            throw ex;
+        }        
+        return status;
+    }
+    
+    public Comparator<?> dbComparatorFloatingIp() {
+        Comparator<?> comparator = new Comparator<IpAddress>() {
+            public int compare(IpAddress u1, IpAddress u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+
+    public Comparator<?> vncComparatorFloatingIp() {
+        Comparator<?> comparator = new Comparator<FloatingIp> () {
+            public int compare(FloatingIp u1, FloatingIp u2) {
+                return u1.getUuid().compareTo(u2.getUuid());
+            }
+        };
+        return comparator;
+    }
+    
+    public Integer compareFloatingIp(IpAddress db, FloatingIp vnc, StringBuffer syncLogMesg) {
+        String dbId = db.getUuid();
+        String vncId = vnc.getUuid();
+        return dbId.compareTo(vncId);
+    } 
+    
+    public void createFloatingIp(IPAddressVO dbIp, StringBuffer syncLogMesg) throws Exception {
+
+        if (dbIp.getState() == IpAddress.State.Releasing) {
+            /* Don't need to push releasing ip */
+            syncLogMesg.append("fip# DB: " + dbIp.getUuid() + ", state releasing, don't create in vnc\n");
+            return;
+        }
+        syncLogMesg.append("fip# DB: " + dbIp.getAddress().addr() + "; VNC: none; action: create\n");
+        if (!_manager.createFloatingIp(PublicIp.createFromAddrAndVlan(dbIp, _vlanDao.findById(dbIp.getVlanId())))) {
+            syncLogMesg.append("fip# VNC: " + dbIp.getAddress().addr() + " unable to create\n");
+            return ;
+        }
+        syncLogMesg.append("fip# VNC: " + dbIp.getUuid() + " created\n");
+    }
+    
+    public void deleteFloatingIp(FloatingIp vnc, StringBuffer syncLogMesg) throws IOException {
+        final ApiConnector api = _manager.getApiConnector();
+        syncLogMesg.append("fip# DB: none; VNC: " + vnc.getAddress() + "(" + 
+                vnc.getUuid() + "); action: delete\n");
+        api.delete(vnc);
+        syncLogMesg.append("fip# VNC: " + vnc.getUuid() + " deleted\n");
+    }
+    
+    public Boolean equalFloatingIp(IPAddressVO db, FloatingIp vnc, StringBuffer syncLogMsg) 
+            throws IOException {
+
+        syncLogMsg.append("fip# DB: " + db.getAddress().addr() + 
+                "; VNC: " + vnc.getAddress() + "; action: equal" + "\n");
+
+        VirtualNetworkModel vnModel = _manager.lookupPublicNetworkModel();
+        assert vnModel != null : "public network vn model is null";
+
+        FloatingIpPoolModel fipPoolModel = vnModel.getFipPoolModel();
+        if (fipPoolModel == null) {
+            fipPoolModel = new FloatingIpPoolModel();
+            fipPoolModel.addToVirtualNetwork(vnModel);
+            fipPoolModel.build(_manager.getModelController());
+            try {
+                fipPoolModel.update(_manager.getModelController());
+                vnModel.setFipPoolModel(fipPoolModel);
+            } catch (Exception ex) {
+                s_logger.warn("floating-ip-pool create: ", ex);
+                return false;
+            }
+        }
+
+        FloatingIpModel current = fipPoolModel.getFloatingIpModel(db.getUuid());
+        if (current == null) {
+            s_logger.debug("add model " + db.getAddress().addr());
+            FloatingIpModel fipModel = new FloatingIpModel(db.getUuid());
+            fipModel.addToFloatingIpPool(fipPoolModel);
+            fipModel.build(_manager.getModelController(),  
+                    PublicIp.createFromAddrAndVlan(db, _vlanDao.findById(db.getVlanId())));
+            try {
+                fipModel.update(_manager.getModelController());
+            } catch (Exception ex) {
+                s_logger.warn("floating-ip create: ", ex);
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    public Integer compareServiceInstance(ServiceInstanceModel siModel, ServiceInstance siObj, StringBuffer logMsg) {
+        String fqn = StringUtils.join(siObj.getQualifiedName(), ':');
+        return siModel.getQualifiedName().compareTo(fqn);
+    }
+    
+    /**
+     * createServiceInstance
+     * 
+     * This method should never be invoked since the model objects have been installed already when sync is called.
+     * @param siModel
+     * @param logMsg
+     */
+    public void createServiceInstance(ServiceInstanceModel siModel, StringBuffer logMsg) {
+        assert false;
+    }
+    
+    public void deleteServiceInstance(ServiceInstance siObj, StringBuffer logMsg) {
+        final ApiConnector api = _manager.getApiConnector();
+        s_logger.debug("delete " + siObj.getQualifiedName());
+        if (!_rw_mode) {
+            return;
+        }
+        try {
+            api.delete(siObj);
+        } catch (IOException ex) {
+            s_logger.warn("service-instance delete", ex);
+        }
+    }
+
+    /**
+     * equalServiceInstance
+     * 
+     * @param siModel
+     * @param siObj
+     * @param logMsg
+     */
+    public void equalServiceInstance(ServiceInstanceModel siModel, ServiceInstance siObj, StringBuffer logMsg) {
+        s_logger.debug("equal " + siModel.getQualifiedName());
+    }
+    
+    static class ServiceInstanceComparator implements Comparator<ServiceInstance> {
+        @Override
+        public int compare(ServiceInstance obj1, ServiceInstance obj2) {
+            String name1 = StringUtils.join(obj1.getQualifiedName(), ':');
+            String name2 = StringUtils.join(obj2.getQualifiedName(), ':');
+            return name1.compareTo(name2);
+        }
+        
+    }
+    /**
+     * The service-instance model list is build as a result of synchronizing virtual-machines.
+     * @return
+     */
+    public boolean syncServiceInstance() {
+        final ApiConnector api = _manager.getApiConnector();
+        boolean inSync;
+        try {
+            @SuppressWarnings("unchecked")
+            List<ServiceInstance> siList = (List<ServiceInstance>) api.list(ServiceInstance.class, null);
+            java.util.Collections.sort(siList, new ServiceInstanceComparator());
+            DBSyncGeneric.SyncStats stats = new DBSyncGeneric.SyncStats();
+            _dbSync.syncCollections(ServiceInstance.class, _manager.getDatabase().getServiceInstances(), siList,
+                    _rw_mode, stats);
+            inSync = stats.create == 0 && stats.delete == 0;
+        } catch (Exception ex) {
+            s_logger.warn("synchronize service-instances", ex);
+            return false;
+        }
+        return inSync;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
new file mode 100644
index 0000000..7fb94d8
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandler.java
@@ -0,0 +1,22 @@
+// 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.network.contrail.management;
+
+public interface ServerEventHandler {
+    public void subscribe();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
new file mode 100644
index 0000000..455e601
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerEventHandlerImpl.java
@@ -0,0 +1,251 @@
+// 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.network.contrail.management;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.event.EventTypes;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.projects.ProjectVO;
+import com.cloud.projects.dao.ProjectDao;
+
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
+import org.apache.cloudstack.framework.messagebus.MessageHandler;
+
+/*
+ * When an Object is created/deleted in cloudstack DB, it has to be reflected in VNC.
+ * This class handles create, delete and update events of cloudstack db objects.
+ * 
+ * - subscribe for interested events 
+ * - create events will have db id of the object and hence db object and its parameters can be retrieved
+ * - delete events will have db id but the object no longer exists in db and hence complete class needs to be synchronized 
+ * 
+ */
+@Component
+public class ServerEventHandlerImpl implements ServerEventHandler {
+    @Inject NetworkOfferingDao _networkOfferingDao;
+    @Inject DomainDao _domainDao;
+    @Inject ProjectDao _projectDao;
+    @Inject private MessageBus _messageBus;
+    @Inject ServerDBSync _dbSync;
+    @Inject ContrailManager _manager;
+    private HashMap<String, Method> _methodMap;
+    private HashMap<String, Class<?>> _classMap;
+
+    private static final Logger s_logger = Logger.getLogger(MessageHandler.class);
+ 
+    ServerEventHandlerImpl() {
+        setMethodMap();
+        setClassMap();
+    }
+
+    protected void finalize () {
+
+    }
+    
+    private void setMethodMap() {
+        _methodMap = new HashMap<String, Method>();
+        Method methods[] = this.getClass().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            _methodMap.put(methods[i].getName(),  methods[i]); 
+        }
+    }
+    
+    private void setClassMap() {
+        _classMap = new HashMap<String, Class<?>>();        
+        _classMap.put("Domain", net.juniper.contrail.api.types.Domain.class);
+        _classMap.put("Project", net.juniper.contrail.api.types.Project.class);
+    }
+    
+    @MessageHandler(topic=".*")
+    public void defaultMessageHandler(String subject, String topic, Object args) {
+        s_logger.info("DB Event Received - topic: " + topic + "; subject: " + subject);
+        
+        if (subject.equals("VLAN.IP.RANGE.CREATE")) {
+            _manager.createPublicNetworks();
+            return;
+        } else if (subject.equals("VLAN.IP.RANGE.DELETE")) {
+            // TODO
+            return;
+        }
+
+        org.apache.cloudstack.framework.events.Event event = (org.apache.cloudstack.framework.events.Event)args;
+        
+        /* Method name should be on<ClassName><Operation> for example: onDomainCreate */
+        Method method = null;
+       
+        try {
+            /* Only create event needs special implementation */
+            if (event.getEventType().contains("CREATE")) {
+                String methodName = "on" + event.getResourceType() + "Create";
+                method = _methodMap.get(methodName);
+                if (method == null) {
+                    defaultCreateHandler(subject, topic, event);
+                } else {
+                    method.invoke(this, subject, topic, event);
+                }
+            } else if (event.getEventType().contains("DELETE")) {
+                defaultDeleteHandler(subject, topic, event);
+            } else {
+                defaultHandler(subject, topic, event);
+            }
+        } catch (Exception e) {
+            s_logger.debug(e);
+        }
+    }
+    
+    /* Default create handler */
+    void defaultCreateHandler(String subject, String topic, org.apache.cloudstack.framework.events.Event event ) {
+        
+        s_logger.debug("Default handler is invoked for subject: " + subject + "; topic: " + topic);
+        s_logger.debug("description: " + event.getDescription());
+        s_logger.debug("category: " + event.getEventCategory());
+        s_logger.debug("type: " + event.getResourceType());
+        s_logger.debug("event-type: " + event.getEventType());
+        
+        Class<?> cls = _classMap.get(event.getResourceType());
+           
+        if ( cls != null ) {
+            _dbSync.syncClass(cls);
+        }
+        
+        return;
+    }
+    
+    /* Default handler */
+    void defaultDeleteHandler(String subject, String topic, org.apache.cloudstack.framework.events.Event event ) {
+        
+        s_logger.debug("Default handler is invoked for subject: " + subject + "; topic: " + topic);
+
+        s_logger.debug("description: " + event.getDescription());
+        s_logger.debug("category: " + event.getEventCategory());
+        s_logger.debug("type: " + event.getResourceType());
+        s_logger.debug("event-type: " + event.getEventType());
+        Class<?> cls = _classMap.get(event.getResourceType());
+        if ( cls != null ) {
+            _dbSync.syncClass(cls);
+        }         
+        return;
+    }
+    
+    /* Default handler */
+    void defaultHandler(String subject, String topic, org.apache.cloudstack.framework.events.Event event ) {
+        
+        s_logger.debug("Default handler is invoked for subject: " + subject + "; topic: " + topic);
+
+        s_logger.debug("description: " + event.getDescription());
+        s_logger.debug("category: " + event.getEventCategory());
+        s_logger.debug("type: " + event.getResourceType());
+        s_logger.debug("event-type: " + event.getEventType());
+        Class<?> cls = _classMap.get(event.getResourceType());
+        if ( cls != null ) {
+            _dbSync.syncClass(cls);
+        }         
+        return;
+    }
+    
+    /* Description string contains substring of format "resourceType Id: <int>" for example: "Project id: 35"
+     * 
+     * example: 
+     *  description: {"details":"Successfully completed deleting project. Project Id: 39","status":"Completed","event":"PROJECT.DELETE","account":"3afca502-d83c-11e2-b748-52540076b7ca","user":"3b111406-d83c-11e2-b748-52540076b7ca"}
+     *  
+     * If the description string format is changed, this code has to be modified
+     */
+    private long parseForId(String resourceType, String description) {
+        String typeStr = resourceType + " Id:";
+        int idIdx = description.indexOf(typeStr) + typeStr.length();
+        String idStr = description.substring(idIdx, description.indexOf('"', idIdx));
+        long id = 0;
+        try {
+            id = Long.parseLong(idStr.trim());            
+        } catch (Exception e) {
+            s_logger.debug("Unable to parse id string<" + idStr.trim() + "> for long value, ignored");
+        }        
+        return id;
+    }
+    
+    
+    public void onDomainCreate(String subject, String topic, org.apache.cloudstack.framework.events.Event event) {
+        s_logger.info("onDomainCreate; topic: " + topic + "; subject: " + subject);
+        try {
+            long id = parseForId(event.getResourceType(), event.getDescription());
+            if (id != 0) {
+                DomainVO domain = _domainDao.findById(id);
+                if (domain != null) {
+                    s_logger.info("createDomain for name: " + domain.getName() + "; uuid: " + domain.getUuid());
+                    StringBuffer logMesg = new StringBuffer();
+                    _dbSync.createDomain(domain, logMesg);
+                } else {
+                    /* could not find db record, resync complete class */
+                    _dbSync.syncClass(net.juniper.contrail.api.types.Domain.class);
+                } 
+            } else {
+                /* Unknown id, resync complete class */
+                _dbSync.syncClass(net.juniper.contrail.api.types.Domain.class);
+            }
+        } catch (Exception e) {
+            s_logger.debug(e);  
+        }
+    }
+             
+    public void onProjectCreate(String subject, String topic, org.apache.cloudstack.framework.events.Event event) {
+        s_logger.info("onProjectCreate; topic: " + topic + "; subject: " + subject);
+        try {
+            long id = parseForId(event.getResourceType(), event.getDescription());
+            if (id != 0) {
+                ProjectVO project = _projectDao.findById(id);
+                if (project != null) {
+                    s_logger.info("createProject for name: " + project.getName() + "; uuid: " + project.getUuid());
+                    StringBuffer logMesg = new StringBuffer();
+                    _dbSync.createProject(project, logMesg);
+                } else {
+                    /* could not find db record, resync complete class */
+                    _dbSync.syncClass(net.juniper.contrail.api.types.Project.class);        
+                } 
+            } else {
+                /* Unknown id, resync complete class */
+                _dbSync.syncClass(net.juniper.contrail.api.types.Project.class);
+            }
+        } catch (Exception e) {
+            s_logger.info(e);
+        }
+        
+    }
+    
+       
+    @Override
+    public void subscribe() {
+        /* subscribe to DB events */
+        _messageBus.subscribe(EventTypes.EVENT_PROJECT_CREATE, MessageDispatcher.getDispatcher(this));
+        _messageBus.subscribe(EventTypes.EVENT_PROJECT_DELETE, MessageDispatcher.getDispatcher(this));
+        _messageBus.subscribe(EventTypes.EVENT_DOMAIN_CREATE, MessageDispatcher.getDispatcher(this));
+        _messageBus.subscribe(EventTypes.EVENT_DOMAIN_DELETE, MessageDispatcher.getDispatcher(this));
+        _messageBus.subscribe(EventTypes.EVENT_VLAN_IP_RANGE_CREATE, MessageDispatcher.getDispatcher(this));
+        _messageBus.subscribe(EventTypes.EVENT_VLAN_IP_RANGE_DELETE, MessageDispatcher.getDispatcher(this));
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java
new file mode 100644
index 0000000..dcc643c
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManager.java
@@ -0,0 +1,40 @@
+// 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.network.contrail.management;
+
+import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.network.Network;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+public interface ServiceManager {
+    /**
+     * Create a virtual machine that executes a network service appliance (e.g. vSRX)
+     * @param left Left or inside network (e.g. project network).
+     * @param right Right or outside network (e.g. public network).
+     * @return
+     */
+    public ServiceVirtualMachine createServiceInstance(DataCenter zone, Account owner, VirtualMachineTemplate template,
+            ServiceOffering serviceOffering, String name, Network left, Network right);
+
+    public void startServiceInstance(long instanceId);
+    public ServiceInstanceResponse createServiceInstanceResponse(long instanceId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
new file mode 100644
index 0000000..47fc99e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceManagerImpl.java
@@ -0,0 +1,249 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiDBUtils;
+import com.cloud.dc.DataCenter;
+import com.cloud.deploy.DataCenterDeployment;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.projects.Project;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+import com.cloud.user.AccountService;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.dao.UserVmDao;
+import com.google.gson.Gson;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse;
+import org.apache.cloudstack.network.contrail.model.ServiceInstanceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.VirtualNetwork;
+
+@Local(value =  {ServiceManager.class})
+public class ServiceManagerImpl implements ServiceManager {
+    private static final Logger s_logger = Logger.getLogger(ServiceManager.class);
+
+    @Inject UserDao  _userDao;
+    @Inject UserVmDao _vmDao;
+    @Inject VirtualMachineManager _vmManager;
+    @Inject NetworkModel _networkModel;
+    @Inject AccountService _accountService;
+    @Inject ContrailManager _manager;
+    
+    /**
+     * In the case of service instance the master object is in the contrail API server. This object stores the
+     * service instance parameters in the database.
+     * 
+     * @param owner     Used to determine the project.
+     * @param name      Service instance name (user specified).
+     * @param template  Image to execute.
+     * @param serviceOffering 
+     * @param left      Inside network.
+     * @param right     Outside network.
+     * @return
+     */
+        
+
+    /**
+     * create a new ServiceVM object.
+     * @return
+     */
+    @ActionEvent(eventType = EventTypes.EVENT_VM_CREATE, eventDescription="createServiceInstance", create = true)
+    private ServiceVirtualMachine createServiceVM(DataCenter zone, Account owner, VirtualMachineTemplate template,
+            ServiceOffering serviceOffering, String name, ServiceInstance siObj, Network left, Network right) {
+        long id = _vmDao.getNextInSequence(Long.class, "id");
+        
+        DataCenterDeployment plan = new DataCenterDeployment(zone.getId());
+        
+        LinkedHashMap<NetworkVO, NicProfile> networks = new LinkedHashMap<NetworkVO, NicProfile>();
+        NetworkVO linklocal = (NetworkVO) _networkModel.getSystemNetworkByZoneAndTrafficType(zone.getId(),
+                TrafficType.Management);
+        networks.put(linklocal, null);
+        networks.put((NetworkVO) left, null);
+        networks.put((NetworkVO) right, null);
+        
+        String instanceName = VirtualMachineName.getVmName(id, owner.getId(), "SRV");
+        ServiceVirtualMachine svm = new ServiceVirtualMachine(id, instanceName, name, template.getId(),
+                serviceOffering.getId(), template.getHypervisorType(), template.getGuestOSId(), zone.getId(), owner.getDomainId(),
+                owner.getAccountId(), false);
+  
+        // database synchronization code must be able to distinguish service instance VMs.
+        Map<String, String> kvmap = new HashMap<String, String>();
+        kvmap.put("service-instance", siObj.getUuid());
+        Gson json = new Gson();
+        String userData = json.toJson(kvmap);
+        svm.setUserData(userData);
+
+        try {
+            _vmManager.allocate(instanceName, template, serviceOffering, networks,
+                                plan, template.getHypervisorType());
+        } catch (InsufficientCapacityException ex) {
+            throw new CloudRuntimeException("Insufficient capacity", ex);
+        }
+        CallContext.current().setEventDetails("Vm Id: " + svm.getId());
+        return svm;
+    }
+    
+    @Override
+    public ServiceVirtualMachine createServiceInstance(DataCenter zone, Account owner, VirtualMachineTemplate template,
+            ServiceOffering serviceOffering, String name, Network left, Network right) {
+        s_logger.debug("createServiceInstance by " + owner.getAccountName());
+        // TODO: permission model.
+        // service instances need to be able to access the public network.
+        if (left.getTrafficType() == TrafficType.Guest) {
+            _networkModel.checkNetworkPermissions(owner, left);
+        }
+        if (right.getTrafficType() == TrafficType.Guest) {
+            _networkModel.checkNetworkPermissions(owner, right);
+        }
+        
+        final ApiConnector api = _manager.getApiConnector();
+        final VirtualNetwork netLeft;
+        try {
+            netLeft = (VirtualNetwork) api.findById(VirtualNetwork.class, left.getUuid());
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to read virtual-network object", ex);
+        }
+        final VirtualNetwork netRight;
+        try {
+            netRight = (VirtualNetwork) api.findById(VirtualNetwork.class, right.getUuid());
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to read virtual-network object", ex);
+        }
+
+        net.juniper.contrail.api.types.Project project;
+        try {
+            project = _manager.getVncProject(owner.getDomainId(), owner.getAccountId());
+        } catch (IOException ex) {
+            s_logger.warn("read project", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        
+        try {
+            final String srvid = api.findByName(ServiceInstance.class, project, name);
+            if (srvid != null) {
+                throw new InvalidParameterValueException("service-instance " + name + " already exists uuid=" + srvid);
+            }
+        } catch (IOException ex) {
+            s_logger.warn("service-instance lookup", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        
+        // 1. Create service-instance.
+        ServiceInstanceModel serviceModel = new ServiceInstanceModel(project, name, template, serviceOffering,
+                netLeft, netRight);
+
+        try {
+            serviceModel.update(_manager.getModelController());
+        } catch (Exception ex) {
+            s_logger.warn("service-instance update", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        
+        s_logger.debug("service-instance object created");
+        
+        ServiceInstance siObj;
+        try {
+            _manager.getDatabase().getServiceInstances().add(serviceModel);
+            siObj = serviceModel.getServiceInstance();
+        } catch (Exception ex){
+            s_logger.warn("DB add", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        
+        // 2. Create one virtual-machine.
+        String svmName = name.replace(" ", "_") + "-1";
+        ServiceVirtualMachine svm = createServiceVM(zone, owner, template, serviceOffering, svmName, siObj, left, right);
+ 
+        s_logger.debug("created VMInstance " + svm.getUuid());
+
+        // 3. Create the virtual-machine model and push the update.
+        VirtualMachineModel instanceModel = new VirtualMachineModel(svm, svm.getUuid());
+        _manager.getDatabase().getVirtualMachines().add(instanceModel);
+        try {
+            instanceModel.setServiceInstance(_manager.getModelController(), svm, serviceModel);
+            instanceModel.update(_manager.getModelController());
+        } catch (Exception ex) {
+            s_logger.warn("service virtual-machine update", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        
+        return svm;
+    }
+
+    @Override
+    public void startServiceInstance(long instanceId) {
+        s_logger.debug("start service instance " + instanceId);
+
+        UserVmVO vm = _vmDao.findById(instanceId);
+        _vmManager.start(vm.getUuid(), null);
+    }
+
+    @Override
+    public ServiceInstanceResponse createServiceInstanceResponse(long instanceId) {
+        s_logger.debug("ServiceInstance response for id: " + instanceId);
+        UserVmVO vm = _vmDao.findById(instanceId);
+        ServiceInstanceResponse response = new ServiceInstanceResponse();
+        response.setId(vm.getUuid());
+        Account owner = _accountService.getAccount(vm.getAccountId());
+        if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
+            Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(owner.getAccountId());
+            response.setProjectId(project.getUuid());
+            response.setProjectName(project.getName());
+        } else {
+            response.setAccountName(owner.getAccountName());
+        }
+        return response;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
new file mode 100644
index 0000000..7418792
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServiceVirtualMachine.java
@@ -0,0 +1,30 @@
+// 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.network.contrail.management;
+
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.vm.UserVmVO;
+
+public class ServiceVirtualMachine extends UserVmVO {
+    public ServiceVirtualMachine(long id, String instanceName, String name, long templateId, long serviceOfferingId,
+            HypervisorType hypervisorType, long guestOSId, long dataCenterId, long domainId, long accountId,
+            boolean haEnabled) {
+        super(id, instanceName, name, templateId, hypervisorType, guestOSId, false, false, domainId, accountId,
+              serviceOfferingId, null, name, null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
new file mode 100644
index 0000000..a640b1e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpModel.java
@@ -0,0 +1,213 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+
+import net.juniper.contrail.api.types.FloatingIp;
+import net.juniper.contrail.api.ApiConnector;
+
+public class FloatingIpModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(FloatingIpModel.class);
+
+    private String _uuid;
+    private long _id;
+    private String _name;
+    private String _addr;
+    private boolean _initialized;
+
+    /*
+     * cached API server objects
+     */
+    private FloatingIp _fip;
+    private FloatingIpPoolModel _fipPoolModel;
+
+    public FloatingIpModel(String uuid) {
+       _uuid = uuid;
+    }
+
+    public void addToFloatingIpPool(FloatingIpPoolModel fipPoolModel) {
+        _fipPoolModel = fipPoolModel;
+        if (fipPoolModel != null) {
+            fipPoolModel.addSuccessor(this);
+        }
+    }
+
+    public void addToVMInterface(VMInterfaceModel vmiModel) {
+        if (vmiModel != null) {
+            vmiModel.addSuccessor(this);
+        }
+    }
+
+    /*
+     * Resynchronize internal state from the cloudstack DB object.
+     */
+    public void build(ModelController controller, PublicIpAddress ip) {
+        setProperties(controller, ip);
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        FloatingIpModel other;
+        try {
+            other = (FloatingIpModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return FloatingIpModel.class.getName().compareTo(clsname);
+        }
+
+        return _uuid.compareTo(other._uuid);
+    }
+
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+
+        try {
+            api.delete(FloatingIp.class, _uuid);
+        } catch (IOException ex) {
+            s_logger.warn("floating ip delete", ex);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public String getUuid() {
+        return _uuid;
+    }
+
+
+    public FloatingIp getFloatingIp() {
+        return _fip;
+    }
+
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller, PublicIpAddress ip) {
+        _uuid = ip.getUuid();
+        _name = Long.toString(ip.getId());
+        _addr = ip.getAddress().addr();
+        _id = ip.getId();
+        assert _fipPoolModel != null : "floating ip uuid is not set";
+        _initialized = true;
+    }
+
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+
+        assert _initialized;
+
+        ApiConnector api = controller.getApiAccessor();
+        ContrailManager manager = controller.getManager();
+        FloatingIp fip = _fip;
+
+        if (_fip == null) {
+            _fip = fip = (FloatingIp) controller.getApiAccessor().findById(FloatingIp.class, _uuid);
+            if (fip == null) {
+                fip = new FloatingIp();
+                fip.setUuid(_uuid);
+                fip.setAddress(_addr);
+                fip.setName(_name);
+                fip.setParent(_fipPoolModel.getFloatingIpPool());
+            }
+        }
+
+        IPAddressVO ipAddrVO = controller.getIPAddressDao().findById(_id);
+        assert ipAddrVO != null : "can not find address object in db";
+        Long vmId = ipAddrVO.getAssociatedWithVmId();
+        Long networkId = ipAddrVO.getAssociatedWithNetworkId();
+        if (vmId == null || networkId == null) {
+            s_logger.debug("Floating ip is not yet associated to either vm or network");
+            return;
+        }
+        NicVO nic = controller.getNicDao().findByNtwkIdAndInstanceId(networkId, vmId);
+        assert nic != null : "can not find nic for the given network and vm in db";
+
+        VMInstanceVO vm = controller.getVmDao().findById(vmId);
+        assert vm != null : "can not find vm in db";
+
+        VirtualMachineModel vmModel = manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        assert vmModel != null : "can not find vm model";
+
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+        assert vmiModel != null && vmiModel.getVMInterface() != null : "can not find virtual machine interface";
+
+        fip.setVirtualMachineInterface(vmiModel.getVMInterface());
+
+        if (_fip == null) {
+            try {
+                api.create(fip);
+            } catch (Exception ex) {
+                s_logger.debug("floating ip create", ex);
+                throw new CloudRuntimeException("Failed to create floating ip", ex);
+            }
+            _fip = fip;
+        } else {
+            try {
+                api.update(fip);
+            } catch (IOException ex) {
+                s_logger.warn("floating ip update", ex);
+                throw new CloudRuntimeException("Unable to update floating ip object", ex);
+            }            
+        }
+
+        addToVMInterface(vmiModel);
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        assert _initialized : "initialized is false";
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject o) {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
new file mode 100644
index 0000000..1205c87
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/FloatingIpPoolModel.java
@@ -0,0 +1,170 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+import java.util.TreeSet;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import net.juniper.contrail.api.types.FloatingIpPool;
+import net.juniper.contrail.api.ApiConnector;
+
+public class FloatingIpPoolModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(FloatingIpPoolModel.class);
+
+    private String _name;
+
+    /*
+     * cached API server objects
+     */
+    private FloatingIpPool _fipPool;
+    private VirtualNetworkModel _vnModel;
+
+    public FloatingIpPoolModel() {
+
+    }
+
+    public void addToVirtualNetwork(VirtualNetworkModel vnModel) {
+        _vnModel = vnModel;
+        if (vnModel != null) {
+            vnModel.addSuccessor(this);
+        }
+    }
+
+    public FloatingIpModel getFloatingIpModel(String uuid) {
+        TreeSet<ModelObject> tree = successors();
+        FloatingIpModel fipKey = new FloatingIpModel(uuid);
+        FloatingIpModel current = (FloatingIpModel) tree.ceiling(fipKey);
+        if (current != null && current.getUuid().equals(uuid)) {
+            return current;
+        }
+        return null;
+    }
+
+    /*
+     * Resynchronize internal state from the cloudstack DB object.
+     */
+    public void build(ModelController controller) {
+        setProperties(controller);
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        /* there can be only one instance */
+        return 0;
+    }
+
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+        try {
+            if (_fipPool != null) {
+                api.delete(_fipPool);
+            }
+            _fipPool = null;
+        } catch (IOException ex) {
+            s_logger.warn("floating ip pool delete", ex);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public FloatingIpPool getFloatingIpPool() {
+        return _fipPool;
+    }
+
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller) {
+        _name = "PublicIpPool";
+        assert _vnModel != null : "vn nodel is not initialized";
+    }
+
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+
+        assert _vnModel != null : "vn model is not set";
+
+        ApiConnector api = controller.getApiAccessor();
+        ContrailManager manager = controller.getManager();
+        FloatingIpPool fipPool = _fipPool;
+
+        if (fipPool == null) {
+            String fipPoolName = manager.getDefaultPublicNetworkFQN() + ":PublicIpPool";
+            _fipPool = fipPool = (FloatingIpPool) controller.getApiAccessor().findByFQN(FloatingIpPool.class, fipPoolName);
+            if (fipPool == null) {
+                fipPool = new FloatingIpPool();
+                fipPool.setName(_name);
+                fipPool.setParent(_vnModel.getVirtualNetwork());
+            }
+        }
+
+        if (_fipPool == null) {
+            try {
+                api.create(fipPool);
+            } catch (Exception ex) {
+                s_logger.debug("floating ip pool create", ex);
+                throw new CloudRuntimeException("Failed to create floating ip pool", ex);
+            }
+            _fipPool = fipPool;
+        } else {
+            try {
+                api.update(fipPool);
+            } catch (IOException ex) {
+                s_logger.warn("floating ip pool update", ex);
+                throw new CloudRuntimeException("Unable to update floating ip ppol object", ex);
+            }            
+        }
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        assert _vnModel != null : "vn model is not set";
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject o) {
+        return true;
+    }
+}


[3/6] OpenContrail network plugin

Posted by hu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
new file mode 100644
index 0000000..7588ba7
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/InstanceIpModel.java
@@ -0,0 +1,174 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.InstanceIp;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.ApiConnector;
+
+import com.cloud.exception.InternalErrorException;
+
+public class InstanceIpModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(InstanceIpModel.class);
+    
+    private String _name;
+    private String _uuid;
+    
+    private String _ipAddress;
+    
+    private VMInterfaceModel _vmiModel;
+    
+    public InstanceIpModel(String vmName, int deviceId) {
+        _name = vmName + '-' + deviceId;
+    }
+    
+    public void addToVMInterface(VMInterfaceModel vmiModel) {
+        _vmiModel = vmiModel;
+        if (vmiModel != null) {
+            vmiModel.addSuccessor(this);
+            s_logger.debug("vmiModel has " + vmiModel.successors().size() + " IP addresses");
+        }
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        InstanceIpModel other;
+        try {
+            other = (InstanceIpModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return InstanceIpModel.class.getName().compareTo(clsname);
+        }
+        return _name.compareTo(other._name);
+    }
+
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        if (_uuid != null) {
+            api.delete(InstanceIp.class, _uuid);
+        }
+        _uuid = null;
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+    }
+
+    public String getAddress() {
+        return _ipAddress;
+    }
+    
+    public String getName() {
+        return _name;
+    }
+    
+    public void setAddress(String ipaddress) {
+        _ipAddress = ipaddress;
+    }
+    
+    @Override
+    public void update(ModelController controller)
+            throws InternalErrorException, IOException {
+        assert _vmiModel != null;
+                
+        ApiConnector api = controller.getApiAccessor();
+        VirtualNetworkModel vnModel = _vmiModel.getVirtualNetworkModel();
+        assert vnModel != null;
+                
+        VirtualMachineInterface vmi = _vmiModel.getVMInterface();
+        VirtualNetwork vnet = vnModel.getVirtualNetwork();
+        if (vnet == null) {
+            vnet = (VirtualNetwork) api.findById(VirtualNetwork.class, _vmiModel.getNetworkUuid());
+        }
+        
+        String ipid = api.findByName(InstanceIp.class, null, _name);
+        if (ipid == null) {
+            InstanceIp ip_obj = new InstanceIp();
+            ip_obj.setName(_name);
+            ip_obj.setVirtualNetwork(vnet);
+            if (_ipAddress != null) {
+                ip_obj.setAddress(_ipAddress);
+            }
+            ip_obj.setVirtualMachineInterface(vmi);
+            if (!api.create(ip_obj)) {
+                throw new InternalErrorException("Unable to create instance-ip " +  _name);
+            }
+            api.read(ip_obj);
+            _uuid = ip_obj.getUuid();
+            if (_ipAddress == null) {
+                if (!api.read(ip_obj)) {
+                    throw new InternalErrorException("Unable to read instance-ip " +  _name);
+                }
+            }
+            _ipAddress = ip_obj.getAddress();
+        } else {
+            // Ensure that the instance-ip has the correct value and is pointing at the VMI.
+            InstanceIp ip_obj = (InstanceIp) api.findById(InstanceIp.class, ipid);
+            if (ip_obj == null) {
+                throw new InternalErrorException("Unable to read instance-ip " +  _name);
+            }
+            boolean update = false;
+            String ipnet_id = ObjectReference.getReferenceListUuid(ip_obj.getVirtualNetwork());
+            if (ipnet_id == null || !ipnet_id.equals(_vmiModel.getNetworkUuid())) {
+                ip_obj.setVirtualNetwork(vnet);
+                update = true;
+            }
+
+            if (_ipAddress != null && !ip_obj.getAddress().equals(_ipAddress)) {
+                ip_obj.setAddress(_ipAddress);
+                update = true;
+            }
+            
+            String vmi_id = ObjectReference.getReferenceListUuid(ip_obj.getVirtualMachineInterface());
+            if (vmi_id == null || !vmi_id.equals(_vmiModel.getUuid())) {
+                if (vmi != null) {
+                    ip_obj.setVirtualMachineInterface(vmi);
+                    update = true;
+                }
+            }
+
+            if (update && !api.update(ip_obj)) {
+                throw new InternalErrorException("Unable to update instance-ip: " + ip_obj.getName());
+            }
+            api.read(ip_obj);
+            _uuid = ip_obj.getUuid();
+            _ipAddress = ip_obj.getAddress();
+        }        
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java
new file mode 100644
index 0000000..8d57879
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelController.java
@@ -0,0 +1,85 @@
+// 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.network.contrail.model;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.dao.UserVmDao;
+
+import net.juniper.contrail.api.ApiConnector;
+
+/**
+ * Collection of state necessary for model object to update the Contrail API server.
+ * 
+ */
+public class ModelController {
+    ApiConnector _api;
+    ContrailManager _manager;
+    UserVmDao _vmDao;
+    NetworkDao  _networkDao;
+    NicDao _nicDao;
+    VlanDao  _vlanDao;
+    IPAddressDao _ipAddressDao;
+    
+    public ModelController(ContrailManager manager, ApiConnector api, UserVmDao vmDao, NetworkDao networkDao, 
+            NicDao nicDao, VlanDao vlanDao, IPAddressDao ipAddressDao) {
+        _manager = manager;
+        assert api != null;
+        _api = api;
+        assert vmDao != null;
+        _vmDao = vmDao;
+        assert networkDao != null;
+        _networkDao = networkDao;
+        assert nicDao != null;
+        _nicDao = nicDao;
+        assert vlanDao != null;
+        _vlanDao = vlanDao;
+        assert ipAddressDao != null;
+        _ipAddressDao = ipAddressDao;
+    }
+    ApiConnector getApiAccessor() {
+        return _api;
+    }
+    ContrailManager getManager() {
+        return _manager;
+    }
+    
+    UserVmDao getVmDao() {
+        return _vmDao;
+    }
+    
+    NetworkDao getNetworkDao() {
+        return _networkDao;
+    }
+    
+    NicDao getNicDao() {
+        return _nicDao;
+    }
+    
+    VlanDao getVlanDao() {
+        return _vlanDao;
+    }
+
+    IPAddressDao getIPAddressDao() {
+        return _ipAddressDao;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java
new file mode 100644
index 0000000..71d28ac
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObject.java
@@ -0,0 +1,118 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.TreeSet;
+
+import com.cloud.exception.InternalErrorException;
+
+/**
+ * ModelObject
+ * 
+ * A model object represents the desired state of the system.
+ * 
+ * The object constructor should set the uuid and the internal id of the cloudstack objects.
+ * 
+ * The build method reads the master database (typically cloudstack mysql) and derives the state that
+ * we wish to reflect in the contrail API. This method should not modify the Contrail API state.
+ * 
+ * The verify method reads the API server state and compares with cached properties.
+ * 
+ * The update method pushes updates to the contrail API server.
+ */
+public interface ModelObject {
+    public static class ModelReference implements Comparable<ModelReference> {
+        WeakReference<ModelObject> reference;
+        ModelReference(ModelObject obj) {
+            reference = new WeakReference<ModelObject>(obj);
+        }
+
+        @Override
+        public int compareTo(ModelReference other) {
+            ModelObject lhs = reference.get();
+            ModelObject rhs = other.reference.get();
+            if (lhs == null) {
+                if (rhs == null) {
+                    return 0;
+                }
+                return -1;
+            }
+            
+            return lhs.compareTo(rhs);
+        }
+        @Override
+        public boolean equals(Object other) {
+            try {
+                ModelReference rhs = (ModelReference) other;
+                return compareTo(rhs) == 0;
+            } catch (ClassCastException ex) {
+            }
+            return false;
+        }
+        public ModelObject get() {
+            return reference.get();
+        }
+    };
+    
+    public void addSuccessor(ModelObject child);
+    
+    public TreeSet<ModelReference> ancestors();
+    public void clearSuccessors();
+    public int compareTo(ModelObject o);
+
+    /**
+     * Delete the object from the API server.
+     * @param controller
+     * @throws IOException
+     */
+    public void delete(ModelController controller) throws IOException;
+
+    /**
+     * Deletes the object from the data model graph.
+     * 
+     * @param controller
+     * @throws IOException
+     */
+    public void destroy(ModelController controller) throws IOException;
+    
+    public void removeSuccessor(ModelObject child);
+    
+    public TreeSet<ModelObject> successors();
+    
+    /**
+     * Push updates to Contrail API server. This API is only valid for objects in the database.
+     * @param controller
+     * @throws IOException 
+     * @throws InternalErrorException 
+     */
+    public void update(ModelController controller) throws InternalErrorException, IOException;
+    
+    /**
+     * Check that the state of the current object matches the state of the API server.
+     * @param controller
+     * @return
+     */
+    public boolean verify(ModelController controller);
+    
+    /*
+     * Compare the state of existing model object with latest model object
+     */
+    public boolean compare(ModelController controller, ModelObject current);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
new file mode 100644
index 0000000..f22c7c5
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ModelObjectBase.java
@@ -0,0 +1,111 @@
+// 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.network.contrail.model;
+
+import java.util.Comparator;
+import java.util.TreeSet;
+
+public abstract class ModelObjectBase implements ModelObject {
+    public static class UuidComparator implements Comparator<ModelObject> {
+        @Override
+        public int compare(ModelObject lhs, ModelObject rhs) {
+            if (lhs == null) {
+                if (rhs == null) {
+                    return 0;
+                }
+                return -1;
+            }
+            if (rhs == null) {
+                return 1;
+            }
+            return lhs.compareTo(rhs);
+        }
+    }
+    private TreeSet<ModelReference> _ancestors;
+    
+    private TreeSet<ModelObject> _successors;
+
+    ModelObjectBase() {
+        _ancestors = new TreeSet<ModelReference>();
+        _successors = new TreeSet<ModelObject>(new UuidComparator());
+    }
+    
+    @Override
+    public void addSuccessor(ModelObject child) {
+        _successors.add(child);
+        ModelObjectBase base = (ModelObjectBase) child;
+        base._ancestors.add(new ModelReference(this));
+    }
+    
+    @Override
+    public TreeSet<ModelReference> ancestors() {
+        return _ancestors;
+    }
+    
+    private void clearAncestorReference(ModelObjectBase child) {
+        ModelReference ref = null;
+        for (ModelReference objref : child._ancestors) {
+            if (objref.get() == this) {
+                ref = objref;
+                break;
+            }
+        }
+        if (ref != null) {
+            child._ancestors.remove(ref);
+        }
+    }
+    
+    @Override
+    public void clearSuccessors() {
+        for (ModelObject successor : _successors) {
+            clearAncestorReference((ModelObjectBase) successor);
+        }
+        _successors.clear();
+    }
+
+    @Override
+    public boolean equals(Object rhs) {
+        ModelObject other;
+        try {
+            other = (ModelObject) rhs;
+        } catch (ClassCastException ex) {
+            return false;
+        }
+        return compareTo(other) == 0;
+    }
+    
+    @Override
+    protected void finalize() {
+        clearSuccessors();
+    }
+
+    public boolean hasDescendents() {
+        return !successors().isEmpty();
+    }
+    
+    @Override
+    public void removeSuccessor(ModelObject child) {
+        clearAncestorReference((ModelObjectBase) child);
+        _successors.remove(child);
+    }
+
+    @Override
+    public TreeSet<ModelObject> successors() {
+        return _successors;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
new file mode 100644
index 0000000..20b80be
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/ServiceInstanceModel.java
@@ -0,0 +1,320 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.NetworkPolicy;
+import net.juniper.contrail.api.types.PolicyEntriesType;
+import net.juniper.contrail.api.types.PolicyEntriesType.PolicyRuleType;
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.ServiceInstanceType;
+import net.juniper.contrail.api.types.ServiceTemplate;
+import net.juniper.contrail.api.types.ServiceTemplateType;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VirtualNetworkPolicyType;
+import net.juniper.contrail.api.ApiConnector;
+
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class ServiceInstanceModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(ServiceInstanceModel.class);
+
+    private String _uuid;
+    private String _fq_name;
+    private String _projectId;
+    private String _mgmtName;
+    private String _leftName;
+    private String _rightName;
+   
+    private String _templateName;
+    private String _templateId;
+    private String _templateUrl;
+    private VirtualNetwork _left;
+    private VirtualNetwork _right;
+    private ServiceTemplate _tmpl;
+    private ServiceInstance _serviceInstance;
+    private NetworkPolicy _policy;
+
+    /**
+     * Create a ServiceInstance as result of an API call.
+     * 
+     * @param owner
+     * @param name
+     * @param template
+     * @param serviceOffering
+     * @param left
+     * @param right
+     */
+    public ServiceInstanceModel(Project project, String name, VirtualMachineTemplate template,
+            ServiceOffering serviceOffering, VirtualNetwork left, VirtualNetwork right) {
+        String parent_name;
+        if (project != null) {
+            parent_name = StringUtils.join(project.getQualifiedName(), ':');
+        } else {
+            parent_name = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT;
+        }
+        _fq_name = parent_name + ":" + name;
+        
+        _mgmtName = ContrailManager.VNC_ROOT_DOMAIN + ":" + ContrailManager.VNC_DEFAULT_PROJECT + ":"
+                + ContrailManager.managementNetworkName;
+        _left = left;
+        _right = right;
+        _leftName = StringUtils.join(left.getQualifiedName(), ":");
+        _rightName = StringUtils.join(right.getQualifiedName(), ":");
+        
+        _templateName = template.getName();
+        _templateId = template.getUuid();
+        _templateUrl = template.getUrl();
+        
+        _projectId = project.getUuid();
+    }
+
+    /**
+     * Create an empty ServiceInstance.
+     * @param uuid
+     */
+    public ServiceInstanceModel(String uuid) {
+        _uuid  = uuid;
+    }
+    
+    public String getQualifiedName() {
+        return _fq_name;
+    }
+    
+    public String getName() {
+        return _fq_name.substring(_fq_name.lastIndexOf(':') + 1);
+    }
+    
+    private void applyNetworkPolicy(ModelController controller, NetworkPolicy policy,
+            VirtualNetwork left, VirtualNetwork right) {
+        left.setNetworkPolicy(policy, new VirtualNetworkPolicyType(
+                new VirtualNetworkPolicyType.SequenceType(1, 0), null));
+        // TODO: network_ipam_refs attr is missing
+        left.clearNetworkIpam();
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.update(left);
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to update virtual-network", ex);
+        }
+        
+        right.setNetworkPolicy(policy, new VirtualNetworkPolicyType(
+                new VirtualNetworkPolicyType.SequenceType(1, 0), null));
+        // TODO: network_ipam_refs attr is missing
+        right.clearNetworkIpam();
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.update(right);
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to update virtual-network", ex);
+        }
+    }
+
+    /**
+     * Recreate the model object from the Contrail API which is the master for this type of object.
+     * @param siObj
+     */
+    public void build(ModelController controller, ServiceInstance siObj) {
+        ApiConnector api = controller.getApiAccessor();
+        _serviceInstance = siObj;
+        _fq_name = StringUtils.join(siObj.getQualifiedName(), ':');
+        ServiceInstanceType props = siObj.getProperties();
+        // TODO: read management network names and cache network objects.
+        ObjectReference ref = siObj.getServiceTemplate().get(0);
+        if (ref != null) {
+            try {
+                ServiceTemplate tmpl = (ServiceTemplate) api.findById(ServiceTemplate.class, ref.getUuid());
+                _templateId = tmpl.getUuid();
+            } catch (IOException ex) {
+                s_logger.warn("service-template read", ex);
+            }
+        }
+        try {
+            Project project = (Project) api.findById(Project.class, siObj.getParentUuid());
+            if (project != null) {
+                _projectId = project.getUuid();
+            }
+            String policyId = api.findByName(NetworkPolicy.class, project, siObj.getName());
+            if (policyId != null) {
+                _policy = (NetworkPolicy) api.findById(NetworkPolicy.class, policyId);
+            }
+        } catch (IOException ex) {
+            s_logger.warn("network-policy read", ex);
+        }
+    }
+    
+    @Override
+    public int compareTo(ModelObject o) {
+        ServiceInstanceModel other;
+        try {
+            other = (ServiceInstanceModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return ServiceInstanceModel.class.getName().compareTo(clsname);
+        }
+        return _fq_name.compareTo(other._fq_name);
+    }
+    
+    private ServiceInstance createServiceInstance(ModelController controller) {
+        Project project  = null;
+        if (_projectId != null) {
+            try {
+                ApiConnector api = controller.getApiAccessor();
+                project = (Project) api.findById(Project.class, _projectId);
+           } catch (IOException ex) {
+                s_logger.warn("project read", ex);
+                throw new CloudRuntimeException("Unable to create service-instance object", ex);            
+           }
+        }
+
+        ServiceInstance si_obj = new ServiceInstance();
+        if (project != null) {
+            si_obj.setParent(project);
+        }
+        si_obj.setName(getName());
+        si_obj.setServiceTemplate(_tmpl);
+        si_obj.setProperties(new ServiceInstanceType(false, _mgmtName, _leftName, null, _rightName, null,
+                new ServiceInstanceType.ServiceScaleOutType(1, false)));
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            api.create(si_obj);
+        } catch (IOException ex) {
+            s_logger.warn("service-instance create", ex);
+            throw new CloudRuntimeException("Unable to create service-instance object", ex);
+        }
+        
+        return si_obj;
+    }
+    
+    private NetworkPolicy createServicePolicy(ModelController controller) {
+        NetworkPolicy policy = new NetworkPolicy();
+        policy.setParent(_serviceInstance.getParent());
+        policy.setName(_serviceInstance.getName());
+        PolicyEntriesType policy_map = new PolicyEntriesType();
+        List<PolicyRuleType.AddressType> srcList = new ArrayList<PolicyRuleType.AddressType>();
+        srcList.add(new PolicyRuleType.AddressType(null, _leftName, null));
+        List<PolicyRuleType.AddressType> dstList = new ArrayList<PolicyRuleType.AddressType>();
+        dstList.add(new PolicyRuleType.AddressType(null, _rightName, null));
+        List<String> siList = new ArrayList<String>();
+        siList.add(StringUtils.join(_serviceInstance.getQualifiedName(), ':'));
+        List<PolicyRuleType.PortType> portAny = new ArrayList<PolicyRuleType.PortType>();
+        portAny.add(new PolicyRuleType.PortType(0, 65535));
+        
+        PolicyRuleType rule = new PolicyRuleType(
+                new PolicyRuleType.SequenceType(1, 0), /* uuid */ null, "<>", "any",
+                srcList, portAny, /* application */ null, dstList, portAny,
+                new PolicyRuleType.ActionListType("pass", "in-network", siList, null));
+        policy_map.addPolicyRule(rule);
+        policy.setEntries(policy_map);
+        
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            if (!api.create(policy)) {
+                throw new CloudRuntimeException("Unable to create network-policy");
+            }
+        } catch (IOException ex) {
+            throw new CloudRuntimeException("Unable to create network-policy", ex);
+        }
+        return policy;
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        if (_serviceInstance != null) {
+            api.delete(_serviceInstance);
+        }
+    }
+    
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+    }
+    
+    public ServiceInstance getServiceInstance() {
+        return _serviceInstance;
+    }
+
+    public String getUuid() {
+        return _uuid;
+    }
+    
+    private ServiceTemplate locateServiceTemplate(ModelController controller) {
+        ServiceTemplate tmpl;
+        try {
+            ApiConnector api = controller.getApiAccessor();
+            tmpl = (ServiceTemplate) api.findById(ServiceTemplate.class, _templateId);
+        } catch (IOException ex) {
+            s_logger.warn("service-template read", ex);
+            throw new CloudRuntimeException("Unable to create service-template object", ex);
+        }
+        if (tmpl == null) {
+            tmpl = new ServiceTemplate();
+            tmpl.setName(_templateName);
+            tmpl.setUuid(_templateId);
+            ServiceTemplateType props = new ServiceTemplateType("in-network", null, _templateUrl, false, null);
+            tmpl.setProperties(props);
+            try {
+                ApiConnector api = controller.getApiAccessor();
+                api.create(tmpl);
+            } catch (IOException ex) {
+                throw new CloudRuntimeException("Unable to create service-template object", ex);
+            }
+        }
+        return tmpl;
+    }
+
+    @Override
+    public void update(ModelController controller) {
+        _tmpl = locateServiceTemplate(controller);
+        if (_serviceInstance == null) {
+            _serviceInstance = createServiceInstance(controller);
+        }
+        _uuid = _serviceInstance.getUuid();
+        if (_policy == null) {
+            _policy = createServicePolicy(controller);
+            // TODO: update the network model objects and call update
+            applyNetworkPolicy(controller, _policy, _left, _right);
+        }
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
new file mode 100644
index 0000000..3476569
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VMInterfaceModel.java
@@ -0,0 +1,265 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.log4j.Logger;
+
+import net.juniper.contrail.api.types.MacAddressesType;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.VirtualMachineInterfacePropertiesType;
+import net.juniper.contrail.api.ApiConnector;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Network;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+
+public class VMInterfaceModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VMInterfaceModel.class);
+
+    private String _uuid;
+    
+    /**
+     * properties
+     */
+    private String _vmName;
+    private int _deviceId;
+    private boolean _netActive;
+    private boolean _nicActive;
+    private String _serviceTag;
+    private String _networkId;
+    private String _macAddress;
+
+    /**
+     * cached objects
+     */
+    private VirtualMachineModel _vmModel;
+    private VirtualNetworkModel _vnModel;
+    private VirtualMachineInterface _vmi;
+    
+    public VMInterfaceModel(String uuid) {
+        _uuid = uuid;
+    }
+    
+    public void addToVirtualMachine(VirtualMachineModel vmModel) {
+        _vmModel = vmModel;
+        if (vmModel != null) {
+            vmModel.addSuccessor(this);
+        }
+    }
+    
+    public void addToVirtualNetwork(VirtualNetworkModel vnModel) {
+        _vnModel = vnModel;
+        if (vnModel != null) {
+            vnModel.addSuccessor(this);
+        }
+    }
+    
+    public void build(ModelController controller, VMInstanceVO instance, NicVO nic) throws IOException {
+        setProperties(controller, instance, nic);
+
+        InstanceIpModel ipModel = getInstanceIp();
+        String ipAddress = nic.getIp4Address();
+        if (ipAddress != null) {
+            if (ipModel == null) {
+                ipModel = new InstanceIpModel(_vmName, _deviceId);
+                ipModel.addToVMInterface(this);
+            }
+            ipModel.setAddress(ipAddress);
+        } else if (ipModel != null) {
+            removeSuccessor(ipModel);
+        }
+        
+        _macAddress = nic.getMacAddress();
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        VMInterfaceModel other;
+        try {
+            other = (VMInterfaceModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VMInterfaceModel.class.getName().compareTo(clsname);
+        }
+        return _uuid.compareTo(other._uuid);
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+
+        ApiConnector api = controller.getApiAccessor();
+        api.delete(VirtualMachineInterface.class, _uuid);        
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+        
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+    
+    public InstanceIpModel getInstanceIp() {
+        for (ModelObject successor : successors()) {
+            if (successor.getClass() == InstanceIpModel.class) {
+                return (InstanceIpModel) successor;
+            }
+        }
+        return null;
+    }
+    
+    public String getNetworkUuid() {
+        return _networkId;
+    }
+    
+    public VirtualNetworkModel getVirtualNetworkModel() {
+        return _vnModel;
+    }
+    
+    public String getUuid() {
+        return _uuid;
+    }
+    
+    public VirtualMachineInterface getVMInterface() {
+        return _vmi;
+    }
+    
+    public void setProperties(ModelController controller, VMInstanceVO instance, NicVO nic) throws IOException {
+        _vmName = instance.getInstanceName();
+        _deviceId = nic.getDeviceId();
+        Network network = controller.getNetworkDao().findById(nic.getNetworkId());
+
+        switch (nic.getState()) {
+        case Allocated:
+        case Reserved:
+            _nicActive = true;
+            break;
+        default:
+            _nicActive = false;
+            break;
+        }
+        
+        switch (network.getState()) {
+        case Implemented:
+        case Setup:
+            _netActive = true;
+            break;
+        default:
+            _netActive = false;
+            break;
+        }
+        assert _vnModel != null;
+        _networkId = _vnModel.getUuid();        
+    }
+    
+    public void setActive() {
+        _nicActive = true;
+    }
+    
+    void setServiceTag(String tag) {
+        _serviceTag = tag;
+    }
+    
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+        if (!_netActive || !_nicActive) {
+            s_logger.debug("vm interface update, _netActive: " + _netActive + ", _nicActive: " + _nicActive);
+            delete(controller);
+            return;
+        }
+        if (_vmModel == null) {
+            throw new InternalErrorException("virtual-machine not set on VMI: " + _uuid);
+        }
+        if (_vnModel == null) {
+            throw new InternalErrorException("virtual-network not set on VMI: " + _uuid);
+        }
+        ContrailManager manager = controller.getManager();
+        ApiConnector api = controller.getApiAccessor();
+
+        VirtualMachineInterface vmi = (VirtualMachineInterface) api.findById(VirtualMachineInterface.class, _uuid);
+        boolean create = false;
+        if (vmi == null) {
+            create = true;
+            vmi = new VirtualMachineInterface();
+            vmi.setParent(_vmModel.getVirtualMachine());
+            vmi.setName(manager.getVifNameByVmName(_vmModel.getInstanceName(), _deviceId));
+            vmi.setUuid(_uuid);
+            vmi.setVirtualNetwork(_vnModel.getVirtualNetwork());
+        } else {
+            // Do not try to update VMI to routing-instance references. These are managed by schema-transformer.
+            vmi.clearRoutingInstance();
+        }
+        _vmi = vmi;
+        if (_macAddress != null) {
+            MacAddressesType mac = new MacAddressesType();
+            mac.addMacAddress(_macAddress);
+            vmi.setMacAddresses(mac);
+        }
+        
+        if (_serviceTag != null) {
+            vmi.setProperties(new VirtualMachineInterfacePropertiesType(_serviceTag, null));
+        }
+
+        if (create) {
+            if (!api.create(vmi)) {
+                throw new InternalErrorException("Unable to create virtual-machine-interface " +  _uuid);
+            }
+        } else {
+            if (!api.update(vmi)) {
+                throw new InternalErrorException("Unable to update virtual-machine-interface " +  _uuid);
+            }
+        }
+
+        api.read(vmi);
+        
+        int ipCount = 0;
+        for (ModelObject successor: successors()) {
+            if (successor.getClass() == InstanceIpModel.class) {
+                ipCount++;
+            }
+            successor.update(controller);
+        }
+        // TODO: if there are no instance-ip successors present and we have an instance-ip object reference
+        // delete the object.
+        if (ipCount == 0) {
+            s_logger.warn("virtual-machine-interface " + _uuid + " has no instance-ip");
+        }
+    }
+    
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
new file mode 100644
index 0000000..ec20a94
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualMachineModel.java
@@ -0,0 +1,349 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.log4j.Logger;
+
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.NicDao;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.ServiceInstance;
+import net.juniper.contrail.api.types.VirtualMachine;
+import net.juniper.contrail.api.ApiConnector;
+
+public class VirtualMachineModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VirtualMachineModel.class);
+
+    private String _uuid;
+    private long _instanceId;
+    
+    /*
+     * current state for object properties 
+     */
+    private boolean _initialized;
+    private boolean _active;
+    private String _serviceUuid;
+    private String _instanceName;
+    private String _projectId;
+    
+    /*
+     * cached API server objects
+     */
+    private VirtualMachine _vm;
+    private ServiceInstanceModel _serviceModel;
+    
+    public VirtualMachineModel(VMInstanceVO vm, String uuid) {
+        _uuid = uuid;
+        if (vm != null) {
+            _instanceId = vm.getId();
+            _instanceName = vm.getInstanceName();
+        }
+    }
+    
+    /**
+     * Resynchronize internal state from the cloudstack DB object.
+     * @param instance
+     */
+    public void build(ModelController controller, VMInstanceVO instance) {
+        setProperties(controller, instance);
+        UserVm userVm = controller.getVmDao().findById(instance.getId());
+        if (userVm != null && userVm.getUserData() != null) {
+            s_logger.debug("vm " + instance.getInstanceName() + " user data: " + userVm.getUserData());
+            final Gson json = new Gson();
+            Map<String, String> kvmap = json.fromJson(userVm.getUserData(),
+                    new TypeToken<Map<String, String>>(){}.getType());
+            String data = kvmap.get("service-instance");
+            if (data != null) {
+                /* link the object with the service instance */
+                buildServiceInstance(controller, data);
+            }
+        }
+    }
+
+    /**
+     * Link the virtual machine with the service instance when recovering state from database.
+     * 
+     * @param controller
+     * @param serviceUuid
+     */
+    private void buildServiceInstance(ModelController controller, String serviceUuid) {
+        ContrailManager manager = controller.getManager();
+        ApiConnector api = controller.getApiAccessor();
+        _serviceUuid = serviceUuid;
+        
+        ServiceInstanceModel siModel = manager.getDatabase().lookupServiceInstance(serviceUuid);
+        if (siModel == null) {
+            ServiceInstance siObj;
+            try {
+                siObj = (ServiceInstance) api.findById(ServiceInstance.class, serviceUuid);
+            } catch (IOException ex) {
+                s_logger.warn("service-instance read", ex);
+                throw new CloudRuntimeException("Unable to read service-instance object", ex);
+            }
+            if (siObj == null) {
+                siModel = new ServiceInstanceModel(serviceUuid);
+                siModel.build(controller, siObj);
+            }
+        }
+        _serviceModel = siModel;
+    }
+
+    @Override
+    public int compareTo(ModelObject o) {
+        VirtualMachineModel other;
+        try {
+            other = (VirtualMachineModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VirtualMachineModel.class.getName().compareTo(clsname);
+        }
+        return _uuid.compareTo(other._uuid);
+    }
+    
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+        
+        try {
+            api.delete(VirtualMachine.class, _uuid);
+        } catch (IOException ex) {
+            s_logger.warn("virtual-machine delete", ex);
+        }
+
+
+        if (_serviceModel != null) {
+            _serviceModel.delete(controller);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+
+        clearSuccessors();
+        
+        if (_serviceModel != null) {
+            _serviceModel.removeSuccessor(this);
+            _serviceModel.destroy(controller);
+            ContrailManager manager = controller.getManager();
+            manager.getDatabase().getServiceInstances().remove(_serviceModel);
+            _serviceModel = null;
+        }
+    }
+
+    public String getInstanceName() {
+        return _instanceName;
+    }
+    
+    public String getUuid() {
+        return _uuid;
+    }
+
+    
+    public VirtualMachine getVirtualMachine() {
+        return _vm;
+    }
+    
+    public VMInterfaceModel getVMInterface(String uuid) {
+        TreeSet<ModelObject> tree = successors();
+        VMInterfaceModel vmiKey = new VMInterfaceModel(uuid);
+        VMInterfaceModel current = (VMInterfaceModel) tree.ceiling(vmiKey);
+        if (current != null && current.getUuid().equals(uuid)) {
+            return current;
+        }
+        return null;
+    }
+    
+    public boolean isActive() {
+        return _active;
+    }
+    
+    boolean isActiveInstance(VMInstanceVO instance) {
+        switch (instance.getState()) {
+        case Migrating:
+        case Starting:
+        case Running:
+        case Shutdowned:
+        case Stopped:
+        case Stopping:
+            return true;
+            
+        case Destroyed:
+        case Error:
+        case Expunging:
+            return false;
+            
+        default:
+            s_logger.warn("Unknown VMInstance state " + instance.getState().getDescription());
+        }
+        return true;
+    }
+    
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller, VMInstanceVO instance) {
+        ContrailManager manager = controller.getManager();
+        _instanceName = instance.getInstanceName();
+        _active = isActiveInstance(instance);
+        
+        try {
+            _projectId = manager.getProjectId(instance.getDomainId(), instance.getAccountId());
+        } catch (IOException ex) {
+            s_logger.warn("project read", ex);
+            throw new CloudRuntimeException(ex);
+        }
+        _initialized = true;
+    }
+
+    /**
+     * Link the virtual machine with a service instance via programmatic API call.
+     * @throws IOException 
+     */
+    public void setServiceInstance(ModelController controller, VMInstanceVO instance,
+            ServiceInstanceModel serviceModel) throws IOException {
+        _serviceUuid = serviceModel.getUuid();
+        _serviceModel = serviceModel;
+        serviceModel.addSuccessor(this);
+        setServiceInstanceNics(controller, instance);
+    }
+    
+    private void setServiceInstanceNics(ModelController controller, VMInstanceVO instance) throws IOException {
+        NicDao nicDao = controller.getNicDao();
+        ContrailManager manager = controller.getManager();
+        NetworkDao networkDao = controller.getNetworkDao();
+        
+        List<NicVO> nics = nicDao.listByVmId(_instanceId);
+        for (NicVO nic : nics) {
+            String tag;
+            
+            switch (nic.getDeviceId()) {
+            case 0:
+                tag = "management";
+                break;
+            case 1:
+                tag = "left";
+                break;
+            case 2:
+                tag = "right";
+                break;
+            default:
+                tag = null;
+            }
+
+            VMInterfaceModel vmiModel = getVMInterface(nic.getUuid());
+            if (vmiModel == null) {
+                vmiModel = new VMInterfaceModel(nic.getUuid());
+                vmiModel.addToVirtualMachine(this);
+                NetworkVO network = networkDao.findById(nic.getNetworkId());
+                VirtualNetworkModel vnModel = manager.getDatabase().lookupVirtualNetwork(
+                        network.getUuid(), manager.getCanonicalName(network), network.getTrafficType());
+                assert vnModel != null;
+                vmiModel.addToVirtualNetwork(vnModel);
+            }
+            vmiModel.setProperties(controller, instance, nic);
+            vmiModel.setServiceTag(tag);
+        }
+    }
+    
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+        assert _initialized;
+        ApiConnector api = controller.getApiAccessor();
+
+        VirtualMachine vm = _vm;
+        if (vm == null) {
+            _vm = vm = (VirtualMachine) api.findById(VirtualMachine.class, _uuid);
+            if (vm == null) {
+                vm = new VirtualMachine();
+                if (_projectId != null) {
+                    Project project;
+                    try {
+                        project = (Project) api.findById(Project.class, _projectId);
+                    } catch (IOException ex) {
+                        s_logger.debug("project read", ex);
+                        throw new CloudRuntimeException("Failed to read project", ex);                    
+                    }
+                    vm.setParent(project);
+                }
+                vm.setName(_instanceName);
+                vm.setUuid(_uuid);
+            }
+        }
+
+        if (_serviceModel != null) { 
+            vm.setServiceInstance(_serviceModel.getServiceInstance());
+        }
+
+        if (_vm == null) {
+            try {
+                api.create(vm);
+            } catch (Exception ex) {
+                s_logger.debug("virtual-machine create", ex);
+                throw new CloudRuntimeException("Failed to create virtual-machine", ex);
+            }
+            _vm = vm;
+        } else {
+            try {
+                api.update(vm);
+            } catch (IOException ex) {
+                s_logger.warn("virtual-machine update", ex);
+                throw new CloudRuntimeException("Unable to update virtual-machine object", ex);
+            }            
+        }
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+    
+    @Override
+    public boolean verify(ModelController controller) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject current) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
new file mode 100644
index 0000000..b4968ac
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/VirtualNetworkModel.java
@@ -0,0 +1,494 @@
+// 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.network.contrail.model;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.log4j.Logger;
+
+import com.cloud.dc.VlanVO;
+import com.cloud.dc.dao.VlanDao;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.NetworkIpam;
+import net.juniper.contrail.api.types.Project;
+import net.juniper.contrail.api.types.SubnetType;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VnSubnetsType;
+import net.juniper.contrail.api.ApiConnector;
+
+public class VirtualNetworkModel extends ModelObjectBase {
+    private static final Logger s_logger = Logger.getLogger(VirtualNetworkModel.class);
+
+    private String _uuid;
+    private long _id;
+    private TrafficType _trafficType; 
+
+    /*
+     * current state for object properties 
+     */
+    private boolean _initialized;
+    private String _name;
+    private String _prefix;
+    private String _gateway;
+    private String _projectId;
+
+    /*
+     * cached API server objects
+     */
+    private VirtualNetwork _vn;
+    private NetworkIpam _ipam;
+
+    private FloatingIpPoolModel _fipPoolModel;
+
+    public VirtualNetworkModel(Network network, String uuid, String name, TrafficType trafficType) {
+        _uuid = uuid;
+        _name = name;
+        _trafficType = trafficType;
+        if (network != null) {
+            _id = network.getId();
+        }
+
+        if (isDynamicNetwork()) {
+            assert _uuid != null : "uuid is must for dynamic networks";
+        } else {
+            assert _name != null : "name is must for static networks";
+        }
+    }
+
+    /*
+     * Resynchronize internal state from the cloudstack DB object.
+     */
+    public void build(ModelController controller, Network network) {
+        setProperties(controller, network);
+    }
+
+    /**
+     * Determine whether this network is dynamically created by cloudstack or is created by default by the contrail
+     * API server.
+     * 
+     * @return
+     */
+    boolean isDynamicNetwork() {
+        return (_trafficType == TrafficType.Guest) || (_trafficType == TrafficType.Public);
+    }
+    
+    @Override
+    public int compareTo(ModelObject o) {
+        VirtualNetworkModel other;
+        try {
+            other = (VirtualNetworkModel) o;
+        } catch (ClassCastException ex) {
+            String clsname = o.getClass().getName();
+            return VirtualNetworkModel.class.getName().compareTo(clsname);
+        }
+        
+        if (!isDynamicNetwork()) {
+            if (!other.isDynamicNetwork()) {
+                // name is not unique since both management and storage networks may map to ip-fabric
+                int cmp = _name.compareTo(other.getName());
+                if (cmp != 0) {
+                    return cmp;
+                }
+                return _trafficType.compareTo(other._trafficType);
+            }
+            return -1;
+        } else if (!other.isDynamicNetwork()) {
+            return 1;
+        }
+                
+        return _uuid.compareTo(other._uuid);
+    }
+
+    @Override
+    public void delete(ModelController controller) throws IOException {
+        ApiConnector api = controller.getApiAccessor();
+        for (ModelObject successor: successors()) {
+            successor.delete(controller);
+        }
+
+        try {
+            api.delete(VirtualNetwork.class, _uuid);
+        } catch (IOException ex) {
+            s_logger.warn("virtual-network delete", ex);
+        }
+    }
+
+    @Override
+    public void destroy(ModelController controller) throws IOException {
+        delete(controller);
+
+        for (ModelObject successor: successors()) {
+            successor.destroy(controller);
+        }
+        clearSuccessors();
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public String getUuid() {
+        return _uuid;
+    }
+
+
+    public VirtualNetwork getVirtualNetwork() {
+        return _vn;
+    }
+
+    /**
+     * Initialize the object properties based on the DB object.
+     * Common code between plugin calls and DBSync.
+     */
+    public void setProperties(ModelController controller, Network network) {
+        ContrailManager manager = controller.getManager();
+        _name = manager.getCanonicalName(network);
+        _prefix = network.getCidr();
+        _gateway = network.getGateway();
+        
+        // For non-cloudstack managed network, find the uuid at this stage.
+        if (!isDynamicNetwork()) {
+            try {
+                _uuid = manager.findVirtualNetworkId(network);
+            } catch (IOException ex) {
+                s_logger.warn("Unable to read virtual-network", ex);
+            }
+        }
+        
+        try {
+            _projectId = manager.getProjectId(network.getDomainId(), network.getAccountId());
+        } catch (IOException ex) {
+            s_logger.warn("project read", ex);
+            throw new CloudRuntimeException(ex);
+        }
+      
+        _initialized = true;
+    }
+
+    @Override
+    public void update(ModelController controller) throws InternalErrorException, IOException {
+
+        assert _initialized;
+
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+        VirtualNetwork vn = _vn;
+        
+        if (!isDynamicNetwork()) {
+            _vn = (VirtualNetwork) controller.getApiAccessor().findById(VirtualNetwork.class, _uuid);
+            return;
+        }
+        
+        assert _uuid != null : "uuid is not set";
+
+        if (_vn == null) {
+            vn = _vn = (VirtualNetwork) controller.getApiAccessor().findById(VirtualNetwork.class, _uuid);
+            if (vn == null) {
+                vn = new VirtualNetwork();
+                if (_projectId != null) {
+                    Project project;
+                    try {
+                        project = (Project) api.findById(Project.class, _projectId);
+                    } catch (IOException ex) {
+                        s_logger.debug("project read", ex);
+                        throw new CloudRuntimeException("Failed to read project", ex);                    
+                    }
+                    vn.setParent(project);
+                }
+                vn.setName(_name);
+                vn.setUuid(_uuid);
+            } 
+        }
+     
+        if (_ipam == null) {
+            NetworkIpam ipam = null;
+            try {
+                String ipam_id = api.findByName(NetworkIpam.class, null, "default-network-ipam");
+                if (ipam_id == null) {
+                    s_logger.debug("could not find default-network-ipam");
+                    return;
+                }
+                ipam = (NetworkIpam) api.findById(NetworkIpam.class, ipam_id);
+                if (ipam == null) {
+                    s_logger.debug("could not find NetworkIpam with ipam_id: " + ipam_id);
+                    return;
+                }
+            } catch (IOException ex) {
+                s_logger.error(ex);
+                return;
+            }
+            _ipam = ipam;
+        }
+
+        if (_prefix != null) {
+            VnSubnetsType subnet = new VnSubnetsType();
+            String[] addr_pair = _prefix.split("\\/");
+            subnet.addIpamSubnets(new SubnetType(addr_pair[0], Integer.parseInt(addr_pair[1])), _gateway);
+            vn.setNetworkIpam(_ipam, subnet);
+        } else if (_trafficType == TrafficType.Public) {
+            vn.clearNetworkIpam();
+            /* Subnet information for Public is stored in the vlan table */
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan : vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                int slash = cidr.indexOf('/');
+                String ip_addr = cidr.substring(0, slash);
+                int plen = Integer.parseInt(cidr.substring(slash + 1));
+                VnSubnetsType subnet = new VnSubnetsType();
+                subnet.addIpamSubnets(new SubnetType(ip_addr, plen), vlan.getVlanGateway());
+                vn.addNetworkIpam(_ipam, subnet);
+            }
+        } 
+
+        if (_vn == null) {
+            try {
+                api.create(vn);
+            } catch (Exception ex) {
+                s_logger.debug("virtual-network create", ex);
+                throw new CloudRuntimeException("Failed to create virtual-network", ex);
+            }
+            _vn = vn;
+        } else {
+            try {
+                api.update(vn);
+            } catch (IOException ex) {
+                s_logger.warn("virtual-network update", ex);
+                throw new CloudRuntimeException("Unable to update virtual-network object", ex);
+            }            
+        }
+
+        for (ModelObject successor: successors()) {
+            successor.update(controller);
+        }
+    }
+
+    public void read(ModelController controller) {
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+        try {
+            _vn = (VirtualNetwork) api.findById(VirtualNetwork.class, _uuid);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (_vn == null) {
+            return;
+        }
+        if (_ipam == null) {
+            NetworkIpam ipam = null;
+            try {
+                String ipam_id = api.findByName(NetworkIpam.class, null, "default-network-ipam");
+                if (ipam_id == null) {
+                    s_logger.debug("could not find default-network-ipam");
+                    return;
+                }
+                ipam = (NetworkIpam) api.findById(NetworkIpam.class, ipam_id);
+                if (ipam == null) {
+                    s_logger.debug("could not find NetworkIpam with ipam_id: " + ipam_id);
+                    return;
+                }
+            } catch (IOException ex) {
+                s_logger.error(ex);
+                return;
+            }
+            _ipam = ipam;
+        }
+
+        if (_prefix != null) {
+            VnSubnetsType subnet = new VnSubnetsType();
+            String[] addr_pair = _prefix.split("\\/");
+            subnet.addIpamSubnets(new SubnetType(addr_pair[0], Integer.parseInt(addr_pair[1])), _gateway);
+            _vn.setNetworkIpam(_ipam, subnet);
+        } else if (_trafficType == TrafficType.Public) {
+            _vn.clearNetworkIpam();
+            /* Subnet information for Public is stored in the vlan table */
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan : vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                int slash = cidr.indexOf('/');
+                String ip_addr = cidr.substring(0, slash);
+                int plen = Integer.parseInt(cidr.substring(slash + 1));
+                VnSubnetsType subnet = new VnSubnetsType();
+                subnet.addIpamSubnets(new SubnetType(ip_addr, plen), vlan.getVlanGateway());
+                _vn.addNetworkIpam(_ipam, subnet);
+            }
+        } 
+        return;
+    }
+
+    @Override
+    public boolean verify(ModelController controller) {
+        assert _initialized : "initialized is false";
+        assert _uuid != null : "uuid is not set";
+
+        ApiConnector api = controller.getApiAccessor();
+        VlanDao vlanDao = controller.getVlanDao();
+
+        try {
+            _vn = (VirtualNetwork) api.findById(VirtualNetwork.class, _uuid);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        if (_vn == null) {
+            return false;
+        }
+
+        if (!isDynamicNetwork()) {
+            return true;
+        }
+        
+        List<String> dbSubnets = new ArrayList<String>();
+        if (_trafficType == TrafficType.Public) {
+            List<VlanVO> vlan_list = vlanDao.listVlansByNetworkId(_id);
+            for (VlanVO vlan:vlan_list) {
+                String cidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask());
+                dbSubnets.add(vlan.getVlanGateway() + cidr);
+            }
+        } else {
+            dbSubnets.add(this._gateway + this._prefix);  
+        }
+            
+        List<ObjectReference<VnSubnetsType>> ipamRefs = _vn.getNetworkIpam();
+        List<String> vncSubnets = new ArrayList<String>();
+        
+        if (ipamRefs == null && !dbSubnets.isEmpty()) {
+            return false;
+        }
+        
+        if (ipamRefs != null) {
+            for (ObjectReference<VnSubnetsType> ref: ipamRefs) {
+                VnSubnetsType vnSubnetType = ref.getAttr();
+                if (vnSubnetType != null) {
+                    List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                    if (subnets != null && !subnets.isEmpty()) {
+                        VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                        vncSubnets.add(ipamSubnet.getDefaultGateway() +
+                                ipamSubnet.getSubnet().getIpPrefix() +"/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                    }  
+                } 
+            }
+        }
+        // unordered, no duplicates hence perform negation operation as set 
+        Set<String> diff = new HashSet<String>(dbSubnets);
+        diff.removeAll(vncSubnets);
+        
+        if (!diff.isEmpty()) {
+            s_logger.debug("Subnets changed, network: " + this._name + 
+                    "; db: " + dbSubnets + ", vnc: " + vncSubnets + ", diff: " + diff);
+            return false;
+        }
+        
+        for (ModelObject successor: successors()) {
+            if (!successor.verify(controller)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean compare(ModelController controller, ModelObject o) {
+        VirtualNetworkModel latest;
+        ApiConnector api = controller.getApiAccessor();
+
+        assert this._vn != null : "vnc virtual network current is not initialized";
+
+        try {
+            latest = (VirtualNetworkModel) o;            
+        } catch (ClassCastException ex) {
+            s_logger.warn("Invalid model object is passed to cast to VirtualNetworkModel");
+            return false;
+        }
+        
+        try {
+            latest.read(controller);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+        assert latest._vn != null : "vnc virtual network new is not initialized";
+        
+        List<ObjectReference<VnSubnetsType>> currentIpamRefs = this._vn.getNetworkIpam();
+        List<ObjectReference<VnSubnetsType>> newIpamRefs = latest._vn.getNetworkIpam();
+        List<String> currentSubnets = new ArrayList<String>();
+        List<String> newSubnets = new ArrayList<String>();
+
+        
+        if ((currentIpamRefs == null && newIpamRefs != null) || 
+            (currentIpamRefs != null && newIpamRefs == null)) {  //Check for existence only
+            s_logger.debug("ipams differ: current=" + currentIpamRefs + ", new=" + newIpamRefs);
+            return false;
+        }        
+        if (currentIpamRefs == null) {
+            return true;
+        }
+        
+        for (ObjectReference<VnSubnetsType> ref: currentIpamRefs) {
+            VnSubnetsType vnSubnetType = ref.getAttr();
+            if (vnSubnetType != null) {
+                List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                if (subnets != null && !subnets.isEmpty()) {
+                    VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                    currentSubnets.add(ipamSubnet.getDefaultGateway() + ipamSubnet.getSubnet().getIpPrefix() +
+                            "/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                } 
+            } 
+        }
+        
+        for (ObjectReference<VnSubnetsType> ref: newIpamRefs) {
+            VnSubnetsType vnSubnetType = ref.getAttr();
+            if (vnSubnetType != null) {
+                List<VnSubnetsType.IpamSubnetType> subnets = vnSubnetType.getIpamSubnets();
+                if (subnets != null && !subnets.isEmpty()) {
+                    VnSubnetsType.IpamSubnetType ipamSubnet = subnets.get(0);
+                    newSubnets.add(ipamSubnet.getDefaultGateway() + ipamSubnet.getSubnet().getIpPrefix() +
+                            "/" + ipamSubnet.getSubnet().getIpPrefixLen());  
+                } 
+            } 
+        }
+        
+        Set<String> diff = new HashSet<String>(currentSubnets);
+        diff.removeAll(newSubnets);
+        
+        if (!diff.isEmpty()) {
+            s_logger.debug("Subnets differ, network: " + this._name + 
+                    "; db: " + currentSubnets + ", vnc: " + newSubnets + ", diff: " + diff);
+            return false;
+        }
+                
+        return true;
+    }
+
+    public FloatingIpPoolModel getFipPoolModel() {
+        return _fipPoolModel;
+    }
+    public void setFipPoolModel(FloatingIpPoolModel fipPoolModel) {
+        _fipPoolModel = fipPoolModel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
new file mode 100644
index 0000000..e70ac5e
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ApiConnectorMockito.java
@@ -0,0 +1,149 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.ApiConnectorMock;
+import net.juniper.contrail.api.ApiObjectBase;
+import net.juniper.contrail.api.ApiPropertyBase;
+import net.juniper.contrail.api.ObjectReference;
+import net.juniper.contrail.api.types.NetworkIpam;
+
+import org.apache.log4j.Logger;
+import static org.mockito.Mockito.*;
+
+import com.google.common.collect.ImmutableMap;
+
+public class ApiConnectorMockito implements ApiConnector {
+    private static final Logger s_logger =
+            Logger.getLogger(ApiConnectorMockito.class);
+
+    static final Map<String, ApiObjectBase> object_map = new ImmutableMap.Builder<String, ApiObjectBase>().
+            put("network-ipam:default-network-ipam", new NetworkIpam()).
+            build();
+    private ApiConnectorMock _mock;
+    private ApiConnector _spy;
+
+    public ApiConnectorMockito(String hostname, int port) {
+        _mock = new ApiConnectorMock(hostname, port);
+        _spy = spy(_mock);
+    }
+
+    public ApiConnector getSpy() {
+        return _spy;
+    }
+
+    @Override
+    public boolean create(ApiObjectBase arg0) throws IOException {
+        s_logger.debug("create " + arg0.getClass().getName() + " id: " + arg0.getUuid());
+        return _spy.create(arg0);
+    }
+
+    @Override
+    public void delete(ApiObjectBase arg0) throws IOException {
+        s_logger.debug("delete " + arg0.getClass().getName() + " id: " + arg0.getUuid());
+        _spy.delete(arg0);
+    }
+
+    @Override
+    public void delete(Class<? extends ApiObjectBase> arg0, String arg1)
+            throws IOException {
+        s_logger.debug("create " + arg0.getName() + " id: " + arg1);
+        _spy.delete(arg0, arg1);
+    }
+
+    @Override
+    public ApiObjectBase find(Class<? extends ApiObjectBase> arg0,
+            ApiObjectBase arg1, String arg2) throws IOException {
+        StringBuilder msg = new StringBuilder();
+        msg.append("find " + arg0.getName());
+        if (arg1 != null) {
+            msg.append(" parent: " + arg1.getName());
+        }
+        msg.append(" name: " + arg2);
+
+        return _mock.find(arg0, arg1, arg2);
+    }
+
+    @Override
+    public ApiObjectBase findByFQN(Class<? extends ApiObjectBase> arg0,
+            String arg1) throws IOException {
+        s_logger.debug("find " + arg0.getName() + " name: " + arg1);
+        return _mock.findByFQN(arg0, arg1);
+    }
+
+    @Override
+    public ApiObjectBase findById(Class<? extends ApiObjectBase> arg0,
+            String arg1) throws IOException {
+        s_logger.debug("find " + arg0.getName() + " id: " + arg1);
+        return _mock.findById(arg0, arg1);
+    }
+
+    @Override
+    public String findByName(Class<? extends ApiObjectBase> arg0,
+            List<String> arg1) throws IOException {
+        s_logger.debug("find " + arg0.getName() + " name: " + arg1);
+        return _mock.findByName(arg0, arg1);
+    }
+
+    @Override
+    public String findByName(Class<? extends ApiObjectBase> arg0,
+            ApiObjectBase arg1, String arg2) throws IOException {
+        StringBuilder msg = new StringBuilder();
+        msg.append("findByName " + arg0.getName());
+        if (arg1 != null) {
+            msg.append(" parent: " + arg1.getName());
+        }
+        msg.append(" name: " + arg2);
+        s_logger.debug(msg.toString());
+        return _mock.findByName(arg0, arg1, arg2);
+    }
+
+    @Override
+    public <T extends ApiPropertyBase> List<? extends ApiObjectBase> getObjects(
+            Class<? extends ApiObjectBase> arg0, List<ObjectReference<T>> arg1)
+                    throws IOException {
+        s_logger.debug("getObjects" + arg0.getName());
+        return _mock.getObjects(arg0, arg1);
+    }
+
+    @Override
+    public List<? extends ApiObjectBase> list(
+            Class<? extends ApiObjectBase> arg0, List<String> arg1)
+                    throws IOException {
+        s_logger.debug("list" + arg0.getName());
+        return _mock.list(arg0, arg1);
+    }
+
+    @Override
+    public boolean read(ApiObjectBase arg0) throws IOException {
+        s_logger.debug("read " + arg0.getClass().getName() + " id: " + arg0.getUuid());
+        return _mock.read(arg0);
+    }
+
+    @Override
+    public boolean update(ApiObjectBase arg0) throws IOException {
+        s_logger.debug("update " + arg0.getClass().getName() + " id: " + arg0.getUuid());
+        return _spy.update(arg0);
+    }
+
+}


[6/6] git commit: updated refs/heads/master to 6b5fab2

Posted by hu...@apache.org.
OpenContrail network plugin

Signed-off-by: Hugo Trippaers <ht...@schubergphilis.com>


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

Branch: refs/heads/master
Commit: 6b5fab2f5cd939f64b5c9c1ee8d87ca8b6f6514d
Parents: 1e41799
Author: Pedro Marques <ro...@juniper.net>
Authored: Thu Oct 31 17:16:58 2013 -0700
Committer: Hugo Trippaers <ht...@schubergphilis.com>
Committed: Fri Nov 1 17:46:52 2013 +0100

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |   1 +
 client/pom.xml                                  |   5 +
 client/tomcatconf/commands.properties.in        |   3 +
 .../xen/resource/CitrixResourceBase.java        |  13 +-
 .../network-elements/juniper-contrail/pom.xml   | 136 +++
 .../api/command/CreateServiceInstanceCmd.java   | 182 ++++
 .../api/response/ServiceInstanceResponse.java   |  83 ++
 .../contrail/management/ContrailElement.java    |  28 +
 .../management/ContrailElementImpl.java         | 349 +++++++
 .../contrail/management/ContrailGuru.java       | 333 +++++++
 .../contrail/management/ContrailManager.java    |  93 ++
 .../management/ContrailManagerImpl.java         | 769 +++++++++++++++
 .../contrail/management/DBSyncGeneric.java      | 322 +++++++
 .../network/contrail/management/EventUtils.java | 120 +++
 .../management/ManagementNetworkGuru.java       | 114 +++
 .../contrail/management/ModelDatabase.java      |  89 ++
 .../contrail/management/ServerDBSync.java       |  39 +
 .../contrail/management/ServerDBSyncImpl.java   | 965 +++++++++++++++++++
 .../contrail/management/ServerEventHandler.java |  22 +
 .../management/ServerEventHandlerImpl.java      | 251 +++++
 .../contrail/management/ServiceManager.java     |  40 +
 .../contrail/management/ServiceManagerImpl.java | 249 +++++
 .../management/ServiceVirtualMachine.java       |  30 +
 .../network/contrail/model/FloatingIpModel.java | 213 ++++
 .../contrail/model/FloatingIpPoolModel.java     | 170 ++++
 .../network/contrail/model/InstanceIpModel.java | 174 ++++
 .../network/contrail/model/ModelController.java |  85 ++
 .../network/contrail/model/ModelObject.java     | 118 +++
 .../network/contrail/model/ModelObjectBase.java | 111 +++
 .../contrail/model/ServiceInstanceModel.java    | 320 ++++++
 .../contrail/model/VMInterfaceModel.java        | 265 +++++
 .../contrail/model/VirtualMachineModel.java     | 349 +++++++
 .../contrail/model/VirtualNetworkModel.java     | 494 ++++++++++
 .../management/ApiConnectorMockito.java         | 149 +++
 .../IntegrationTestConfiguration.java           | 835 ++++++++++++++++
 .../management/ManagementServerMock.java        | 393 ++++++++
 .../contrail/management/MockAccountManager.java | 372 +++++++
 .../management/NetworkProviderTest.java         | 477 +++++++++
 .../management/ProviderTestConfiguration.java   |  12 +
 .../contrail/management/PublicNetworkTest.java  | 147 +++
 .../PublicNetworkTestConfiguration.java         |  13 +
 .../contrail/management/TestDbSetup.java        | 151 +++
 .../management/VirtualNetworkModelTest.java     |  62 ++
 .../test/resources/commonContext.xml            | 172 ++++
 .../test/resources/contrail.properties          |  19 +
 .../test/resources/db.properties                |  66 ++
 .../test/resources/log4j.properties             |  35 +
 .../test/resources/mysql_db_start.sh            |  51 +
 .../test/resources/mysql_db_stop.sh             |  31 +
 .../test/resources/providerContext.xml          |  16 +
 .../test/resources/publicNetworkContext.xml     |  16 +
 plugins/pom.xml                                 |   1 +
 52 files changed, 9549 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 49f380b..bda3326 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -114,6 +114,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         private static List<Provider> supportedProviders = new ArrayList<Provider>();
 
         public static final Provider VirtualRouter = new Provider("VirtualRouter", false);
+        public static final Provider JuniperContrail = new Provider("JuniperContrail", false);
         public static final Provider JuniperSRX = new Provider("JuniperSRX", true);
         public static final Provider F5BigIp = new Provider("F5BigIp", true);
         public static final Provider Netscaler = new Provider("Netscaler", true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 3e08a9a..b1f7bd5 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -87,6 +87,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-network-contrail</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-plugin-network-ovs</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index e92596c..8cbe972 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -681,3 +681,6 @@ deleteLdapConfiguration=3
 listLdapUsers=3
 ldapCreateAccount=3
 importLdapUsers=3
+
+#### juniper-contrail commands
+createServiceInstance=1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/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 3df28ed..ccb27ea 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
@@ -1072,7 +1072,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
     }
 
-    protected VIF createVif(Connection conn, String vmName, VM vm, NicTO nic) throws XmlRpcException, XenAPIException {
+    protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO vmSpec, NicTO nic) throws XmlRpcException, XenAPIException {
         assert(nic.getUuid() != null) : "Nic should have a uuid value";
 
         if (s_logger.isDebugEnabled()) {
@@ -1087,6 +1087,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         vifr.otherConfig = new HashMap<String, String>();
         vifr.otherConfig.put("nicira-iface-id", nic.getUuid());
         vifr.otherConfig.put("nicira-vm-id", vm.getUuid(conn));
+        // Provide XAPI with the cloudstack vm and nic uids.
+        vifr.otherConfig.put("cloudstack-nic-id", nic.getUuid());
+	if (vmSpec != null) {
+	    vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid()); 
+	}
 
         vifr.network = getNetwork(conn, nic);
 
@@ -1716,7 +1721,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             for (NicTO nic : vmSpec.getNics()) {
-                createVif(conn, vmName, vm, nic);
+                createVif(conn, vmName, vm, vmSpec, nic);
             }
 
             startVM(conn, host, vm, vmName);
@@ -2422,7 +2427,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
                 nic.setDeviceId(Integer.parseInt(vifDeviceNum));
 
-                correctVif = createVif(conn, vmName, router, nic);
+                correctVif = createVif(conn, vmName, router, null, nic);
                 correctVif.plug(conn);
                 // Add iptables rule for network usage
                 networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn));
@@ -8391,7 +8396,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
             String deviceId = getLowestAvailableVIFDeviceNum(conn, vm);
             nic.setDeviceId(Integer.parseInt(deviceId));
-            vif = createVif(conn, vmName, vm, nic);
+            vif = createVif(conn, vmName, vm, null, nic);
             vif.plug(conn);
             return new PlugNicAnswer(cmd, true, "success");
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml
new file mode 100644
index 0000000..22167fe
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/pom.xml
@@ -0,0 +1,136 @@
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-network-contrail</artifactId>
+  <name>Apache CloudStack Plugin - Network Juniper Contrail</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <repositories>
+    <repository>
+      <id>juniper-contrail</id>
+      <url>http://juniper.github.io/contrail-maven/snapshots</url>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-hypervisor-xen</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-network-internallb</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-orchestration</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-schema</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-config</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-events</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${cs.guava.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>net.juniper.contrail</groupId>
+      <artifactId>juniper-contrail-api</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${cs.mysql.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-exec</artifactId>
+        <version>1.1</version>
+    </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-all</artifactId>
+        <version>1.9.5</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+    <testResources>
+      <testResource>
+        <directory>test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <forkMode>always</forkMode>
+          <argLine>-Xmx1024m</argLine>
+	  <excludes>
+	    <exclude>**/NetworkProviderTest.java</exclude>
+	    <exclude>**/PublicNetworkTest.java</exclude>
+	    </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
new file mode 100644
index 0000000..62ab317
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/command/CreateServiceInstanceCmd.java
@@ -0,0 +1,182 @@
+// 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.network.contrail.api.command;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.network.contrail.api.response.ServiceInstanceResponse;
+import org.apache.cloudstack.network.contrail.management.ServiceManager;
+import org.apache.cloudstack.network.contrail.management.ServiceVirtualMachine;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "createServiceInstance",
+    description="Creates a system virtual-machine that implements network services",
+    responseObject=ServiceInstanceResponse.class)
+public class CreateServiceInstanceCmd extends BaseAsyncCreateCmd {
+    private static final String s_name = "createserviceinstanceresponse";
+    
+    /// API parameters
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
+            required = true, description = "Availability zone for the service instance")
+    private Long zoneId;
+
+    //Owner information
+    @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING,
+            description="An optional account for the virtual machine. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+            description="An optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class,
+            description = "Project ID for the service instance")
+    private Long projectId;
+    
+    @Parameter(name = "leftnetworkid", type = CommandType.UUID, entityType = NetworkResponse.class,
+            required = true, description = "The left (inside) network for service instance")
+    private Long leftNetworkId;
+    
+    @Parameter(name = "rightnetworkid", type = CommandType.UUID, entityType = NetworkResponse.class,
+            required = true, description = "The right (outside) network ID for the service instance")
+    private Long rightNetworkId;
+    
+    @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class,
+            required = true, description = "The template ID that specifies the image for the service appliance")
+    private Long templateId;
+    
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID,
+            entityType = ServiceOfferingResponse.class, required = true,
+            description = "The service offering ID that defines the resources consumed by the service appliance")
+    private Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING)
+    private String name;
+    
+    /// Implementation
+    @Inject ServiceManager _vrouterService;
+    @Override
+    public void create() throws ResourceAllocationException {
+        // Parameter validation
+        try {
+            DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find zone ID " + zoneId);
+            }
+            
+            Account owner = _accountService.getActiveAccountById(getEntityOwnerId());
+
+            VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+            if (template == null) {
+                throw new InvalidParameterValueException("Invalid template ID " + templateId);
+            }
+            
+            ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+            if (serviceOffering == null) {
+                throw new InvalidParameterValueException("Invalid service offering ID " + serviceOfferingId);
+            }
+            
+            Network left = _networkService.getNetwork(leftNetworkId);
+            if (left == null) {
+                throw new InvalidParameterValueException("Invalid ID for left network " + leftNetworkId);
+            }
+            
+            Network right = _networkService.getNetwork(rightNetworkId);
+            if (right == null) {
+                throw new InvalidParameterValueException("Invalid ID for right network " + rightNetworkId);
+            }
+
+            ServiceVirtualMachine svm = _vrouterService.createServiceInstance(zone, owner, template, serviceOffering,
+                                                                              name, left, right);
+            if (svm == null) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to create service instance");
+            }
+            setEntityId(svm.getId());
+            setEntityUuid(svm.getUuid());
+        } catch (Exception ex) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Create service instance";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException,
+            InsufficientCapacityException, ServerApiException,
+            ConcurrentOperationException, ResourceAllocationException,
+            NetworkRuleConflictException {
+        try {
+            _vrouterService.startServiceInstance(getEntityId());
+            ServiceInstanceResponse response = _vrouterService.createServiceInstanceResponse(getEntityId());
+            response.setObjectName("serviceinstance");
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } catch (Exception ex) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
new file mode 100644
index 0000000..6b17351
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/api/response/ServiceInstanceResponse.java
@@ -0,0 +1,83 @@
+// 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.network.contrail.api.response;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.response.ControlledEntityResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class ServiceInstanceResponse extends BaseResponse implements
+        ControlledEntityResponse {
+    
+    @SerializedName(ApiConstants.ID) @Param(description="the ID of the virtual machine")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME) @Param(description="the name of the virtual machine")
+    private String name;
+
+    @SerializedName("displayname") @Param(description="user generated name. The name of the virtual machine is returned if no displayname exists.")
+    private String displayName;
+
+    @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account associated with the virtual machine")
+    private String accountName;
+
+    @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the vm")
+    private String projectId;
+
+    @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the vm")
+    private String projectName;
+
+    @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the ID of the domain in which the virtual machine exists")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN) @Param(description="the name of the domain in which the virtual machine exists")
+    private String domainName;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    @Override
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java
new file mode 100644
index 0000000..28680df
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElement.java
@@ -0,0 +1,28 @@
+// 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.network.contrail.management;
+
+import com.cloud.utils.component.PluggableService;
+
+// Network Provider plugin
+public interface ContrailElement extends PluggableService {
+    /**
+     * TODO:
+     * define APIs to configure the Network Virtualization service.
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
new file mode 100644
index 0000000..dfbe7d3
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java
@@ -0,0 +1,349 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.network.contrail.api.command.CreateServiceInstanceCmd;
+import org.apache.cloudstack.network.contrail.model.InstanceIpModel;
+import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.NetworkACLServiceProvider;
+import com.cloud.network.element.SourceNatServiceProvider;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.VpcProvider;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRouteProfile;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.network.IpAddress;
+
+@Component
+@Local(value = {ContrailElement.class, StaticNatServiceProvider.class})
+public class ContrailElementImpl extends AdapterBase
+    implements ContrailElement, IpDeployer, StaticNatServiceProvider {
+
+	private static final Map<Service, Map<Capability, String>> _capabilities = InitCapabilities();
+
+	@Inject ContrailManager _manager;
+	@Inject NicDao _nicDao;
+	@Inject ServerDBSync  _dbSync;
+	private static final Logger s_logger =
+			Logger.getLogger(ContrailElement.class);
+	
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+    	s_logger.debug("configure");
+    	return true;
+    }
+
+    // PluggableService
+    @Override
+    public List<Class<?>> getCommands() {
+    	List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateServiceInstanceCmd.class);
+        return cmdList;
+    }
+
+    // NetworkElement API
+    @Override
+    public Provider getProvider() {
+        return Provider.JuniperContrail;
+    }
+
+    private static Map<Service, Map<Capability, String>> InitCapabilities() {
+    	Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+    	capabilities.put(Service.Connectivity, null);
+    	capabilities.put(Service.Dhcp, new HashMap<Capability, String>());
+        capabilities.put(Service.StaticNat, null);
+        capabilities.put(Service.SourceNat, null);
+
+    	return capabilities;
+    }
+
+	@Override
+	public Map<Service, Map<Capability, String>> getCapabilities() {
+		return _capabilities;
+	}
+
+	/**
+	 * Network add/update.
+	 */
+	@Override
+	public boolean implement(Network network, NetworkOffering offering,
+			DeployDestination dest, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException,
+			InsufficientCapacityException {
+	    s_logger.debug("NetworkElement implement: " + network.getName() + ", traffic type: " + network.getTrafficType());
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        s_logger.debug("ignore network " + network.getName());
+	        return true;        
+	    }
+	    VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+	            _manager.getCanonicalName(network), network.getTrafficType());
+
+	    if (vnModel == null) {
+	        vnModel = new VirtualNetworkModel(network, network.getUuid(), 
+	                _manager.getCanonicalName(network), network.getTrafficType());
+	        vnModel.setProperties(_manager.getModelController(), network);
+	    }
+	    try {
+	        if (!vnModel.verify(_manager.getModelController())) {
+	            vnModel.update(_manager.getModelController());
+	        }
+	        _manager.getDatabase().getVirtualNetworks().add(vnModel);   
+	    } catch (Exception ex) {
+	        s_logger.warn("virtual-network update: ", ex);
+	    }
+	    return true;
+	}
+
+	@Override
+	public boolean prepare(Network network, NicProfile nicProfile,
+			VirtualMachineProfile vm,
+			DeployDestination dest, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException,
+			InsufficientCapacityException {
+
+	    s_logger.debug("NetworkElement prepare: " + network.getName() + ", traffic type: " + network.getTrafficType());
+
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        s_logger.debug("ignore network " + network.getName());
+	        return true;
+	    }
+
+	    s_logger.debug("network: " + network.getId());
+	    
+	    VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+                _manager.getCanonicalName(network), network.getTrafficType());
+	    
+	    if (vnModel == null) {
+	        // There is no notification after a physical network is associated with the VRouter NetworkOffering
+	        // this may be the first time we see this network.
+	        return false;
+	    }
+
+	    VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+	    if (vmModel == null) {
+	        VMInstanceVO vmVo = (VMInstanceVO) vm.getVirtualMachine();
+	        vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
+	        vmModel.setProperties(_manager.getModelController(), vmVo);
+	    }
+
+	    NicVO nic = _nicDao.findById(nicProfile.getId());
+	    assert nic != null;
+
+	    VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+	    if (vmiModel == null) {
+	        vmiModel = new VMInterfaceModel(nic.getUuid());
+	        vmiModel.addToVirtualMachine(vmModel);	
+                vmiModel.addToVirtualNetwork(vnModel);          
+	    }
+	    
+	    try {
+	        vmiModel.build(_manager.getModelController(), (VMInstanceVO) vm.getVirtualMachine(), nic);
+	    } catch (IOException ex) {
+	        s_logger.warn("vm interface set", ex);
+	        return false;
+	    }
+
+	    InstanceIpModel ipModel = vmiModel.getInstanceIp();
+	    if (ipModel == null) {
+	        ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
+	        ipModel.addToVMInterface(vmiModel);
+	    }
+	    ipModel.setAddress(nicProfile.getIp4Address());
+
+	    try {
+	        vmModel.update(_manager.getModelController());
+	    } catch (Exception ex) {
+	        s_logger.warn("virtual-machine-update", ex);
+	        return false;
+	    }
+	    _manager.getDatabase().getVirtualMachines().add(vmModel);   
+
+	    return true;
+	}
+
+	@Override
+	public boolean release(Network network, NicProfile nicProfile,
+			VirtualMachineProfile vm,
+			ReservationContext context) throws ConcurrentOperationException,
+			ResourceUnavailableException {
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        return true;
+	    } else if (!_manager.isManagedPhysicalNetwork(network)) {
+	        s_logger.debug("release ignore network " + network.getId());
+	        return true;
+	    }
+
+	    NicVO nic = _nicDao.findById(nicProfile.getId());
+	    assert nic != null;
+
+	    VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+	    if (vmModel == null) {
+	        s_logger.debug("vm " + vm.getInstanceName() + " not in local database");
+	        return true;
+	    }
+	    VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+	    if (vmiModel != null) {
+	        try {
+	            vmiModel.destroy(_manager.getModelController());
+	        } catch (IOException ex) {
+	            s_logger.warn("virtual-machine-interface delete", ex);
+	        }
+	        vmModel.removeSuccessor(vmiModel);
+	    }
+
+	    if (!vmModel.hasDescendents()) {
+	        _manager.getDatabase().getVirtualMachines().remove(vmModel);
+	        try {
+	            vmModel.delete(_manager.getModelController());
+	        } catch (IOException e) {
+	            return false;
+	        }
+	    }
+
+	    return true;
+	}
+
+	/**
+	 * Network disable
+	 */
+	@Override
+	public boolean shutdown(Network network, ReservationContext context,
+			boolean cleanup) throws ConcurrentOperationException,
+			ResourceUnavailableException {
+		s_logger.debug("NetworkElement shutdown");
+		return true;
+	}
+
+	/**
+	 * Network delete
+	 */
+	@Override
+	public boolean destroy(Network network, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		s_logger.debug("NetworkElement destroy");
+		return true;
+	}
+
+	@Override
+	public boolean isReady(PhysicalNetworkServiceProvider provider) {
+		return true;
+	}
+
+	@Override
+	public boolean shutdownProviderInstances(
+			PhysicalNetworkServiceProvider provider, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		s_logger.debug("NetworkElement shutdown ProviderInstances");
+		return true;
+	}
+
+	@Override
+	public boolean canEnableIndividualServices() {
+		return true;
+	}
+
+	@Override
+	public boolean verifyServicesCombination(Set<Service> services) {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement verifyServices");
+		s_logger.debug("Services: " + services);
+		return true;
+	}
+
+
+    @Override
+    public IpDeployer getIpDeployer(Network network) {
+	return this;
+    }
+
+    @Override
+    public boolean applyIps(Network network,
+            List<? extends PublicIpAddress> ipAddress, Set<Service> services)
+                    throws ResourceUnavailableException {
+
+        for (PublicIpAddress ip: ipAddress) {
+            if (ip.isSourceNat()) {
+                continue;
+            }
+            if (isFloatingIpCreate(ip)) {
+                if (_manager.createFloatingIp(ip)) {
+                    s_logger.debug("Successfully created floating ip: " + ip.getAddress().addr());
+                }
+            } else {
+                if (_manager.deleteFloatingIp(ip)) {
+                    s_logger.debug("Successfully deleted floating ip: " + ip.getAddress().addr());
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNats(Network config,
+            List<? extends StaticNat> rules)
+                    throws ResourceUnavailableException {
+        return true;
+    }
+    
+    private boolean isFloatingIpCreate(PublicIpAddress ip) {        
+        if (ip.getState() == IpAddress.State.Allocated && ip.getAssociatedWithVmId() != null && !ip.isSourceNat()) {
+            return true;
+        }
+        return false;        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
new file mode 100644
index 0000000..ca53f41
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java
@@ -0,0 +1,333 @@
+// 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.network.contrail.management;
+
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+
+import net.juniper.contrail.api.types.MacAddressesType;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+
+import org.apache.cloudstack.network.contrail.model.InstanceIpModel;
+import org.apache.cloudstack.network.contrail.model.VMInterfaceModel;
+import org.apache.cloudstack.network.contrail.model.VirtualMachineModel;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.NicVO;
+
+@Component
+public class ContrailGuru extends AdapterBase implements NetworkGuru {
+    @Inject NetworkDao _networkDao;
+    @Inject ContrailManager _manager;
+    @Inject NicDao _nicDao;
+
+    private static final Logger s_logger = Logger.getLogger(ContrailGuru.class);
+    private static final TrafficType[] _trafficTypes = {TrafficType.Guest};
+
+    private boolean canHandle(NetworkOffering offering) {
+        return (offering.getName().equals(ContrailManager.offeringName));
+    }
+
+    @Override
+    public String getName() {
+	return "ContrailGuru";
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan,
+            Network userSpecified, Account owner) {
+        if (!canHandle(offering)) {
+            return null;
+        }
+        NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch,
+                offering.getId(), State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId());
+        if (userSpecified.getCidr() != null) {
+            network.setCidr(userSpecified.getCidr());
+            network.setGateway(userSpecified.getGateway());
+        }
+        s_logger.debug("Allocated network " + userSpecified.getName() +
+                (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
+        return network;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering,
+            DeployDestination destination, ReservationContext context)
+                    throws InsufficientVirtualNetworkCapcityException {
+        s_logger.debug("Implement network: " + network.getName() + ", traffic type: " + network.getTrafficType());
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(
+                network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            vnModel = new VirtualNetworkModel(network, network.getUuid(), 
+                    _manager.getCanonicalName(network), network.getTrafficType());
+            vnModel.setProperties(_manager.getModelController(), network);
+        }
+
+        try {
+            if (!vnModel.verify(_manager.getModelController())) {
+                vnModel.update(_manager.getModelController());
+            }
+        } catch (Exception ex) {
+            s_logger.warn("virtual-network update: ", ex);
+            return network;
+        }
+        _manager.getDatabase().getVirtualNetworks().add(vnModel);   
+        return network;
+    }
+
+    /**
+     * Allocate the NicProfile object.
+     * At this point the UUID of the nic is not yet known. We defer allocating the VMI and instance-ip objects
+     * until the reserve API is called because of this reason. 
+     */
+    @Override
+    public NicProfile allocate(Network network, NicProfile profile,
+            VirtualMachineProfile vm)
+                    throws InsufficientVirtualNetworkCapcityException,
+                    InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("allocate NicProfile on " + network.getName());
+
+        if (profile != null && profile.getRequestedIpv4() != null) {
+            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + profile);
+        }
+        if (profile == null) {
+            profile = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        }
+
+        profile.setStrategy(ReservationStrategy.Start);
+        
+        return profile;
+    }
+
+    /**
+     * Allocate the ip address (and mac) for the specified VM device.
+     */
+    @Override
+    public void reserve(NicProfile nic, Network network,
+            VirtualMachineProfile vm,
+            DeployDestination dest, ReservationContext context)
+                    throws InsufficientVirtualNetworkCapcityException,
+                    InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("reserve NicProfile on network id: " + network.getId() +
+                " " + network.getName());
+        s_logger.debug("deviceId: " + nic.getDeviceId());
+
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(
+                network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        /* Network must have been implemented */
+        assert vnModel != null;
+        
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            VMInstanceVO vmVo = (VMInstanceVO) vm.getVirtualMachine();
+            vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
+            vmModel.setProperties(_manager.getModelController(), vmVo);
+        }
+
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            vmiModel = new VMInterfaceModel(nicVO.getUuid());
+            vmiModel.addToVirtualMachine(vmModel);
+            vmiModel.addToVirtualNetwork(vnModel);
+        }
+        try {
+            vmiModel.build(_manager.getModelController(), (VMInstanceVO) vm.getVirtualMachine(), nicVO);
+            vmiModel.setActive();
+        } catch (IOException ex) {
+            s_logger.error("virtual-machine-interface set", ex);
+            return;
+        }
+
+        InstanceIpModel ipModel = vmiModel.getInstanceIp();
+        if (ipModel == null) {
+            ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
+            ipModel.addToVMInterface(vmiModel);
+        } else {
+            s_logger.debug("Reuse existing instance-ip object on " + ipModel.getName());
+        }
+        if (nic.getIp4Address() != null) {
+            s_logger.debug("Nic using existing IP address " +  nic.getIp4Address());
+            ipModel.setAddress(nic.getIp4Address());
+        }
+
+        try {
+            vmModel.update(_manager.getModelController());
+        } catch (Exception ex) {
+            s_logger.warn("virtual-machine update", ex);
+            return;
+        }
+
+        _manager.getDatabase().getVirtualMachines().add(vmModel);   
+
+        VirtualMachineInterface vmi = vmiModel.getVMInterface();
+        // allocate mac address
+        if (nic.getMacAddress() == null) {
+            MacAddressesType macs = vmi.getMacAddresses();
+            if (macs == null) {
+                s_logger.debug("no mac address is allocated for Nic " + nicVO.getUuid());
+            } else {
+                s_logger.info("VMI " + _manager.getVifNameByVmUuid(vm.getUuid(), nicVO.getDeviceId()) + " got mac address: " +
+                        macs.getMacAddress().get(0));
+                nic.setMacAddress(macs.getMacAddress().get(0));
+            }
+        }
+
+        if (nic.getIp4Address() == null) {
+            s_logger.debug("Allocated IP address " + ipModel.getAddress());
+            nic.setIp4Address(ipModel.getAddress());
+            nic.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
+            nic.setGateway(network.getGateway());
+            nic.setFormat(AddressFormat.Ip4);
+        }
+    }
+
+    /**
+     * When a VM is stopped this API is called to release transient resources.
+     */
+    @Override
+    public boolean release(NicProfile nic,
+            VirtualMachineProfile vm,
+            String reservationId) {
+
+        s_logger.debug("release NicProfile " + nic.getId());
+
+        return true;
+    }
+
+    /**
+     * Release permanent resources of a Nic (VMI and addresses).
+     */
+    @Override
+    public void deallocate(Network network, NicProfile nic,
+            VirtualMachineProfile vm) {
+        s_logger.debug("deallocate NicProfile " + nic.getId() + " on " + network.getName());
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            return;
+        }
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            return;
+        }
+        try {
+            vmiModel.destroy(_manager.getModelController());
+        } catch (IOException ex) {
+            return;
+        }
+        vmModel.removeSuccessor(vmiModel);
+        
+        if (!vmModel.hasDescendents()) {
+            _manager.getDatabase().getVirtualMachines().remove(vmModel);
+            try {
+                vmModel.delete(_manager.getModelController());
+            } catch (IOException ex) {
+                s_logger.warn("virtual-machine delete", ex);
+                return;
+            }
+        }
+
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        // TODO Auto-generated method stub
+        s_logger.debug("update NicProfile " + profile.getId() + " on " + network.getName());
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering)  {
+        s_logger.debug("NetworkGuru shutdown");
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+                _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            return;
+        }
+        try {
+            vnModel.delete(_manager.getModelController());
+        } catch (IOException e) {
+            s_logger.warn("virtual-network delete", e);
+        }
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru trash");
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru updateNetworkProfile");
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return _trafficTypes;
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : _trafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java
new file mode 100644
index 0000000..b96b00c
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java
@@ -0,0 +1,93 @@
+// 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.network.contrail.management;
+
+import java.util.List;
+import java.io.IOException;
+
+import org.apache.cloudstack.network.contrail.model.ModelController;
+import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.types.FloatingIp;
+import net.juniper.contrail.api.types.VirtualNetwork;
+
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.domain.DomainVO;
+import com.cloud.projects.ProjectVO;
+
+public interface ContrailManager {
+    public static final String offeringName = "Juniper Contrail offering";
+    public static final String offeringDisplayText = "Juniper Contrail network offering";
+    public static final int DB_SYNC_INTERVAL_DEFAULT = 600000;
+    public static final String VNC_ROOT_DOMAIN = "default-domain";
+    public static final String VNC_DEFAULT_PROJECT = "default-project";
+    public static final String managementNetworkName = "ip-fabric";
+
+    public NetworkOffering getOffering();
+    public void syncNetworkDB(short syncMode) throws IOException;
+
+    public boolean isManagedPhysicalNetwork(Network network);
+
+    /**
+     * Lookup the virtual network that implements the CloudStack network object.
+     * @param net_id internal identifier of the NetworkVO object.
+     * @return the uuid of the virtual network that corresponds to the
+     * specified CloudStack network.
+     */
+    public String findVirtualNetworkId(Network net) throws IOException;
+    public void findInfrastructureNetworks(PhysicalNetworkVO phys, List<NetworkVO> dbList);
+    public String getPhysicalNetworkName(PhysicalNetworkVO phys_net);
+    public String getCanonicalName(Network net);
+    public String getDomainCanonicalName(DomainVO domain);
+    public String getProjectCanonicalName(ProjectVO project);
+    public String getFQN(Network net);
+    public String getDomainName(long domainId);
+    public String getProjectName(long accountId);
+    public String getDefaultPublicNetworkFQN();
+    public String getProjectId(long domainId, long accountId) throws IOException;
+    public net.juniper.contrail.api.types.Project getVncProject(long domainId, long accountId) throws IOException;
+    public boolean isSystemRootDomain(net.juniper.contrail.api.types.Domain vnc);
+    public boolean isSystemRootDomain(DomainVO domain);
+    public boolean isSystemDefaultProject(net.juniper.contrail.api.types.Project project);
+    public boolean isSystemDefaultProject(ProjectVO project);
+    public boolean isSystemDefaultNetwork(VirtualNetwork vnet);
+    public boolean isSystemDefaultNetwork(NetworkVO dbNet);
+    public String getVifNameByVmName(String vm_name, Integer device_id);
+    public String getVifNameByVmUuid(String vm_uuid, Integer device_id);
+    
+    public ApiConnector getApiConnector();
+    public ModelDatabase getDatabase();
+    public ModelController getModelController(); 
+    public List<NetworkVO> findJuniperManagedNetworks(List<TrafficType> types);
+    public List<IPAddressVO> findJuniperManagedPublicIps();
+    public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType)
+            throws IOException;
+    public List<FloatingIp> getFloatingIps();
+    public VirtualNetworkModel lookupPublicNetworkModel();
+    public void createPublicNetworks();
+    public boolean createFloatingIp(PublicIpAddress ip);
+    public boolean deleteFloatingIp(PublicIpAddress ip);
+}
+  


[2/6] OpenContrail network plugin

Posted by hu...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
new file mode 100644
index 0000000..7c8d516
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java
@@ -0,0 +1,835 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.IpAddress;
+
+import org.apache.cloudstack.acl.APIChecker;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.affinity.AffinityGroupService;
+import org.apache.cloudstack.affinity.AffinityGroupVO;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl;
+import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl;
+import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl;
+import org.apache.cloudstack.api.IdentityService;
+import org.apache.cloudstack.engine.service.api.OrchestrationService;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
+import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
+import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
+import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl;
+import org.apache.cloudstack.query.QueryService;
+import org.apache.cloudstack.region.PortableIpDaoImpl;
+import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
+import org.apache.cloudstack.region.RegionManager;
+import org.apache.cloudstack.region.dao.RegionDaoImpl;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
+import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl;
+import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl;
+import org.apache.cloudstack.usage.UsageService;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.ComponentScan.Filter;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.FilterType;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.core.type.filter.TypeFilter;
+
+import com.cloud.acl.DomainChecker;
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.manager.allocator.HostAllocator;
+import com.cloud.agent.manager.allocator.PodAllocator;
+import com.cloud.alert.AlertManager;
+import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.AccountJoinDaoImpl;
+import com.cloud.api.query.dao.AffinityGroupJoinDaoImpl;
+import com.cloud.api.query.dao.AsyncJobJoinDaoImpl;
+import com.cloud.api.query.dao.DataCenterJoinDaoImpl;
+import com.cloud.api.query.dao.DiskOfferingJoinDaoImpl;
+import com.cloud.api.query.dao.DomainRouterJoinDaoImpl;
+import com.cloud.api.query.dao.HostJoinDaoImpl;
+import com.cloud.api.query.dao.ImageStoreJoinDaoImpl;
+import com.cloud.api.query.dao.InstanceGroupJoinDaoImpl;
+import com.cloud.api.query.dao.ProjectAccountJoinDaoImpl;
+import com.cloud.api.query.dao.ProjectInvitationJoinDaoImpl;
+import com.cloud.api.query.dao.ProjectJoinDaoImpl;
+import com.cloud.api.query.dao.ResourceTagJoinDaoImpl;
+import com.cloud.api.query.dao.SecurityGroupJoinDaoImpl;
+import com.cloud.api.query.dao.ServiceOfferingJoinDaoImpl;
+import com.cloud.api.query.dao.StoragePoolJoinDaoImpl;
+import com.cloud.api.query.dao.TemplateJoinDaoImpl;
+import com.cloud.api.query.dao.UserAccountJoinDaoImpl;
+import com.cloud.api.query.dao.UserVmJoinDaoImpl;
+import com.cloud.api.query.dao.VolumeJoinDaoImpl;
+import com.cloud.capacity.CapacityManager;
+import com.cloud.capacity.dao.CapacityDaoImpl;
+import com.cloud.cluster.ClusterManager;
+import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl;
+import com.cloud.cluster.dao.ManagementServerHostDaoImpl;
+import com.cloud.configuration.ConfigurationManagerImpl;
+
+import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl;
+
+import com.cloud.configuration.dao.ResourceCountDaoImpl;
+import com.cloud.configuration.dao.ResourceLimitDaoImpl;
+import com.cloud.consoleproxy.ConsoleProxyManager;
+import com.cloud.consoleproxy.ConsoleProxyService;
+import com.cloud.dc.ClusterDetailsDaoImpl;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.dao.AccountVlanMapDaoImpl;
+import com.cloud.dc.dao.ClusterDaoImpl;
+import com.cloud.dc.dao.DataCenterDaoImpl;
+import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
+import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl;
+import com.cloud.dc.dao.DataCenterVnetDaoImpl;
+import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl;
+import com.cloud.dc.dao.DedicatedResourceDaoImpl;
+import com.cloud.dc.dao.HostPodDaoImpl;
+import com.cloud.dc.dao.PodVlanDaoImpl;
+import com.cloud.dc.dao.PodVlanMapDaoImpl;
+import com.cloud.dc.dao.VlanDaoImpl;
+import com.cloud.deploy.DeploymentPlanner;
+import com.cloud.deploy.DeploymentPlanningManager;
+import com.cloud.deploy.dao.PlannerHostReservationDaoImpl;
+import com.cloud.domain.dao.DomainDaoImpl;
+import com.cloud.event.dao.EventDaoImpl;
+import com.cloud.event.dao.EventJoinDaoImpl;
+import com.cloud.event.dao.UsageEventDaoImpl;
+import com.cloud.ha.HighAvailabilityManager;
+import com.cloud.host.dao.HostDaoImpl;
+import com.cloud.host.dao.HostDetailsDaoImpl;
+import com.cloud.host.dao.HostTagsDaoImpl;
+import com.cloud.hypervisor.HypervisorGuruManagerImpl;
+import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl;
+import com.cloud.network.ExternalDeviceUsageManager;
+import com.cloud.network.Ipv6AddressManagerImpl;
+import com.cloud.network.NetworkModelImpl;
+import com.cloud.network.NetworkServiceImpl;
+import com.cloud.network.NetworkUsageService;
+import com.cloud.network.StorageNetworkManager;
+import com.cloud.network.StorageNetworkService;
+import com.cloud.network.as.AutoScaleService;
+import com.cloud.network.as.dao.AutoScalePolicyConditionMapDaoImpl;
+import com.cloud.network.as.dao.AutoScalePolicyDaoImpl;
+import com.cloud.network.as.dao.AutoScaleVmGroupDaoImpl;
+import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDaoImpl;
+import com.cloud.network.as.dao.AutoScaleVmProfileDaoImpl;
+import com.cloud.network.as.dao.ConditionDaoImpl;
+import com.cloud.network.as.dao.CounterDaoImpl;
+import com.cloud.network.dao.AccountGuestVlanMapDaoImpl;
+import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
+import com.cloud.network.dao.FirewallRulesDaoImpl;
+import com.cloud.network.dao.LBHealthCheckPolicyDaoImpl;
+import com.cloud.network.dao.LBStickinessPolicyDaoImpl;
+import com.cloud.network.dao.LoadBalancerDaoImpl;
+import com.cloud.network.dao.LoadBalancerVMMapDaoImpl;
+import com.cloud.network.dao.NetworkAccountDaoImpl;
+import com.cloud.network.dao.NetworkDaoImpl;
+import com.cloud.network.dao.NetworkDomainDaoImpl;
+import com.cloud.network.dao.NetworkOpDaoImpl;
+import com.cloud.network.dao.NetworkRuleConfigDaoImpl;
+import com.cloud.network.dao.NetworkServiceMapDaoImpl;
+import com.cloud.network.dao.PhysicalNetworkDaoImpl;
+import com.cloud.network.dao.PhysicalNetworkServiceProviderDaoImpl;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl;
+import com.cloud.network.dao.RemoteAccessVpnDaoImpl;
+import com.cloud.network.dao.RouterNetworkDaoImpl;
+import com.cloud.network.dao.Site2SiteCustomerGatewayDaoImpl;
+import com.cloud.network.dao.Site2SiteVpnConnectionDaoImpl;
+import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl;
+import com.cloud.network.dao.UserIpv6AddressDaoImpl;
+import com.cloud.network.dao.VirtualRouterProviderDaoImpl;
+import com.cloud.network.dao.VpnUserDaoImpl;
+import com.cloud.network.element.Site2SiteVpnServiceProvider;
+import com.cloud.network.firewall.FirewallManagerImpl;
+import com.cloud.network.lb.LoadBalancingRulesManagerImpl;
+import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
+import com.cloud.network.rules.RulesManagerImpl;
+import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl;
+import com.cloud.network.security.dao.SecurityGroupDaoImpl;
+import com.cloud.network.security.dao.SecurityGroupRuleDaoImpl;
+import com.cloud.network.security.dao.SecurityGroupRulesDaoImpl;
+import com.cloud.network.security.dao.SecurityGroupVMMapDaoImpl;
+import com.cloud.network.security.dao.SecurityGroupWorkDaoImpl;
+import com.cloud.network.security.dao.VmRulesetLogDaoImpl;
+import com.cloud.network.vpc.NetworkACLManagerImpl;
+import com.cloud.network.vpc.NetworkACLService;
+import com.cloud.network.vpc.VpcManagerImpl;
+import com.cloud.network.vpc.dao.NetworkACLDaoImpl;
+import com.cloud.network.vpc.dao.NetworkACLItemDaoImpl;
+import com.cloud.network.vpc.dao.PrivateIpDaoImpl;
+import com.cloud.network.vpc.dao.StaticRouteDaoImpl;
+import com.cloud.network.vpc.dao.VpcDaoImpl;
+import com.cloud.network.vpc.dao.VpcGatewayDaoImpl;
+import com.cloud.network.vpc.dao.VpcOfferingDaoImpl;
+import com.cloud.network.vpc.dao.VpcOfferingServiceMapDaoImpl;
+import com.cloud.network.vpc.dao.VpcServiceMapDaoImpl;
+import com.cloud.network.vpn.RemoteAccessVpnService;
+import com.cloud.network.vpn.Site2SiteVpnManager;
+import com.cloud.projects.dao.ProjectInvitationDaoImpl;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.offerings.dao.NetworkOfferingDaoImpl;
+import com.cloud.offerings.dao.NetworkOfferingDao;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl;
+import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl;
+import com.cloud.projects.ProjectManager;
+import com.cloud.projects.dao.ProjectAccountDaoImpl;
+import com.cloud.projects.ProjectManagerImpl;
+import com.cloud.projects.dao.ProjectDaoImpl;
+import com.cloud.region.ha.GlobalLoadBalancingRulesService;
+import com.cloud.resource.ResourceManager;
+import com.cloud.server.ConfigurationServerImpl;
+import com.cloud.server.ManagementServer;
+import com.cloud.server.ResourceMetaDataService;
+import com.cloud.server.StatsCollector;
+import com.cloud.server.TaggedResourceService;
+import com.cloud.server.auth.UserAuthenticator;
+import com.cloud.service.dao.ServiceOfferingDaoImpl;
+import com.cloud.service.dao.ServiceOfferingDetailsDaoImpl;
+import com.cloud.storage.DataStoreProviderApiService;
+import com.cloud.storage.StorageManager;
+import com.cloud.storage.dao.DiskOfferingDaoImpl;
+import com.cloud.storage.dao.GuestOSCategoryDaoImpl;
+import com.cloud.storage.dao.GuestOSDaoImpl;
+import com.cloud.storage.dao.LaunchPermissionDao;
+import com.cloud.storage.dao.SnapshotDaoImpl;
+import com.cloud.storage.dao.SnapshotPolicyDaoImpl;
+import com.cloud.storage.dao.StoragePoolDetailsDaoImpl;
+import com.cloud.storage.dao.StoragePoolHostDaoImpl;
+import com.cloud.storage.dao.UploadDaoImpl;
+import com.cloud.storage.dao.VMTemplateDaoImpl;
+import com.cloud.storage.dao.VMTemplateDetailsDaoImpl;
+import com.cloud.storage.dao.VMTemplateHostDaoImpl;
+import com.cloud.storage.dao.VMTemplateZoneDaoImpl;
+import com.cloud.storage.dao.VolumeDaoImpl;
+import com.cloud.storage.dao.VolumeHostDaoImpl;
+import com.cloud.storage.secondary.SecondaryStorageVmManager;
+import com.cloud.storage.snapshot.SnapshotApiService;
+import com.cloud.storage.snapshot.SnapshotManager;
+import com.cloud.storage.VolumeApiService;
+import com.cloud.tags.dao.ResourceTagDao;
+import com.cloud.tags.dao.ResourceTagsDaoImpl;
+import com.cloud.template.TemplateApiService;
+import com.cloud.template.TemplateManager;
+import com.cloud.user.Account;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.user.AccountDetailsDaoImpl;
+import com.cloud.user.AccountVO;
+import com.cloud.user.DomainManagerImpl;
+import com.cloud.user.ResourceLimitService;
+import com.cloud.user.dao.AccountDaoImpl;
+import com.cloud.user.dao.SSHKeyPairDaoImpl;
+import com.cloud.user.dao.UserDaoImpl;
+import com.cloud.user.dao.UserStatisticsDaoImpl;
+import com.cloud.user.dao.UserStatsLogDaoImpl;
+import com.cloud.user.dao.VmDiskStatisticsDaoImpl;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+import com.cloud.uuididentity.dao.IdentityDaoImpl;
+import com.cloud.vm.ItWorkDaoImpl;
+import com.cloud.vm.dao.ConsoleProxyDaoImpl;
+import com.cloud.vm.dao.DomainRouterDaoImpl;
+import com.cloud.vm.dao.InstanceGroupDaoImpl;
+import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl;
+import com.cloud.vm.dao.NicIpAliasDaoImpl;
+import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
+import com.cloud.vm.dao.SecondaryStorageVmDaoImpl;
+import com.cloud.vm.dao.UserVmCloneSettingDaoImpl;
+import com.cloud.vm.dao.UserVmDaoImpl;
+import com.cloud.vm.dao.UserVmDetailsDaoImpl;
+import com.cloud.vm.dao.VMInstanceDaoImpl;
+import com.cloud.vm.snapshot.VMSnapshotManager;
+import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl;
+
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobDaoImpl;
+import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
+
+import com.cloud.network.IpAddressManagerImpl;
+
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.jobs.dao.SyncQueueItemDaoImpl;
+import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJournalDaoImpl;
+import org.apache.cloudstack.framework.jobs.dao.AsyncJobJoinMapDaoImpl;
+import org.apache.cloudstack.framework.jobs.AsyncJobDispatcher;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor;
+import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
+import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager;
+import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService;
+import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService;
+
+import com.cloud.utils.db.EntityManager;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.network.contrail.management.ContrailElementImpl;
+import org.apache.cloudstack.network.contrail.management.ContrailGuru;
+import org.apache.cloudstack.network.contrail.management.ContrailManagerImpl;
+import org.apache.cloudstack.network.contrail.management.EventUtils;
+import org.apache.cloudstack.network.contrail.management.ServerEventHandlerImpl;
+
+
+@ComponentScan(basePackageClasses={
+        AccountDaoImpl.class,
+        AccountDetailsDaoImpl.class,
+        AccountGuestVlanMapDaoImpl.class,
+        AccountJoinDaoImpl.class,
+        AccountVlanMapDaoImpl.class,
+        AffinityGroupDaoImpl.class,
+        AffinityGroupDomainMapDaoImpl.class,
+        AffinityGroupJoinDaoImpl.class,
+        AffinityGroupVMMapDaoImpl.class,
+        ApiDBUtils.class,
+        ApplicationLoadBalancerRuleDaoImpl.class,
+        AsyncJobDaoImpl.class,
+        AsyncJobJoinDaoImpl.class,
+        AsyncJobJoinMapDaoImpl.class,
+        AsyncJobJournalDaoImpl.class,
+        AsyncJobManagerImpl.class,
+        AutoScalePolicyConditionMapDaoImpl.class,
+        AutoScalePolicyDaoImpl.class,
+        AutoScaleVmGroupDaoImpl.class,
+        AutoScaleVmGroupPolicyMapDaoImpl.class,
+        AutoScaleVmProfileDaoImpl.class,
+        CapacityDaoImpl.class,
+        ClusterDaoImpl.class,
+        ClusterDetailsDaoImpl.class,
+        ConditionDaoImpl.class,
+        ConfigurationDaoImpl.class,
+        ConfigurationManagerImpl.class,
+        ConfigurationServerImpl.class,
+        ConsoleProxyDaoImpl.class,
+        ContrailElementImpl.class,
+        ContrailGuru.class,
+        ContrailManagerImpl.class,
+        CounterDaoImpl.class,
+        DataCenterDaoImpl.class,
+        DataCenterIpAddressDaoImpl.class,
+        DataCenterJoinDaoImpl.class,
+        DataCenterLinkLocalIpAddressDaoImpl.class,
+        DataCenterVnetDaoImpl.class,
+        DcDetailsDaoImpl.class,
+        DedicatedResourceDaoImpl.class,
+        DiskOfferingDaoImpl.class,
+        DiskOfferingJoinDaoImpl.class,
+        DomainDaoImpl.class,
+        DomainManagerImpl.class,
+        DomainRouterDaoImpl.class,
+        DomainRouterJoinDaoImpl.class,
+        EventDaoImpl.class,
+        EventJoinDaoImpl.class,
+        EventUtils.class,
+        EventUtils.class,
+        FirewallManagerImpl.class,
+        FirewallRulesCidrsDaoImpl.class,
+        FirewallRulesDaoImpl.class,
+        GuestOSCategoryDaoImpl.class,
+        GuestOSDaoImpl.class,
+        HostDaoImpl.class,
+        HostDetailsDaoImpl.class,
+        HostJoinDaoImpl.class,
+        HostPodDaoImpl.class,
+        HostTagsDaoImpl.class,
+        HostTransferMapDaoImpl.class,
+        HypervisorCapabilitiesDaoImpl.class,
+        HypervisorGuruManagerImpl.class,
+        IdentityDaoImpl.class,
+        ImageStoreDaoImpl.class,
+        ImageStoreJoinDaoImpl.class,
+        InstanceGroupDaoImpl.class,
+        InstanceGroupJoinDaoImpl.class,
+        InstanceGroupVMMapDaoImpl.class,
+        IpAddressManagerImpl.class,
+        Ipv6AddressManagerImpl.class,
+        ItWorkDaoImpl.class,
+        LBHealthCheckPolicyDaoImpl.class,
+        LBStickinessPolicyDaoImpl.class,
+        LaunchPermissionDao.class,
+        LoadBalancerDaoImpl.class,
+        LoadBalancerVMMapDaoImpl.class,
+        LoadBalancingRulesManagerImpl.class,
+        ManagementServerHostDaoImpl.class,
+        MockAccountManager.class,
+        NetworkACLDaoImpl.class,
+        NetworkACLItemDaoImpl.class,
+        NetworkACLManagerImpl.class,
+        NetworkAccountDaoImpl.class,
+        NetworkDaoImpl.class,
+        NetworkDomainDaoImpl.class,
+        NetworkModelImpl.class,
+        NetworkOfferingDaoImpl.class,
+        NetworkOfferingDetailsDaoImpl.class,
+        NetworkOfferingServiceMapDaoImpl.class,
+        NetworkOpDaoImpl.class,
+        NetworkRuleConfigDaoImpl.class,
+        NetworkServiceImpl.class,
+        NetworkServiceMapDaoImpl.class,
+        NicIpAliasDaoImpl.class,
+        NicSecondaryIpDaoImpl.class,
+        PhysicalNetworkDaoImpl.class,
+        PhysicalNetworkServiceProviderDaoImpl.class,
+        PhysicalNetworkTrafficTypeDaoImpl.class,
+        PlannerHostReservationDaoImpl.class,
+        PodVlanDaoImpl.class,
+        PodVlanMapDaoImpl.class,
+        PortForwardingRulesDaoImpl.class,
+        PortableIpDaoImpl.class,
+        PortableIpRangeDaoImpl.class,
+        PrimaryDataStoreDaoImpl.class,
+        PrivateIpDaoImpl.class,
+        ProjectAccountDaoImpl.class,
+        ProjectAccountJoinDaoImpl.class,
+        ProjectInvitationDaoImpl.class,
+        ProjectDaoImpl.class,
+        ProjectInvitationJoinDaoImpl.class,
+        ProjectJoinDaoImpl.class,
+        ProjectManagerImpl.class,
+        RegionDaoImpl.class,
+        RemoteAccessVpnDaoImpl.class,
+        ResourceCountDaoImpl.class,
+        ResourceLimitDaoImpl.class,
+        ResourceTagDao.class,
+        ResourceTagJoinDaoImpl.class,
+        ResourceTagsDaoImpl.class,
+        RouterNetworkDaoImpl.class,
+        RulesManagerImpl.class,
+        SSHKeyPairDaoImpl.class,
+        SecondaryStorageVmDaoImpl.class,
+        SecurityGroupDaoImpl.class,
+        SecurityGroupJoinDaoImpl.class,
+        SecurityGroupRuleDaoImpl.class,
+        SecurityGroupRulesDaoImpl.class,
+        SecurityGroupVMMapDaoImpl.class,
+        SecurityGroupWorkDaoImpl.class,
+        ServerEventHandlerImpl.class,
+        ServiceOfferingDaoImpl.class,
+        ServiceOfferingDetailsDaoImpl.class,
+        ServiceOfferingJoinDaoImpl.class,
+        Site2SiteCustomerGatewayDaoImpl.class,
+        Site2SiteVpnConnectionDaoImpl.class,
+        Site2SiteVpnGatewayDaoImpl.class,
+        SnapshotDaoImpl.class,
+        SnapshotPolicyDaoImpl.class,
+        StaticRouteDaoImpl.class,
+        StatsCollector.class,
+        StoragePoolDetailsDaoImpl.class,
+        StoragePoolHostDaoImpl.class,
+        StoragePoolJoinDaoImpl.class,
+        SyncQueueItemDaoImpl.class,
+        TemplateDataStoreDaoImpl.class,
+        TemplateJoinDaoImpl.class,
+        UploadDaoImpl.class,
+        UsageEventDaoImpl.class,
+        UserAccountJoinDaoImpl.class,
+        UserDaoImpl.class,
+        UserIpv6AddressDaoImpl.class,
+        UserStatisticsDaoImpl.class,
+        UserStatsLogDaoImpl.class,
+        UserVmCloneSettingDaoImpl.class,
+        UserVmDaoImpl.class,
+        UserVmDetailsDaoImpl.class,
+        UserVmJoinDaoImpl.class,
+        VMInstanceDaoImpl.class,
+        VMSnapshotDaoImpl.class,
+        VMTemplateDaoImpl.class,
+        VMTemplateDetailsDaoImpl.class,
+        VMTemplateHostDaoImpl.class,
+        VMTemplateZoneDaoImpl.class,
+        VirtualRouterProviderDaoImpl.class,
+        VlanDaoImpl.class,
+        VmDiskStatisticsDaoImpl.class,
+        VmRulesetLogDaoImpl.class,
+        VolumeDaoImpl.class,
+        VolumeHostDaoImpl.class,
+        VolumeJoinDaoImpl.class,
+        VpcDaoImpl.class,
+        VpcGatewayDaoImpl.class,
+        VpcManagerImpl.class,
+        VpcOfferingDaoImpl.class,
+        VpcOfferingServiceMapDaoImpl.class,
+        VpcServiceMapDaoImpl.class,
+        VpcVirtualNetworkApplianceManagerImpl.class,
+        VpnUserDaoImpl.class,
+},
+includeFilters={@Filter(value=IntegrationTestConfiguration.ComponentFilter.class, type=FilterType.CUSTOM)},
+useDefaultFilters=false)
+
+@Configuration
+public class IntegrationTestConfiguration {
+    public static class ComponentFilter implements TypeFilter {
+        @Override
+        public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
+            String clsname = mdr.getClassMetadata().getClassName();
+            ComponentScan cs = IntegrationTestConfiguration.class.getAnnotation(ComponentScan.class);
+            return includedInBasePackageClasses(clsname, cs);
+        }
+    }
+    
+    public static boolean includedInBasePackageClasses(String clazzName, ComponentScan cs) {
+        Class<?> clazzToCheck;
+        try {
+            clazzToCheck = Class.forName(clazzName);
+        } catch (ClassNotFoundException e) {
+            System.out.println("Unable to find " + clazzName);
+            return false;
+        }
+        Class<?>[] clazzes = cs.basePackageClasses();
+        for (Class<?> clazz : clazzes) {
+            if (clazzToCheck.isAssignableFrom(clazz)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Inject
+    AffinityGroupDao _affinityGroupDao;
+    @Inject AccountDao _accountDao;
+    @Inject UserDao _userDao;
+    @Inject NetworkOfferingDao _networkOfferingDao;
+    @Inject DataCenterDao _zoneDao;
+    @Inject IPAddressDao _ipAddressDao;
+
+
+    @Bean
+    public AffinityGroupService affinityGroupService() {
+        AffinityGroupService mock = Mockito.mock(AffinityGroupService.class);
+        try {
+            final AffinityGroupVO gmock = new AffinityGroupVO("grp1", "grp-type", "affinity group", 1, AccountVO.ACCOUNT_ID_SYSTEM, ControlledEntity.ACLType.Account); 
+	    Transaction.execute(new TransactionCallbackNoReturn() {
+		    @Override
+		    public void doInTransactionWithoutResult(TransactionStatus status) {
+			_affinityGroupDao.persist(gmock);		
+		    }
+	    });
+            Mockito.when(mock.createAffinityGroupInternal(Mockito.any(String.class), Mockito.any(Long.class), Mockito.any(String.class), Mockito.any(String.class), Mockito.any(String.class))).thenReturn(gmock);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return mock;
+    }
+
+    @Bean
+    public AgentManager agentManager() {
+        return Mockito.mock(AgentManager.class);
+    }
+
+    @Bean
+    public AlertManager alertManager() {
+        return Mockito.mock(AlertManager.class);
+    }
+
+    @Bean
+    public APIChecker apiChecker() {
+        return Mockito.mock(APIChecker.class);
+    }
+
+    @Bean
+    public AsyncJobDispatcher asyncJobDispatcher() {
+        return Mockito.mock(AsyncJobDispatcher.class);
+    }
+    @Bean
+    public AsyncJobMonitor asyncJobMonitor() {
+        return Mockito.mock(AsyncJobMonitor.class);
+    }
+
+    @Bean
+    public AutoScaleService autoScaleService() {
+        return Mockito.mock(AutoScaleService.class);
+    }
+    @Bean
+    public CapacityManager capacityManager() {
+        return Mockito.mock(CapacityManager.class);
+    }
+    @Bean
+    public ClusterManager clusterManager() {
+        return Mockito.mock(ClusterManager.class);
+    }
+    @Bean
+    public ConfigDepot configDepot() {
+        return Mockito.mock(ConfigDepot.class);
+    }
+    @Bean
+    public ConfigDepotAdmin configDepotAdmin() {
+        return Mockito.mock(ConfigDepotAdmin.class);
+    }
+    @Bean
+    public ConsoleProxyManager consoleProxyManager() {
+        return Mockito.mock(ConsoleProxyManager.class);
+    }
+    @Bean
+    public ConsoleProxyService consoleProxyService() {
+        return Mockito.mock(ConsoleProxyService.class);
+    }
+    @Bean
+    public DataStoreManager dataStoreManager() {
+        return Mockito.mock(DataStoreManager.class);
+    }
+    @Bean
+    public DataStoreProviderApiService dataStoreProviderApiService() {
+        return Mockito.mock(DataStoreProviderApiService.class);
+    }
+    @Bean
+    public DeploymentPlanner deploymentPlanner() {
+        return Mockito.mock(DeploymentPlanner.class);
+    }
+    @Bean
+    public DeploymentPlanningManager deploymentPlanningManager() {
+        return Mockito.mock(DeploymentPlanningManager.class);
+    }
+    @Bean
+    public DomainChecker domainChecker() {
+        DomainChecker mock = Mockito.mock(DomainChecker.class);
+        try {
+            Mockito.when(mock.checkAccess(Mockito.any(Account.class), Mockito.any(DataCenter.class))).thenReturn(true);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return mock;
+    }
+    @Bean
+    public EndPointSelector endPointSelector() {
+        return Mockito.mock(EndPointSelector.class);
+    }
+    @Bean
+    public EntityManager entityManager() {
+        EntityManager mock = Mockito.mock(EntityManager.class);
+        try {
+            Mockito.when(mock.findById(Mockito.same(Account.class), Mockito.anyLong())).thenReturn(_accountDao.findById(AccountVO.ACCOUNT_ID_SYSTEM));
+            Mockito.when(mock.findById(Mockito.same(User.class), Mockito.anyLong())).thenReturn(_userDao.findById(UserVO.UID_SYSTEM));
+            Mockito.when(mock.findById(Mockito.same(NetworkOffering.class), Mockito.any(Long.class))).thenAnswer(
+                new Answer<NetworkOffering>()
+                {
+                     @Override
+                     public NetworkOffering answer(final InvocationOnMock invocation) throws Throwable
+                     {
+                          Long id = (Long) invocation.getArguments()[1];
+                          return _networkOfferingDao.findById(id);
+                     }
+                }
+             );
+            Mockito.when(mock.findById(Mockito.same(IpAddress.class), Mockito.any(Long.class))).thenAnswer(
+                new Answer<IpAddress>()
+                {
+                     @Override
+                     public IpAddress answer(final InvocationOnMock invocation) throws Throwable
+                     {
+                          Long id = (Long) invocation.getArguments()[1];
+                          return _ipAddressDao.findById(id);
+                     }
+                }
+             );
+            Mockito.when(mock.findById(Mockito.same(DataCenter.class), Mockito.any(Long.class))).thenAnswer(
+                new Answer<DataCenter>()
+                {
+                     @Override
+                     public DataCenter answer(final InvocationOnMock invocation) throws Throwable
+                     {
+                          Long id = (Long) invocation.getArguments()[1];
+                          return _zoneDao.findById(id);
+                     }
+                }
+             );
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        CallContext.init(mock);
+        return mock;
+    }
+    @Bean
+    public ExternalDeviceUsageManager externalDeviceUsageManager() {
+        return Mockito.mock(ExternalDeviceUsageManager.class);
+    }
+    @Bean
+    public GlobalLoadBalancingRulesService globalLoadBalancingRulesService() {
+        return Mockito.mock(GlobalLoadBalancingRulesService.class);
+    }
+    @Bean
+    public HighAvailabilityManager highAvailabilityManager()  {
+        return Mockito.mock(HighAvailabilityManager.class);
+    }
+    @Bean
+    public HostAllocator hostAllocator() {
+        return Mockito.mock(HostAllocator.class);
+    }
+    @Bean
+    public IdentityService identityService() {
+        return Mockito.mock(IdentityService.class);
+    }
+    @Bean
+    public InternalLoadBalancerVMManager internalLoadBalancerVMManager() {
+        return Mockito.mock(InternalLoadBalancerVMManager.class);
+    }
+    @Bean
+    public InternalLoadBalancerVMService internalLoadBalancerVMService() {
+        return Mockito.mock(InternalLoadBalancerVMService.class);
+    }
+    @Bean
+    public ApplicationLoadBalancerService applicationLoadBalancerService() {
+        return Mockito.mock(ApplicationLoadBalancerService.class);
+    }
+    @Bean
+    public ManagementServer managementServer() {
+        return Mockito.mock(ManagementServer.class);
+    }
+    @Bean
+    public NetworkACLService networkACLService() {
+        return Mockito.mock(NetworkACLService.class);
+    }
+    @Bean
+    public NetworkUsageService networkUsageService() {
+        return Mockito.mock(NetworkUsageService.class);
+    }
+    @Bean
+    public OrchestrationService orchSrvc() {
+        return Mockito.mock(OrchestrationService.class);
+    }
+    @Bean
+    public PodAllocator podAllocator() {
+        return Mockito.mock(PodAllocator.class);
+    }
+    @Bean
+    public QueryService queryService() {
+        return Mockito.mock(QueryService.class);
+    }
+    @Bean
+    public RegionManager regionManager() {
+        return Mockito.mock(RegionManager.class);
+    }
+    @Bean
+    public RemoteAccessVpnService remoteAccessVpnService() {
+        return Mockito.mock(RemoteAccessVpnService.class);
+    }
+    @Bean
+    public ResourceLimitService resourceLimitService() {
+        return Mockito.mock(ResourceLimitService.class);
+    }
+    @Bean
+    public ResourceManager resourceManager() {
+        return Mockito.mock(ResourceManager.class);
+    }
+    @Bean
+    public ResourceMetaDataService resourceMetaDataService() {
+        return Mockito.mock(ResourceMetaDataService.class);
+    }
+    @Bean
+    public SecondaryStorageVmManager secondaryStorageVmManager() {
+        return Mockito.mock(SecondaryStorageVmManager.class);
+    }
+    @Bean
+    public Site2SiteVpnManager  site2SiteVpnManager() {
+        return Mockito.mock(Site2SiteVpnManager.class);
+    }
+    @Bean
+    public Site2SiteVpnServiceProvider site2SiteVpnServiceProvider() {
+        return Mockito.mock(Site2SiteVpnServiceProvider.class);
+    }
+    @Bean
+    public SnapshotApiService snapshotApiService() {
+        return Mockito.mock(SnapshotApiService.class);
+    }
+    @Bean
+    public SnapshotManager snapshotManager() {
+        return Mockito.mock(SnapshotManager.class);
+    }
+    @Bean
+    public StorageManager storageManager() {
+        return Mockito.mock(StorageManager.class);
+    }
+    @Bean
+    public StorageNetworkManager storageNetworkManager() {
+        return Mockito.mock(StorageNetworkManager.class);
+    }
+    @Bean
+    public StorageNetworkService storageNetworkService() {
+        return Mockito.mock(StorageNetworkService.class);
+    }
+    @Bean
+    public StoragePoolAllocator storagePoolAllocator() {
+        return Mockito.mock(StoragePoolAllocator.class);
+    }
+    @Bean
+    public SyncQueueManager syncQueueManager() {
+        return Mockito.mock(SyncQueueManager.class);
+    }
+    @Bean
+    public TaggedResourceService taggedResourceService() {
+        return Mockito.mock(TaggedResourceService.class);
+    }
+    @Bean
+    public TemplateDataFactory templateDataFactory() {
+        return Mockito.mock(TemplateDataFactory.class);
+    }
+    @Bean
+    public TemplateApiService templateApiService() {
+        return Mockito.mock(TemplateApiService.class);
+    }
+    @Bean
+    public TemplateManager templateManager() {
+        return Mockito.mock(TemplateManager.class);
+    }
+    @Bean
+    public TemplateService templateService() {
+        return Mockito.mock(TemplateService.class);
+    }
+    @Bean
+    public UsageService usageService() {
+        return Mockito.mock(UsageService.class);
+    }
+    @Bean
+    public UserAuthenticator userAuthenticator() {
+        return Mockito.mock(UserAuthenticator.class);
+    }
+    @Bean
+    public VMSnapshotManager vMSnapshotManager() {
+        return Mockito.mock(VMSnapshotManager.class);
+    }
+    @Bean
+    public VolumeApiService volumeApiService() {
+        return Mockito.mock(VolumeApiService.class);
+    }
+    @Bean
+    public VolumeDataFactory volumeDataFactory() {
+        return Mockito.mock(VolumeDataFactory.class);
+    }
+    @Bean 
+    public VolumeOrchestrationService volumeOrchestrationService() {
+        return Mockito.mock(VolumeOrchestrationService.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
new file mode 100644
index 0000000..82893f1
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
@@ -0,0 +1,393 @@
+// 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.network.contrail.management;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
+import org.apache.log4j.Logger;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import static org.junit.Assert.*;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.manager.Commands;
+import com.cloud.configuration.ConfigurationManager;
+import com.cloud.configuration.ConfigurationService;
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.DataCenter.NetworkType;
+import com.cloud.dc.DataCenterVO;
+import com.cloud.dc.dao.DataCenterDao;
+import com.cloud.domain.Domain;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.NetworkService;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetwork.BroadcastDomainRange;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.resource.ResourceState;
+import com.cloud.service.ServiceOfferingVO;
+import com.cloud.service.dao.ServiceOfferingDao;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.VMTemplateVO;
+import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.vm.dao.UserVmDao;
+
+public class ManagementServerMock {
+    private static final Logger s_logger =
+            Logger.getLogger(ManagementServerMock.class);
+
+    @Inject private AccountManager _accountMgr;
+    @Inject private ConfigurationService _configService;
+    @Inject private DataCenterDao _zoneDao;
+    @Inject private NetworkService _networkService;
+    @Inject private NetworkDao _networksDao;
+    @Inject private PhysicalNetworkDao _physicalNetworkDao;
+    @Inject private UserVmDao _userVmDao;
+    @Inject private ServiceOfferingDao _serviceOfferingDao;
+    @Inject private VMTemplateDao _vmTemplateDao;
+    @Inject private HostDao _hostDao;
+    @Inject public AgentManager _agentMgr;
+    @Inject public VirtualMachineManager _vmMgr;
+
+    private DataCenterVO _zone;
+    private PhysicalNetwork _znet;
+
+    private long _host_id = -1L;
+
+    // TODO: Use the name parameter to retrieve the @Parameter annotation.
+    static void setParameter(BaseCmd cmd, String name, BaseCmd.CommandType field_type, Object value) {
+        Class<?> cls = cmd.getClass();
+        Field field;
+        try {
+            field = cls.getDeclaredField(name);
+        } catch (Exception ex) {
+            s_logger.warn("class: " + cls.getName() + "\t" + ex);
+            return;
+        }
+        field.setAccessible(true);
+        switch (field_type) {
+        case STRING:
+            try {
+                field.set(cmd, value);
+            } catch (Exception ex) {
+                s_logger.warn(ex);
+                return;
+            }
+            break;
+        case UUID:
+            if (value.equals("-1")) {
+                try {
+                    field.setLong(cmd, -1L);
+                } catch (Exception ex) {
+                    s_logger.warn(ex);
+                    return;
+                }
+            }
+            break;
+        case LONG:
+            try {
+                field.set(cmd, value);
+            } catch (Exception ex) {
+                s_logger.warn(ex);
+                return;
+            }
+            break;
+        default:
+            try {
+                field.set(cmd, value);
+            } catch (Exception ex) {
+                s_logger.warn(ex);
+                return;
+            }
+            break;
+        }
+    }
+
+    private void createHost() {
+        HostVO host = new HostVO(_host_id, "aa01", Type.BaremetalDhcp,
+                "192.168.1.1", "255.255.255.0", null,
+                null, null, null,
+                null, null, null,
+                null, null, null,
+                UUID.randomUUID().toString(), Status.Up, "1.0", null,
+                null, _zone.getId(), null, 0, 0, "aa", 0, StoragePoolType.NetworkFilesystem);
+        host.setResourceState(ResourceState.Enabled);
+        _hostDao.persist(host);
+        _host_id = host.getId();
+    }
+    private void createPublicVlanIpRange() {
+        CreateVlanIpRangeCmd cmd = new CreateVlanIpRangeCmd();
+        BaseCmd proxy = ComponentContext.inject(cmd);
+        Long public_net_id = null;
+
+        List<NetworkVO> nets = _networksDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
+        if (nets != null && !nets.isEmpty()) {
+            NetworkVO public_net = nets.get(0); 
+            public_net_id = public_net.getId();
+        } else {
+            s_logger.debug("no public network found in the zone: " + _zone.getId());
+        }
+        Account system = _accountMgr.getSystemAccount();
+
+        setParameter(cmd, "accountName", BaseCmd.CommandType.STRING, system.getAccountName());
+        setParameter(cmd, "domainId", BaseCmd.CommandType.LONG, Domain.ROOT_DOMAIN);
+        setParameter(cmd, "startIp", BaseCmd.CommandType.STRING, "10.84.60.200");
+        setParameter(cmd, "endIp", BaseCmd.CommandType.STRING, "10.84.60.250");
+        setParameter(cmd, ApiConstants.GATEWAY, BaseCmd.CommandType.STRING, "10.84.60.254");
+        setParameter(cmd, ApiConstants.NETMASK, BaseCmd.CommandType.STRING, "255.255.255.0");
+        setParameter(cmd, "networkID", BaseCmd.CommandType.LONG, public_net_id);
+        setParameter(cmd, "zoneId", BaseCmd.CommandType.LONG, _zone.getId());
+        setParameter(cmd, "vlan", BaseCmd.CommandType.STRING, "untagged");
+        s_logger.debug("createPublicVlanIpRange execute : zone id: " + _zone.getId() + ", public net id: " + public_net_id);
+        try {
+           _configService.createVlanAndPublicIpRange(cmd);
+        } catch (Exception e) {
+           s_logger.debug("createPublicVlanIpRange: " + e);
+        }
+    }
+
+
+    public UserVm createVM(String name, Network network) {
+        VMTemplateVO tmpl = getVMTemplate();
+        assertNotNull(tmpl);
+        ServiceOffering small = getServiceByName("Small Instance");
+        assertNotNull(small);
+
+        Answer<?> callback = new Answer<Object>() {
+            public Object answer(InvocationOnMock invocation) {
+                Object[] args = invocation.getArguments();
+                Commands cmds = (Commands) args[1];
+                if (cmds == null) {
+                    return null;
+                }
+                PlugNicAnswer reply = new PlugNicAnswer(null, true, "PlugNic");
+                com.cloud.agent.api.Answer[] answers = { reply };
+                cmds.setAnswers(answers);
+                return null;
+            }
+        };
+        try {
+            Mockito.when(_agentMgr.send(Mockito.anyLong(), Mockito.any(Commands.class))).thenAnswer(callback);
+        } catch (AgentUnavailableException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        } catch (OperationTimedoutException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        long id = _userVmDao.getNextInSequence(Long.class, "id");
+        UserVmVO vm = new UserVmVO(id, name, name, tmpl.getId(), HypervisorType.XenServer, tmpl.getGuestOSId(),
+                false, false, _zone.getDomainId(), Account.ACCOUNT_ID_SYSTEM, small.getId(), null, name, null);
+        vm.setState(com.cloud.vm.VirtualMachine.State.Running);
+        vm.setHostId(_host_id);
+        vm.setDataCenterId(network.getDataCenterId());
+        _userVmDao.persist(vm);
+
+        NicProfile profile = new NicProfile();
+        try {
+            _vmMgr.addVmToNetwork(vm, network, profile);
+        } catch (Exception ex) {
+            // TODO Auto-generated catch block
+            //ex.printStackTrace();
+        }
+        return vm;
+    }
+
+    private void deleteHost() {
+        _hostDao.remove(_host_id);
+
+    }
+
+    public void deleteVM(UserVm vm, Network network) {
+        Answer<?> callback = new Answer<Object>() {
+            public Object answer(InvocationOnMock invocation) {
+                Object[] args = invocation.getArguments();
+                Commands cmds = (Commands) args[1];
+                if (cmds == null) {
+                    return null;
+                }
+                UnPlugNicAnswer reply = new UnPlugNicAnswer(null, true, "PlugNic");
+                com.cloud.agent.api.Answer[] answers = { reply };
+                cmds.setAnswers(answers);
+                return null;
+            }
+        };
+
+        try {
+            Mockito.when(_agentMgr.send(Mockito.anyLong(), Mockito.any(Commands.class))).thenAnswer(callback);
+        } catch (AgentUnavailableException e) {
+            e.printStackTrace();
+        } catch (OperationTimedoutException e) {
+            e.printStackTrace();
+        }
+        
+        _userVmDao.remove(vm.getId());
+    }
+
+    public void initialize(boolean oneShot) {
+        locateZone();
+        locatePhysicalNetwork();
+        createHost();
+        if (oneShot) {
+            createPublicVlanIpRange();
+        }
+    }
+
+    private VMTemplateVO getVMTemplate() {
+        List<VMTemplateVO> tmpl_list = _vmTemplateDao.listDefaultBuiltinTemplates();
+        for (VMTemplateVO tmpl: tmpl_list) {
+            if (tmpl.getHypervisorType() == HypervisorType.XenServer) {
+                return tmpl;
+            }
+        }    
+        return null;
+    }
+
+    private ServiceOffering getServiceByName(String name) {
+        List<ServiceOfferingVO> service_list = _serviceOfferingDao.findPublicServiceOfferings();
+        for (ServiceOfferingVO service: service_list) {
+            if (service.getName().equals(name)) {
+                return service;
+            }
+        }
+        return null;
+    }
+
+    public DataCenter getZone() {
+        return _zone;
+    }
+
+    private void locatePhysicalNetwork() {
+        // mandatory: name, zone-id
+        try {
+            long id = _networkService.findPhysicalNetworkId(_zone.getId(), "znet", TrafficType.Guest);
+            _znet = _networkService.getPhysicalNetwork(id);
+            List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
+            if (nets == null || nets.isEmpty()) {
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null);
+            }
+        } catch (InvalidParameterValueException e) {
+            List<String> isolationMethods = new ArrayList<String>();
+            isolationMethods.add("GRE");
+            _znet = _networkService.createPhysicalNetwork(_zone.getId(), null, null, isolationMethods,
+                    BroadcastDomainRange.ZONE.toString(), _zone.getDomainId(),
+                    null, "znet");
+            List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
+            if (nets == null || nets.isEmpty()) {
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null);
+            }
+        }
+        if (_znet.getState() != PhysicalNetwork.State.Enabled) {
+            _znet = _networkService.updatePhysicalNetwork(_znet.getId(), null, null, null,
+                    PhysicalNetwork.State.Enabled.toString());
+        }
+
+        // Ensure that the physical network supports Guest traffic.
+        Pair<List<? extends PhysicalNetworkTrafficType>, Integer> trafficTypes =
+                _networkService.listTrafficTypes(_znet.getId());
+        boolean found = false;
+        for (PhysicalNetworkTrafficType ttype: trafficTypes.first()) {
+            if (ttype.getTrafficType() == TrafficType.Guest) {
+                found = true;
+            }
+        }
+        if (!found) {
+            _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(),
+                    null, null, null, null, null);
+        }
+
+        Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> providers =
+                _networkService.listNetworkServiceProviders(_znet.getId(), Provider.JuniperContrail.getName(),
+                        null, null, null);
+        if (providers.second() == 0) {
+            s_logger.debug("Add " + Provider.JuniperContrail.getName() + " to network " + _znet.getName());
+            PhysicalNetworkServiceProvider provider =
+                    _networkService.addProviderToPhysicalNetwork(_znet.getId(), Provider.JuniperContrail.getName(),
+                            null, null);
+            _networkService.updateNetworkServiceProvider(provider.getId(),
+                    PhysicalNetworkServiceProvider.State.Enabled.toString(), null);
+        } else {
+            PhysicalNetworkServiceProvider provider = providers.first().get(0);
+            if (provider.getState() != PhysicalNetworkServiceProvider.State.Enabled) {
+                _networkService.updateNetworkServiceProvider(provider.getId(),
+                        PhysicalNetworkServiceProvider.State.Enabled.toString(), null); 
+            }
+        }
+
+        providers = _networkService.listNetworkServiceProviders(_znet.getId(), null,
+                PhysicalNetworkServiceProvider.State.Enabled.toString(), null, null);
+        s_logger.debug(_znet.getName() + " has " + providers.second().toString() + " Enabled providers");
+        for (PhysicalNetworkServiceProvider provider: providers.first()) {
+            if (provider.getProviderName().equals(Provider.JuniperContrail.getName())) {
+                continue;
+            }
+            s_logger.debug("Disabling " + provider.getProviderName());
+            _networkService.updateNetworkServiceProvider(provider.getId(),
+                    PhysicalNetworkServiceProvider.State.Disabled.toString(), null);
+        }
+    }
+
+    private void locateZone() {
+        _zone = _zoneDao.findByName("default");
+        if (_zone == null) {
+            ConfigurationManager mgr = (ConfigurationManager) _configService;
+            _zone = mgr.createZone(User.UID_SYSTEM, "default", "8.8.8.8", null, "8.8.4.4", null,
+                    null /* cidr */, "ROOT", Domain.ROOT_DOMAIN,
+                    NetworkType.Advanced, null, null /* networkDomain */, false, false, null, null);
+        }
+    }
+    public void shutdown() {
+        deleteHost();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
new file mode 100644
index 0000000..195e932
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java
@@ -0,0 +1,372 @@
+// 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.network.contrail.management;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
+import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
+import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
+import org.apache.cloudstack.api.command.admin.user.RegisterCmd;
+import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
+
+import com.cloud.api.query.vo.ControlledViewEntity;
+import com.cloud.domain.Domain;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.projects.Project.ListProjectResourcesCriteria;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
+import com.cloud.user.User;
+import com.cloud.user.UserAccount;
+import org.apache.cloudstack.context.CallContext;
+import com.cloud.user.UserVO;
+import com.cloud.user.dao.AccountDao;
+import com.cloud.api.query.dao.AccountJoinDao;
+import com.cloud.configuration.dao.ResourceCountDao;
+import com.cloud.configuration.ResourceLimit;
+import com.cloud.api.query.vo.AccountJoinVO;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Pair;
+import com.cloud.utils.Ternary;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+
+import org.mockito.Mockito;
+
+public class MockAccountManager extends ManagerBase implements AccountManager {
+    private static final Logger s_logger =
+            Logger.getLogger(MockAccountManager.class);
+
+	@Inject AccountDao _accountDao;
+        @Inject ResourceCountDao _resourceCountDao;
+
+        @Inject AccountJoinDao _accountJoinDao;
+	@Inject UserDao _userDao;
+	
+	UserVO _systemUser;
+	AccountVO _systemAccount;
+
+    @Override
+    public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
+        _systemAccount = _accountDao.findById(AccountVO.ACCOUNT_ID_SYSTEM);
+        if (_systemAccount == null) {
+            throw new ConfigurationException("Unable to find the system account using " + Account.ACCOUNT_ID_SYSTEM);
+        }
+
+        _systemUser = _userDao.findById(UserVO.UID_SYSTEM);
+        if (_systemUser == null) {
+            throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
+        }
+        CallContext.register(_systemUser, _systemAccount);
+        s_logger.info("MockAccountManager initialization successful");
+        return true;
+    }
+
+    @Override
+    public void checkAccess(Account arg0, Domain arg1)
+            throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void checkAccess(Account arg0, AccessType arg1, boolean arg2,
+            ControlledEntity... arg3) throws PermissionDeniedException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public String[] createApiKeyAndSecretKey(RegisterCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User createUser(String arg0, String arg1, String arg2, String arg3,
+            String arg4, String arg5, String arg6, Long arg7, String arg8) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount createUserAccount(String arg0, String arg1, String arg2,
+            String arg3, String arg4, String arg5, String arg6, short arg7,
+            Long arg8, String arg9, Map<String, String> arg10, String arg11,
+            String arg12) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account finalizeOwner(Account arg0, String arg1, Long arg2, Long arg3) {
+        return _systemAccount; 
+    }
+
+    @Override
+    public Account getActiveAccountByName(String arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getActiveUser(long arg0) {
+        return _systemUser;
+    }
+
+    @Override
+    public User getActiveUserByRegistrationToken(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RoleType getRoleType(Account arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account getSystemAccount() {
+        return _systemAccount;
+    }
+
+    @Override
+    public User getSystemUser() {
+        return _systemUser;
+    }
+
+    @Override
+    public UserAccount getUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public User getUserIncludingRemoved(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean isAdmin(short arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean isRootAdmin(short arg0) {
+        // TODO Auto-generated method stub
+        return true;
+    }
+
+    @Override
+    public UserAccount lockUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void markUserRegistered(long arg0) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public UserAccount authenticateUser(String arg0, String arg1, Long arg2,
+            String arg3, Map<String, Object[]> arg4) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void buildACLSearchBuilder(
+            SearchBuilder<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLSearchCriteria(
+            SearchCriteria<? extends ControlledEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLSearchParameters(Account arg0, Long arg1, String arg2,
+            Long arg3, List<Long> arg4,
+            Ternary<Long, Boolean, ListProjectResourcesCriteria> arg5,
+            boolean arg6, boolean arg7) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLViewSearchBuilder(
+            SearchBuilder<? extends ControlledViewEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void buildACLViewSearchCriteria(
+            SearchCriteria<? extends ControlledViewEntity> arg0, Long arg1,
+            boolean arg2, List<Long> arg3, ListProjectResourcesCriteria arg4) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public Long checkAccessAndSpecifyAuthority(Account arg0, Long arg1) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean deleteAccount(AccountVO arg0, long arg1, Account arg2) {
+        return true;
+    }
+
+    @Override
+    public boolean deleteUser(DeleteUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean deleteUserAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public boolean disableAccount(long arg0)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account disableAccount(String arg0, Long arg1, Long arg2)
+            throws ConcurrentOperationException, ResourceUnavailableException {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount disableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public boolean enableAccount(long arg0) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    public Account enableAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount enableUser(long arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Pair<User, Account> findUserByApiKey(String arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account lockAccount(String arg0, Long arg1, Long arg2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Account updateAccount(UpdateAccountCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public UserAccount updateUser(UpdateUserCmd arg0) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+	@Override
+	public Account getActiveAccountById(long accountId) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public Account getAccount(long accountId) {
+               return _systemAccount;
+	}
+
+	@Override
+	public Account createAccount(String accountName, short accountType,
+			Long domainId, String networkDomain, Map<String, String> details,
+			String uuid) {
+	    final AccountVO account = new AccountVO(accountName, domainId, networkDomain, accountType, uuid);
+	    Transaction.execute(new TransactionCallbackNoReturn() {
+	        @Override
+		public void doInTransactionWithoutResult(TransactionStatus status) {
+
+		    _accountDao.persist(account);
+		    _resourceCountDao.createResourceCounts(account.getId(), ResourceLimit.ResourceOwnerType.Account);
+		}
+	    });
+            return account;
+	}
+
+	@Override
+	public void logoutUser(long userId) {
+		// TODO Auto-generated method stub
+		
+	}
+    
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
new file mode 100644
index 0000000..40cd1ea
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java
@@ -0,0 +1,477 @@
+// 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.network.contrail.management;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import junit.framework.TestCase;
+
+import org.apache.cloudstack.network.contrail.management.ContrailManager;
+import org.apache.cloudstack.network.contrail.management.ServerDBSync;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.ApiConnectorFactory;
+import net.juniper.contrail.api.ApiConnectorMock;
+import net.juniper.contrail.api.types.InstanceIp;
+import net.juniper.contrail.api.types.NetworkIpam;
+import net.juniper.contrail.api.types.SubnetType;
+import net.juniper.contrail.api.types.VirtualMachine;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.api.types.VnSubnetsType;
+import net.juniper.contrail.api.types.Project;
+
+import org.apache.log4j.Logger;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.command.user.project.CreateProjectCmd;
+import org.apache.cloudstack.api.command.user.project.DeleteProjectCmd;
+import org.apache.cloudstack.api.command.user.address.AssociateIPAddrCmd;
+import org.apache.cloudstack.api.command.user.nat.EnableStaticNatCmd;
+import org.apache.cloudstack.api.command.user.nat.DisableStaticNatCmd;
+import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd;
+import org.junit.runner.RunWith;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.cloud.utils.db.Merovingian2;
+import com.cloud.utils.mgmt.JmxUtil;
+
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.dc.DataCenter;
+import com.cloud.domain.Domain;
+import com.cloud.exception.CloudException;
+import com.cloud.network.Network;
+import com.cloud.network.NetworkService;
+import com.cloud.domain.DomainVO;
+import com.cloud.domain.dao.DomainDao;
+import com.cloud.projects.ProjectVO;
+import com.cloud.projects.dao.ProjectDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.User;
+import com.cloud.uservm.UserVm;
+import com.cloud.utils.component.ComponentContext;
+import com.cloud.utils.component.ComponentLifecycle;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.vm.VirtualMachineManager;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.IPAddressVO;
+
+import org.apache.cloudstack.context.CallContext;
+import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations="classpath:/providerContext.xml")
+/**
+ * Exercise the public API.
+ */
+public class NetworkProviderTest extends TestCase {
+    private static final Logger s_logger =
+            Logger.getLogger(NetworkProviderTest.class);
+
+    @Inject public ContrailManager _contrailMgr;
+    @Inject public ServerDBSync _dbSync;
+    @Inject public AccountManager _accountMgr;
+    @Inject IPAddressDao _ipAddressDao;
+    @Inject private NetworkService _networkService;
+
+    @Inject public VirtualMachineManager _vmMgr;
+
+    @Inject public DomainDao _domainDao;
+    @Inject public ProjectDao _projectDao;
+    @Inject public AgentManager _agentMgr;
+    
+    private ManagementServerMock _server;
+    private ApiConnector _api;
+    private static int _mysql_server_port;
+    private static long _msId;
+    private static Merovingian2 _lockMaster;
+    public static boolean _initDone = false;
+
+    @BeforeClass
+    public static void globalSetUp() throws Exception {
+        ApiConnectorFactory.setImplementation(ApiConnectorMock.class);
+        s_logger.info("mysql server is getting launched ");
+        _mysql_server_port = TestDbSetup.init(null);
+        s_logger.info("mysql server launched on port " + _mysql_server_port);
+
+        _msId = ManagementServerNode.getManagementServerId();
+        _lockMaster = Merovingian2.createLockMaster(_msId);        
+    }
+ 
+    @AfterClass
+    public static void globalTearDown() throws Exception {
+        _lockMaster.cleanupForServer(_msId);
+        JmxUtil.unregisterMBean("Locks", "Locks");
+        _lockMaster = null;
+        
+        AbstractApplicationContext ctx = (AbstractApplicationContext) ComponentContext.getApplicationContext();
+        Map<String, ComponentLifecycle> lifecycleComponents = ctx.getBeansOfType(ComponentLifecycle.class);
+        for (ComponentLifecycle bean: lifecycleComponents.values()) {
+            bean.stop();
+        }
+        ctx.close();
+        
+        s_logger.info("destroying mysql server instance running at port <" + _mysql_server_port + ">");
+        TestDbSetup.destroy(_mysql_server_port, null);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        try {
+            ComponentContext.initComponentsLifeCycle();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            s_logger.error(ex.getMessage());
+        }
+        Account system = _accountMgr.getSystemAccount();
+        User user = _accountMgr.getSystemUser();
+        CallContext.register(user, system);
+        _server = ComponentContext.inject(new ManagementServerMock());
+
+        _server.initialize(!_initDone);
+        _initDone = false;
+        _api = _contrailMgr.getApiConnector();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        _server.shutdown();
+    }
+
+    private void purgeTestNetwork() {
+        Account system = _accountMgr.getSystemAccount();
+        DataCenter zone = _server.getZone();
+        List<? extends Network> list =
+                _networkService.getIsolatedNetworksOwnedByAccountInZone(zone.getId(), system);
+        for (Network net : list) {
+            s_logger.debug("Delete network " + net.getName());
+            _networkService.deleteNetwork(net.getId());
+        }
+    }
+
+    private Network lookupTestNetwork(String name) {
+        Account system = _accountMgr.getSystemAccount();
+        DataCenter zone = _server.getZone();
+        List<? extends Network> list =
+                _networkService.getIsolatedNetworksOwnedByAccountInZone(zone.getId(), system);
+        for (Network net : list) {
+            if (net.getName().equals(name)) {
+                return net;
+            }
+        }
+        return null;
+    }
+
+    private Network createTestNetwork(String name) {
+        CreateNetworkCmd cmd = new CreateNetworkCmd();
+        ComponentContext.inject(cmd);
+        Account system = _accountMgr.getSystemAccount();
+        DataCenter zone = _server.getZone();
+
+        ManagementServerMock.setParameter(cmd, "accountName", BaseCmd.CommandType.STRING, system.getAccountName());
+        ManagementServerMock.setParameter(cmd, ApiConstants.NAME, BaseCmd.CommandType.STRING, name);
+        ManagementServerMock.setParameter(cmd, "displayText", BaseCmd.CommandType.STRING, "test network");
+        ManagementServerMock.setParameter(cmd, "networkOfferingId", BaseCmd.CommandType.LONG, _contrailMgr.getOffering().getId());
+        ManagementServerMock.setParameter(cmd, "zoneId", BaseCmd.CommandType.LONG, zone.getId());
+        ManagementServerMock.setParameter(cmd, ApiConstants.GATEWAY, BaseCmd.CommandType.STRING, "10.0.1.254");
+        ManagementServerMock.setParameter(cmd, ApiConstants.NETMASK, BaseCmd.CommandType.STRING, "255.255.255.0");
+        // Physical network id can't be specified for Guest traffic type.
+        // SetParameter(cmd, "physicalNetworkId", BaseCmd.CommandType.LONG, _znet.getId());
+
+        Network result = null;
+        try {
+            result = _networkService.createGuestNetwork(cmd);
+        } catch (CloudException e) {
+            e.printStackTrace();
+            return null;
+        }
+        return result;
+    }
+
+
+    @Test
+    //@Ignore
+    public void testCreateNetwork() {
+        purgeTestNetwork();
+        createTestNetwork("test");
+    }
+ 
+    @Test
+    public void testConnectivity() {
+        Network network = lookupTestNetwork("test");
+        if (network == null) {
+            network = createTestNetwork("test");
+        }
+        UserVm vm1 = _server.createVM("x01", network);
+        UserVm vm2 = _server.createVM("x02", network);
+
+        _server.deleteVM(vm1, network);
+        _server.deleteVM(vm2, network);
+    }
+
+    @Test
+    public void floatingIpTest() {
+        Network network = lookupTestNetwork("test-fip-net");
+        if (network == null) {
+            network = createTestNetwork("test-fip-net");
+        }
+        UserVm vm = _server.createVM("test-fip-vm", network);
+        try {
+            IPAddressVO ip = createFloatingIp(network, vm);
+            deleteFloatingIp(ip);
+        } catch (Exception e) {
+            fail("unable to create/delete floating ip");
+        }
+        _server.deleteVM(vm, network);
+    }
+
+    public void deleteFloatingIp(IPAddressVO ip) throws Exception{
+        BaseCmd cmd = new DisableStaticNatCmd();
+        BaseCmd proxy = ComponentContext.inject(cmd);
+        ManagementServerMock.setParameter(proxy, "ipAddressId", BaseCmd.CommandType.LONG, ip.getId());
+        try {
+            proxy.execute();
+        } catch (Exception e) {
+            s_logger.debug("DisableStaticNatCmd exception: " + e);
+            e.printStackTrace();
+            throw e;
+        }
+    }
+
+    public IPAddressVO createFloatingIp(Network network, UserVm vm) throws Exception {
+        BaseCmd cmd = new AssociateIPAddrCmd();
+        BaseCmd proxy = ComponentContext.inject(cmd);
+        Account system = _accountMgr.getSystemAccount();
+        DataCenter zone = _server.getZone();
+
+        ManagementServerMock.setParameter(proxy, "accountName", BaseCmd.CommandType.STRING, system.getAccountName());
+        ManagementServerMock.setParameter(proxy, "domainId", BaseCmd.CommandType.LONG, Domain.ROOT_DOMAIN);
+        ManagementServerMock.setParameter(proxy, "zoneId", BaseCmd.CommandType.LONG, zone.getId());
+        ManagementServerMock.setParameter(proxy, "networkId", BaseCmd.CommandType.LONG, network.getId());
+        try {
+            ((AssociateIPAddrCmd)cmd).create();
+            ((AssociateIPAddrCmd)cmd).execute();
+        } catch (Exception e) {
+            s_logger.debug("AssociateIPAddrCmd exception: " + e);
+            e.printStackTrace();
+            throw e;
+        }
+
+        SearchBuilder<IPAddressVO> searchBuilder = _ipAddressDao.createSearchBuilder();
+        searchBuilder.and("sourceNat", searchBuilder.entity().isSourceNat(), Op.EQ);
+        searchBuilder.and("network", searchBuilder.entity().getAssociatedWithNetworkId(), Op.EQ);
+        searchBuilder.and("dataCenterId", searchBuilder.entity().getDataCenterId(), Op.EQ);
+        searchBuilder.and("associatedWithVmId", searchBuilder.entity().getAssociatedWithVmId(), Op.NULL);
+        SearchCriteria<IPAddressVO> sc = searchBuilder.create();
+        sc.setParameters("sourceNat", false);
+        sc.setParameters("network", network.getId());
+
+        List<IPAddressVO> publicIps = _ipAddressDao.search(sc, null);
+        assertNotNull(publicIps);
+
+        cmd = new EnableStaticNatCmd();
+        proxy = ComponentContext.inject(cmd);
+        ManagementServerMock.setParameter(proxy, "ipAddressId", BaseCmd.CommandType.LONG, publicIps.get(0).getId());
+        ManagementServerMock.setParameter(proxy, "networkId", BaseCmd.CommandType.LONG, network.getId());
+        ManagementServerMock.setParameter(proxy, "virtualMachineId", BaseCmd.CommandType.LONG, vm.getId());
+
+        try {
+            proxy.execute();
+        } catch (Exception e) {
+            s_logger.debug("EnableStaticNatCmd exception: " + e);
+            e.printStackTrace();
+            throw e;
+        }
+        return publicIps.get(0);
+    }
+
+    public void createProject(String name) {
+        BaseCmd cmd = new CreateProjectCmd();
+        BaseCmd proxy = ComponentContext.inject(cmd);
+        Account system = _accountMgr.getSystemAccount();
+
+        ManagementServerMock.setParameter(proxy, "accountName", BaseCmd.CommandType.STRING, system.getAccountName());
+        ManagementServerMock.setParameter(proxy, "domainId", BaseCmd.CommandType.LONG, Domain.ROOT_DOMAIN);
+        ManagementServerMock.setParameter(proxy, "name", BaseCmd.CommandType.STRING, name);
+        ManagementServerMock.setParameter(proxy, "displayText", BaseCmd.CommandType.STRING, name);
+        try {
+            ((CreateProjectCmd)proxy).create();
+            ((CreateProjectCmd)proxy).execute();
+        } catch (Exception e) {
+            s_logger.debug("CreateProjectCmd exception: " + e);
+            e.printStackTrace();
+            fail("create project cmd failed");
+        }
+        DomainVO domain = _domainDao.findById(Domain.ROOT_DOMAIN);
+        try {
+            net.juniper.contrail.api.types.Domain vncDomain = (net.juniper.contrail.api.types.Domain)
+                    _api.findById(net.juniper.contrail.api.types.Domain.class, domain.getUuid());
+            if (_api.findByName(net.juniper.contrail.api.types.Project.class, vncDomain, name) == null) {
+                 fail("create project failed in vnc");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("Exception while creating a project in vnc");
+        }
+    }
+
+    public void deleteProject(String name) {
+        BaseCmd cmd = new DeleteProjectCmd();
+        BaseCmd proxy = ComponentContext.inject(cmd);
+
+        ProjectVO project = _projectDao.findByNameAndDomain(name, Domain.ROOT_DOMAIN);
+        try {
+            ManagementServerMock.setParameter(proxy, "id", BaseCmd.CommandType.LONG, project.getId());
+            ((DeleteProjectCmd)proxy).execute();
+            if (_api.findById(net.juniper.contrail.api.types.Project.class, project.getUuid()) != null) {
+                 fail("unable to delete project in vnc");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("Exception while deleting project");
+        }
+    }
+
+    @Test
+    public void testProject() {
+        createProject("test-project");
+        deleteProject("test-project");
+    }
+
+    @Test
+    public void dbSyncTest() {
+        Network network = lookupTestNetwork("test-db-only-net");
+        if (network == null) {
+            network = createTestNetwork("test-db-only-net");
+        }
+        UserVm vm = _server.createVM("test-db-only-vm", network);
+        try {
+            createFloatingIp(network, vm);
+        } catch (Exception e) {
+            fail("unable to create floating ip");
+        }
+
+        /* reset ApiServer objects to default config only, so above created objects 
+         * exists only in cludstack db but not in api server
+         */
+        ((ApiConnectorMock)_api).initConfig();
+        /* reset model cached objects */
+        _contrailMgr.getDatabase().initDb();
+
+        /* Create one object of each type directly in api-server - these objects does not exist in cloudstack */
+        net.juniper.contrail.api.types.Domain domain = new net.juniper.contrail.api.types.Domain();
+        domain.setName("test-vnc-only-domain--1");
+        domain.setUuid(UUID.randomUUID().toString());
+        try {
+            assertTrue(_api.create(domain));
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+
+        Project project = new Project();
+        project.setName("test-vnc-only-project-1");
+        project.setUuid(UUID.randomUUID().toString());
+        project.setParent(domain);
+        try {
+            assertTrue(_api.create(project));
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+
+        VirtualNetwork net = new VirtualNetwork();
+        net.setName("test-vnc-only-net-1");
+        net.setUuid(UUID.randomUUID().toString());
+        net.setParent(project);
+        
+        NetworkIpam ipam = null;
+        try {
+            // Find default-network-ipam
+            String ipam_id = _api.findByName(NetworkIpam.class, null, "default-network-ipam");
+            assertNotNull(ipam_id);
+            ipam = (NetworkIpam) _api.findById(NetworkIpam.class, ipam_id);
+            assertNotNull(ipam);
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+
+        VnSubnetsType subnet = new VnSubnetsType();
+        subnet.addIpamSubnets(new SubnetType("10.0.2.0", 24), "10.0.2.254");
+
+        net.addNetworkIpam(ipam, subnet);
+
+        VirtualMachine vncVm = new VirtualMachine();
+        vncVm.setName("test-vnc-only-vm-1");
+        try {
+            assertTrue(_api.create(vncVm));
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+
+        VirtualMachineInterface vmi = new VirtualMachineInterface();
+        vmi.setParent(vncVm);
+        vmi.setName("test-vnc-only-vmi-1");
+
+        try {
+            assertTrue(_api.create(vmi));
+            assertTrue(_api.create(net));
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+        InstanceIp ip_obj = new InstanceIp();
+        ip_obj.setName(net.getName() + ":0");
+        ip_obj.setVirtualNetwork(net);
+        ip_obj.setVirtualMachineInterface(vmi);
+        try {
+            assertTrue(_api.create(ip_obj));
+            // Must perform a GET in order to update the object contents.
+            assertTrue(_api.read(ip_obj));
+            assertNotNull(ip_obj.getAddress());
+
+        } catch (IOException ex) {
+            fail(ex.getMessage());
+        }
+        
+        //now db sync
+        if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_UPDATE) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
+            s_logger.info("# Cloudstack DB & VNC are out of sync - resync done");
+        }
+        
+        if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_CHECK) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
+            s_logger.info("# Cloudstack DB & VNC are still out of sync");
+            fail("DB Sync failed"); 
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6b5fab2f/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
new file mode 100644
index 0000000..818d6a0
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ProviderTestConfiguration.java
@@ -0,0 +1,12 @@
+package org.apache.cloudstack.network.contrail.management;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ProviderTestConfiguration {
+	@Bean
+	ServerDBSync getServerDBSync() {
+		return new ServerDBSyncImpl();
+	}
+}