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();
+ }
+}