Merge "SAL Actions Property is OF1.0 specific"
authorGiovanni Meo <gmeo@cisco.com>
Mon, 11 Nov 2013 17:38:14 +0000 (17:38 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 11 Nov 2013 17:38:14 +0000 (17:38 +0000)
158 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/config-api/pom.xml
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/stat/ConfigProvider.java [deleted file]
opendaylight/config/config-manager/pom.xml
opendaylight/config/config-persister-api/pom.xml
opendaylight/config/config-persister-api/src/main/java/org/opendaylight/controller/config/persist/api/storage/StorageAdapter.java
opendaylight/config/config-persister-file-adapter/pom.xml
opendaylight/config/config-persister-file-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/FileStorageAdapter.java
opendaylight/config/config-util/pom.xml
opendaylight/config/logback-config/pom.xml
opendaylight/config/netty-threadgroup-config/pom.xml
opendaylight/config/pom.xml
opendaylight/config/threadpool-config-api/pom.xml
opendaylight/config/threadpool-config-impl/pom.xml
opendaylight/config/yang-jmx-generator-it/pom.xml
opendaylight/config/yang-jmx-generator-plugin/pom.xml
opendaylight/config/yang-jmx-generator/pom.xml
opendaylight/config/yang-store-api/pom.xml
opendaylight/config/yang-store-impl/pom.xml
opendaylight/config/yang-test/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/md-sal/clustered-data-store/implementation/pom.xml
opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/Activator.java
opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStore.java [deleted file]
opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ActivatorTest.java
opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java [new file with mode: 0644]
opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreTest.java [deleted file]
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingAwareBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataTransactionImpl.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/osgi/ClassLoaderUtils.java with 56% similarity]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-config/pom.xml
opendaylight/md-sal/sal-binding-it/pom.xml
opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java
opendaylight/md-sal/sal-binding-it/src/test/java/org/opendaylight/controller/test/sal/binding/it/DataServiceTest.java
opendaylight/md-sal/sal-common-impl/pom.xml
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/routing/AbstractDataReadRouter.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountService.java
opendaylight/md-sal/sal-dom-broker/pom.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerActivator.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend [deleted file]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend [moved from opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/HashMapDataStore.xtend with 50% similarity]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.xtend
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connector/netconf/test/MountTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft02.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfService.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java [new file with mode: 0644]
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/BrokerFacade.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/ControllerContext.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-zeromq-connector/pom.xml
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChange.java [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/Activator.java [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/Message.java [moved from opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/Message.java with 65% similarity]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/RouteIdentifierImpl.java [moved from opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/RouteIdentifierImpl.java with 73% similarity]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/RpcRequestImpl.java [moved from opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/RpcRequestImpl.java with 70% similarity]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/ZeroMqRpcRouter.java [new file with mode: 0644]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/Activator.java [deleted file]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/RpcReplyImpl.java [deleted file]
opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/ZeroMqRpcRouter.java [deleted file]
opendaylight/md-sal/samples/toaster-it/pom.xml
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java
opendaylight/md-sal/test/sal-rest-connector-it/pom.xml
opendaylight/md-sal/test/sal-rest-connector-it/src/test/java/org/opendaylight/controller/test/restconf/it/ServiceProviderController.java
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-persister-impl/pom.xml
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/NoOpStorageAdapter.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/PersisterImpl.java
opendaylight/netconf/config-persister-impl/src/main/java/org/opendaylight/controller/netconf/persist/impl/osgi/ConfigPersisterActivator.java
opendaylight/netconf/config-persister-impl/src/test/java/org/opendaylight/controller/netconf/persist/impl/PersisterImplTest.java
opendaylight/netconf/netconf-api/pom.xml
opendaylight/netconf/netconf-client/pom.xml
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfImplActivator.java
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-mapping-api/pom.xml
opendaylight/netconf/netconf-util/pom.xml
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/osgi/NetconfConfigUtil.java
opendaylight/netconf/pom.xml
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/Activator.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronFloatingIPInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronNetworkInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronPortInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronRouterInterface.java
opendaylight/networkconfiguration/neutron/implementation/src/main/java/org/opendaylight/controller/networkconfig/neutron/implementation/NeutronSubnetInterface.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronFloatingIPCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronNetworkCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronPortCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronRouterCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetAware.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/INeutronSubnetCRUD.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronCRUDInterfaces.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronFloatingIP.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronNetwork.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronPort.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_Interface.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronRouter_NetworkReference.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_HostRoute.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/Neutron_IPs.java
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronFloatingIPsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworkRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNetworksNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronNorthboundRSApplication.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronPortsNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRouterRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronRoutersNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetRequest.java
opendaylight/northbound/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/northbound/NeutronSubnetsNorthbound.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/MessageReadWriteService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SwitchHandler.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java

index 58a6427f3d6696348287dc54fd8e0a58b60c55a8..f86a0b7e78a841e040deb6ef51a435d33ff0001b 100644 (file)
@@ -76,8 +76,8 @@
     <yangtools.binding.version>0.6.0-SNAPSHOT</yangtools.binding.version>
     <!--versions for bits of the controller -->
     <controller.version>0.4.1-SNAPSHOT</controller.version>
-    <config.version>0.2.2-SNAPSHOT</config.version>
-    <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+    <config.version>0.2.3-SNAPSHOT</config.version>
+    <netconf.version>0.2.3-SNAPSHOT</netconf.version>
     <mdsal.version>1.0-SNAPSHOT</mdsal.version>
     <containermanager.version>0.5.1-SNAPSHOT</containermanager.version>
     <switchmanager.api.version>0.6.1-SNAPSHOT</switchmanager.api.version>
index 394831d25263d08e816b9b429c843e6e574c1c44..d733834b438aee738b234d93b7814999c5817d8c 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <artifactId>config-api</artifactId>
@@ -49,7 +49,6 @@
                             org.opendaylight.controller.config.api.jmx,
                             org.opendaylight.controller.config.api.jmx.constants,
                             org.opendaylight.controller.config.api.runtime,
-                            org.opendaylight.controller.config.stat,
                         </Export-Package>
                     </instructions>
                 </configuration>
diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/stat/ConfigProvider.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/stat/ConfigProvider.java
deleted file mode 100644 (file)
index 3a81061..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.stat;
-
-import org.osgi.framework.BundleContext;
-
-/**
- * Subset of {@link org.osgi.framework.BundleContext}
- */
-public interface ConfigProvider {
-    /**
-     * Returns the value of the specified property. If the key is not found in
-     * the Framework properties, the system properties are then searched. The
-     * method returns {@code null} if the property is not found.
-     *
-     * <p>
-     * All bundles must have permission to read properties whose names start
-     * with &quot;org.osgi.&quot;.
-     *
-     * @param key
-     *            The name of the requested property.
-     * @return The value of the requested property, or {@code null} if the
-     *         property is undefined.
-     * @throws SecurityException
-     *             If the caller does not have the appropriate
-     *             {@code PropertyPermission} to read the property, and the Java
-     *             Runtime Environment supports permissions.
-     */
-    String getProperty(String key);
-
-    public static class ConfigProviderImpl implements ConfigProvider {
-        private final BundleContext context;
-
-        public ConfigProviderImpl(BundleContext context) {
-            this.context = context;
-        }
-
-        @Override
-        public String getProperty(String key) {
-            return context.getProperty(key);
-        }
-
-        @Override
-        public String toString() {
-            return "ConfigProviderImpl{" + "context=" + context + '}';
-        }
-    }
-
-}
index 138f5007a7518d595d2909fcbf6027207174b545..b55b5da8a20735364c0d647aa0955ec52775a6b4 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-manager</artifactId>
index 504c295639cb630d6a1947f0263c158f1f95f74d..51f8c0b8257255d73b5e6d73643a99588a90fdce 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-api</artifactId>
@@ -33,7 +33,6 @@
                             com.google.common.base,
                             org.w3c.dom,
                             org.osgi.framework,
-                            org.opendaylight.controller.config.stat
                         </Import-Package>
                         <Export-Package>
                             org.opendaylight.controller.config.persist.api,
index 447504027e1ba95b7c9987c658e268762e5accc4..9daf4a132502cb1c917b35065a2361fdcbeea552 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.controller.config.persist.api.storage;
 
 import org.opendaylight.controller.config.persist.api.Persister;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
 
 /**
  * Plugins for {@link org.opendaylight.controller.config.persist.api.Persister}
@@ -17,6 +17,6 @@ import org.opendaylight.controller.config.stat.ConfigProvider;
  */
 public interface StorageAdapter extends Persister {
 
-    void setProperties(ConfigProvider configProvider);
+    void setProperties(BundleContext bundleContext);
 
 }
index a5c026da27e2e60b3a44df72b9b1b6f3bf073ff3..b243eadcc66ff50776ba8c00561e38bcaa649864 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-persister-file-adapter</artifactId>
@@ -80,7 +80,6 @@
                             javax.xml.transform.stream,
                             org.apache.commons.lang3,
                             org.opendaylight.controller.config.persist.api,
-                            org.opendaylight.controller.config.stat,
                             org.opendaylight.controller.config.persist.api.storage,
                             org.slf4j,
                             org.w3c.dom,
index a866743b0dee6b2e11e3b85529e1b54bb1073bd5..775fb1f88192cb697b38e712716851c3a246e974 100644 (file)
@@ -16,7 +16,7 @@ import com.google.common.collect.Sets;
 import com.google.common.io.Files;
 import org.apache.commons.lang3.StringUtils;
 import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
@@ -55,8 +55,8 @@ public class FileStorageAdapter implements StorageAdapter {
     private File storage;
 
     @Override
-    public void setProperties(ConfigProvider configProvider) {
-        File storage = extractStorageFileFromProperties(configProvider);
+    public void setProperties(BundleContext bundleContext) {
+        File storage = extractStorageFileFromProperties(bundleContext);
         logger.debug("Using file {}", storage.getAbsolutePath());
         // Create file if it does not exist
         File parentFile = storage.getAbsoluteFile().getParentFile();
@@ -92,12 +92,12 @@ public class FileStorageAdapter implements StorageAdapter {
         numberOfStoredBackups = numberOfBackups;
     }
 
-    private static File extractStorageFileFromProperties(ConfigProvider configProvider) {
-        String fileStorageProperty = configProvider.getProperty(FILE_STORAGE_PROP);
+    private static File extractStorageFileFromProperties(BundleContext bundleContext) {
+        String fileStorageProperty = bundleContext.getProperty(FILE_STORAGE_PROP);
         Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + FILE_STORAGE_PROP
-                + " in received properties :" + configProvider);
+                + " in received context :" + bundleContext);
         File result = new File(fileStorageProperty);
-        String numberOfBAckupsAsString = configProvider.getProperty(NUMBER_OF_BACKUPS);
+        String numberOfBAckupsAsString = bundleContext.getProperty(NUMBER_OF_BACKUPS);
         if (numberOfBAckupsAsString != null) {
             numberOfStoredBackups = Integer.valueOf(numberOfBAckupsAsString);
         } else {
index bf681b1065f60224d0d0f83396473e2385328497..206184ccce0b6f2f3209fa0a2c4a728f986eefa0 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>config-util</artifactId>
index 9abc8ccb637dd4a9d873f79c895b4111b70d6cd0..b63f3298c1af9602674894915664499bcb9d038f 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <artifactId>logback-config</artifactId>
     <name>${project.artifactId}</name>
index e1b8fb34da29bdbddcfc5cc4ca4cc45ba474e65b..ef63fce2ce66126f329d72eeb94aa0e69d33eb23 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <modelVersion>4.0.0</modelVersion>
index 6cf23e8868b72af1fc040246cb768b681e9fd615..2842b5c450712f5a78d8df67abf534027620a6c3 100755 (executable)
@@ -10,7 +10,7 @@
     </parent>
 
 
-    <version>0.2.2-SNAPSHOT</version>
+    <version>0.2.3-SNAPSHOT</version>
     <artifactId>config-subsystem</artifactId>
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
index 1f8f1ea87ee07346c1650917a072adf66dbe6dd5..d8ddc4f24d3d843270fb3704a1098e3012dcef33 100644 (file)
@@ -3,7 +3,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-subsystem</artifactId>
-      <version>0.2.2-SNAPSHOT</version>
+      <version>0.2.3-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>threadpool-config-api</artifactId>
index 1bad023bac0ff3cf7924979bb31e5b988040bd8c..cde64363cfe4454c1ca6184ff6e3c81efef520e4 100644 (file)
@@ -3,7 +3,7 @@
    <parent>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-subsystem</artifactId>
-      <version>0.2.2-SNAPSHOT</version>
+      <version>0.2.3-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>threadpool-config-impl</artifactId>
@@ -96,4 +96,4 @@
       </plugins>
    </build>
 
-</project>
\ No newline at end of file
+</project>
index 336d0c3b824825cb6c284ed4f42f8aeb577e8775..bcec65f2e7db58d613dccedf500afb02d818adfb 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator-it</artifactId>
index 1d53f58d5c79bcbf633c3fe84586f69ab54dc251..f06c7bdad8a65a31345e4c615284cfc8fc564490 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-jmx-generator-plugin</artifactId>
index 37846384bffc6d3113666422b7b06000c521e37a..cd985714d46804ecf84d713a0882811d9177aa38 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-jmx-generator</artifactId>
index 6e850b2566455ce4ed6239319cfb8a8253c89610..9b103df8d7f8900e7e474bf0e777ec30805670f4 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-api</artifactId>
index 07ac4d4bb6e5ca7d7f3d9e20a50bba4d0548965f..ae59dde26ca461ee844df5486ae50fd6367a76b9 100644 (file)
@@ -4,7 +4,7 @@
     <parent>
         <artifactId>config-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
         <relativePath>..</relativePath>
     </parent>
     <artifactId>yang-store-impl</artifactId>
index 3de06882a62cb8afc15d56c3fe14a161fac5b4bc..b7540c8787b15b499d9542e46998de0c32cfa2e2 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>config-subsystem</artifactId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <artifactId>yang-test</artifactId>
index 1ebab9b03adefcf245319388a6f290ce0c759949..abfc0648af6afd137d8f10c3732037cab61eb506 100644 (file)
           <artifactId>model-flow-management</artifactId>
           <version>${mdsal.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller.md</groupId>
+          <artifactId>inventory-manager</artifactId>
+          <version>${mdsal.version}</version>
+        </dependency>
 
         <dependency>
           <groupId>org.opendaylight.controller</groupId>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-util</artifactId>
+          <artifactId>binding-generator-spi</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-model-api</artifactId>
+          <artifactId>binding-generator-api</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
           <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-spi</artifactId>
+          <artifactId>binding-generator-impl</artifactId>
+          <version>${yangtools.binding.version}</version>
+         </dependency>
+         <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>binding-generator-util</artifactId>
+          <version>${yangtools.binding.version}</version>
+         </dependency>
+         <dependency>
+          <groupId>org.opendaylight.yangtools</groupId>
+          <artifactId>binding-model-api</artifactId>
           <version>${yangtools.binding.version}</version>
          </dependency>
          <dependency>
index f822ac5d38ed7e971e45199dce3da3a28ba5265b..bb43809a5c63c4bdb08d8bc6cf2e2ca2a3a492f3 100644 (file)
     </plugins>
   </build>
   <dependencies>
+
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
     <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>sal-common-api</artifactId>
         <version>1.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+       <groupId>org.mockito</groupId>
+       <artifactId>mockito-all</artifactId>
+       <scope>test</scope>
+    </dependency>
     <dependency>
       <groupId>equinoxSDK381</groupId>
       <artifactId>org.eclipse.osgi</artifactId>
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/ClusteredDataStore.java
new file mode 100644 (file)
index 0000000..0a577ad
--- /dev/null
@@ -0,0 +1,18 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+
+package org.opendaylight.controller.datastore;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface ClusteredDataStore extends DataReader<InstanceIdentifier<? extends Object>, Object>, DataCommitHandler<InstanceIdentifier<? extends Object>,Object> {
+}
index 101da7ffa3474d95c4bc7a66797d172e913e4324..c94355d4f6b2597964d16a1ef5f64b293878c229 100644 (file)
@@ -9,14 +9,46 @@
 
 package org.opendaylight.controller.datastore.internal;
 
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Set;
+
 public class Activator extends ComponentActivatorAbstractBase {
     protected static final Logger logger = LoggerFactory
             .getLogger(Activator.class);
 
 
+    @Override
+    protected Object[] getGlobalImplementations(){
+       logger.debug("Calling getGlobalImplementations to return:", ClusteredDataStoreManager.class);
+        return new Object[] {
+            ClusteredDataStoreManager.class
+        };
+    }
+
+
+    @Override
+    protected void configureGlobalInstance(Component c, Object imp){
+        if (imp.equals(ClusteredDataStoreManager.class)) {
+            Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
+
+            c.setInterface(new String[] { ClusteredDataStore.class.getName() }, props);
+            logger.debug("configureGlobalInstance adding dependency:", IClusterGlobalServices.class);
+            
+            c.add(createServiceDependency().setService(
+                    IClusterGlobalServices.class).setCallbacks(
+                    "setClusterGlobalServices",
+                    "unsetClusterGlobalServices").setRequired(true));
+
+        }
+    }
+
 
 }
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStore.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStore.java
deleted file mode 100644 (file)
index 7c25b14..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.opendaylight.controller.datastore.internal;
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
-import org.opendaylight.controller.md.sal.common.api.data.DataModification;
-import org.opendaylight.controller.md.sal.common.api.data.DataReader;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public class ClusteredDataStore implements DataReader<InstanceIdentifier<? extends Object>, Object>, DataCommitHandler<InstanceIdentifier<? extends Object>,Object> {
-    @Override
-    public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
-        return null;
-    }
-
-    @Override
-    public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
-        return null;
-    }
-
-    @Override
-    public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
-        return null;
-    }
-}
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImpl.java
new file mode 100644 (file)
index 0000000..f2e7773
--- /dev/null
@@ -0,0 +1,122 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.datastore.internal;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * The ClusteredDataStoreImpl stores global data to be shared across a controller cluster. It uses Clustering Services.
+ */
+public class ClusteredDataStoreImpl implements ClusteredDataStore {
+
+
+    public static final String OPERATIONAL_DATA_CACHE = "clustered_data_store.operational_data_cache";
+    public static final String CONFIGURATION_DATA_CACHE = "clustered_data_store.configuration_data_cache";
+
+    private ConcurrentMap operationalDataCache;
+    private ConcurrentMap configurationDataCache;
+
+    public ClusteredDataStoreImpl(IClusterGlobalServices clusterGlobalServices) throws CacheExistException, CacheConfigException {
+        Preconditions.checkNotNull(clusterGlobalServices, "clusterGlobalServices cannot be null");
+
+        operationalDataCache = clusterGlobalServices.createCache(OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+        if(operationalDataCache == null){
+            Preconditions.checkNotNull(operationalDataCache, "operationalDataCache cannot be null");
+        }
+
+        configurationDataCache = clusterGlobalServices.createCache(CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+        if(configurationDataCache == null){
+            Preconditions.checkNotNull(configurationDataCache, "configurationDataCache cannot be null");
+        }
+
+    }
+
+    @Override
+    public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
+        return new ClusteredDataStoreTransaction(modification);
+    }
+
+    @Override
+    public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
+        Preconditions.checkNotNull(path, "path cannot be null");
+        return operationalDataCache.get(path);
+    }
+
+    @Override
+    public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
+        Preconditions.checkNotNull(path, "path cannot be null");
+        return configurationDataCache.get(path);
+    }
+
+    private RpcResult<Void> finish(final ClusteredDataStoreTransaction transaction) {
+      final DataModification<InstanceIdentifier<? extends Object>,Object> modification = transaction.getModification();
+
+      this.configurationDataCache.putAll(modification.getUpdatedConfigurationData());
+      this.operationalDataCache.putAll(modification.getUpdatedOperationalData());
+
+      for (final InstanceIdentifier<? extends Object> removal : modification.getRemovedConfigurationData()) {
+        this.configurationDataCache.remove(removal);
+      }
+
+      for (final InstanceIdentifier<? extends Object> removal : modification.getRemovedOperationalData()) {
+        this.operationalDataCache.remove(removal  );
+      }
+
+      Set<RpcError> _emptySet = Collections.<RpcError>emptySet();
+      return Rpcs.<Void>getRpcResult(true, null, _emptySet);
+    }
+
+    private RpcResult<Void> rollback(final ClusteredDataStoreTransaction transaction) {
+      Set<RpcError> _emptySet = Collections.<RpcError>emptySet();
+      return Rpcs.<Void>getRpcResult(true, null, _emptySet);
+    }
+
+    private class ClusteredDataStoreTransaction implements DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> {
+        private final DataModification<InstanceIdentifier<? extends Object>,Object> modification;
+
+        public ClusteredDataStoreTransaction(DataModification<InstanceIdentifier<? extends Object>,Object> modification){
+            Preconditions.checkNotNull(modification, "modification cannot be null");
+
+            this.modification = modification;
+        }
+
+        @Override
+        public DataModification<InstanceIdentifier<? extends Object>, Object> getModification() {
+            return this.modification;
+        }
+
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            return ClusteredDataStoreImpl.this.finish(this);
+        }
+
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            return ClusteredDataStoreImpl.this.rollback(this);
+        }
+    }
+}
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java b/opendaylight/md-sal/clustered-data-store/implementation/src/main/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManager.java
new file mode 100644 (file)
index 0000000..e6acdb0
--- /dev/null
@@ -0,0 +1,75 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+
+
+package org.opendaylight.controller.datastore.internal;
+
+import com.google.common.base.Preconditions;
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.datastore.ClusteredDataStore;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class ClusteredDataStoreManager implements ClusteredDataStore {
+
+    private ClusteredDataStoreImpl clusteredDataStore = null;
+    private IClusterGlobalServices clusterGlobalServices = null;
+
+    @Override
+    public DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> requestCommit(DataModification<InstanceIdentifier<? extends Object>, Object> modification) {
+        Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+        return clusteredDataStore.requestCommit(modification);
+    }
+
+    @Override
+    public Object readOperationalData(InstanceIdentifier<? extends Object> path) {
+        Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+        return clusteredDataStore.readOperationalData(path);
+    }
+
+    @Override
+    public Object readConfigurationData(InstanceIdentifier<? extends Object> path) {
+        Preconditions.checkState(clusteredDataStore != null, "clusteredDataStore cannot be null");
+        return clusteredDataStore.readConfigurationData(path);
+    }
+
+
+    public void setClusterGlobalServices(IClusterGlobalServices clusterGlobalServices){
+        this.clusterGlobalServices = clusterGlobalServices;
+    }
+
+    public void unsetClusterGlobalServices(IClusterGlobalServices clusterGlobalServices){
+        this.clusterGlobalServices = null;
+        this.clusteredDataStore = null;
+    }
+
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        try {
+               //Adding creation of the clustered data store in its own method to make the method unit testable
+            clusteredDataStore = createClusteredDataStore(c);
+        } catch (CacheExistException e) {
+            throw new IllegalStateException("could not construct clusteredDataStore");
+        } catch (CacheConfigException e) {
+            throw new IllegalStateException("could not construct clusteredDataStore");
+        }
+    }
+    protected ClusteredDataStoreImpl createClusteredDataStore(Component c) throws CacheExistException,CacheConfigException{
+       return  new ClusteredDataStoreImpl(clusterGlobalServices);
+    }
+}
index d36e9baf2c956a68c787f8271888749e5cc71a75..5ced9d9a411d80da96a72fc9d2fe9c98c0ae4e00 100644 (file)
@@ -1,13 +1,70 @@
+
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.controller.datastore.internal;
 
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.ServiceDependency;
+
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 
 import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ActivatorTest {
 
+       private static  ServiceDependency serviceDependency;
+       
+       @BeforeClass 
+       public static void initialize(){
+               serviceDependency = mock(ServiceDependency.class);
+       }
+       
+       private class ActivatorTestImpl extends Activator{
+                protected ServiceDependency createServiceDependency() {
+                       return ActivatorTest.serviceDependency;
+                   }
+       }
+       
     @Test
     public void construct(){
         assertNotNull(new Activator());
     }
+    
+    @Test
+    public void construct_OnInvokeOfGlobalImpl_ShouldReturnNotNullObject(){
+        Activator activator = new Activator();
+        
+        assertNotNull(activator.getGlobalImplementations());
+        assertEquals(ClusteredDataStoreManager.class,activator.getGlobalImplementations()[0]);
+    }
+    
+    @Test
+    public void construct_OnInvokeOfConfigGlobalInstance_ShouldNotThrowAnyExceptions(){
+       Activator activator = new ActivatorTestImpl();
+       
+       Component c = mock(Component.class);
+       Object clusterDataStoreMgr = ClusteredDataStoreManager.class;
+       
+       when(serviceDependency.setService(IClusterGlobalServices.class)).thenReturn(serviceDependency);
+       when(serviceDependency.setCallbacks("setClusterGlobalServices",
+                    "unsetClusterGlobalServices")).thenReturn(serviceDependency);
+       when(serviceDependency.setRequired(true)).thenReturn(serviceDependency);
+       
+       
+       activator.configureGlobalInstance(c, clusterDataStoreMgr);
+       
+       
+    }
+    
 }
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java b/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreImplTest.java
new file mode 100644 (file)
index 0000000..8049bae
--- /dev/null
@@ -0,0 +1,248 @@
+package org.opendaylight.controller.datastore.internal;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ClusteredDataStoreImplTest {
+    @Before
+    public void setUp(){
+
+    }
+
+    @Test
+    public void constructor_WhenPassedANullClusteringServices_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+        try {
+            new ClusteredDataStoreImpl(null);
+        } catch(NullPointerException npe){
+            assertEquals("clusterGlobalServices cannot be null", npe.getMessage());
+        }
+    }
+
+    @Test
+    public void constructor_WhenClusteringServicesReturnsANullOperationalDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+        try {
+            new ClusteredDataStoreImpl(mock(IClusterGlobalServices.class));
+        } catch(NullPointerException npe){
+            assertEquals("operationalDataCache cannot be null", npe.getMessage());
+        }
+    }
+
+    @Test
+    public void constructor_WhenClusteringServicesReturnsANullOConfigurationDataCache_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+        // Confused about the following line?
+        // See this http://stackoverflow.com/questions/10952629/a-strange-generics-edge-case-with-mockito-when-and-generic-type-inference
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
+
+
+        try {
+            new ClusteredDataStoreImpl(mockClusterGlobalServices);
+        } catch(NullPointerException npe){
+            assertEquals("configurationDataCache cannot be null", npe.getMessage());
+        }
+    }
+
+    @Test
+    public void constructor_WhenPassedAValidClusteringServices_ShouldNotThrowAnyExceptions() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        new ClusteredDataStoreImpl(mockClusterGlobalServices);
+    }
+
+
+    @Test
+    public void readOperationalData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        try {
+            store.readOperationalData(null);
+        } catch(NullPointerException npe){
+            assertEquals("path cannot be null", npe.getMessage());
+        }
+    }
+
+    @Test
+    public void readOperationalData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
+        InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        assertNull(store.readOperationalData(path));
+    }
+
+    @Test
+    public void readOperationalData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
+        InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+        Object valueObject = mock(Object.class);
+
+        when(mockOperationalDataCache.get(path)).thenReturn(valueObject);
+
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(new ConcurrentHashMap<Object, Object>());
+
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        assertEquals(valueObject, store.readOperationalData(path));
+    }
+
+
+
+    @Test
+    public void readConfigurationData_WhenPassedANullPath_ShouldThrowANullPointerException() throws CacheExistException, CacheConfigException {
+
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        try {
+            store.readConfigurationData(null);
+        } catch(NullPointerException npe){
+            assertEquals("path cannot be null", npe.getMessage());
+        }
+    }
+
+
+    @Test
+    public void readConfigurationData_WhenPassedAKeyThatDoesNotExistInTheCache_ShouldReturnNull() throws CacheExistException, CacheConfigException {
+        InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        assertNull(store.readConfigurationData(path));
+    }
+
+    @Test
+    public void readConfigurationData_WhenPassedAKeyThatDoesExistInTheCache_ShouldReturnTheValueObject() throws CacheExistException, CacheConfigException {
+        InstanceIdentifier path = InstanceIdentifier.builder().toInstance();
+
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+
+        Object valueObject = mock(Object.class);
+
+        when(mockConfigurationDataCache.get(path)).thenReturn(valueObject);
+
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        assertEquals(valueObject, store.readConfigurationData(path));
+    }
+
+
+    @Test
+    public void requestCommit_ShouldReturnADataTransaction() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = createClusterGlobalServices();
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        assertNotNull(store.requestCommit(mock(DataModification.class)));
+
+
+    }
+
+    @Test
+    public void finishingADataTransaction_ShouldUpdateTheUnderlyingCache() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+        ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+        ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        DataModification mockModification = mock(DataModification.class);
+
+        Map configurationData = mock(Map.class);
+        Map operationalData = mock(Map.class);
+
+        when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
+        when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
+
+        DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> transaction = store.requestCommit(mockModification);
+
+        transaction.finish();
+
+        verify(mockConfigurationDataCache).putAll(mockModification.getUpdatedConfigurationData());
+        verify(mockOperationalDataCache).putAll(mockModification.getUpdatedOperationalData());
+    }
+
+
+    @Test
+    public void rollingBackADataTransaction_ShouldDoNothing() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+        ConcurrentMap mockConfigurationDataCache = mock(ConcurrentMap.class);
+        ConcurrentMap mockOperationalDataCache = mock(ConcurrentMap.class);
+
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockOperationalDataCache);
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mockConfigurationDataCache);
+
+        ClusteredDataStoreImpl store = new ClusteredDataStoreImpl(mockClusterGlobalServices);
+
+        DataModification mockModification = mock(DataModification.class);
+
+        Map configurationData = mock(Map.class);
+        Map operationalData = mock(Map.class);
+
+        when(mockModification.getUpdatedConfigurationData()).thenReturn(configurationData);
+        when(mockModification.getUpdatedOperationalData()).thenReturn(operationalData);
+
+        DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends Object>, Object> transaction = store.requestCommit(mockModification);
+
+        transaction.rollback();
+
+        verify(mockConfigurationDataCache, never()).putAll(mockModification.getUpdatedConfigurationData());
+        verify(mockOperationalDataCache, never()).putAll(mockModification.getUpdatedOperationalData());
+
+    }
+
+
+    private IClusterGlobalServices createClusterGlobalServices() throws CacheExistException, CacheConfigException {
+        IClusterGlobalServices mockClusterGlobalServices = mock(IClusterGlobalServices.class);
+
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.OPERATIONAL_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+        Mockito.<ConcurrentMap<?,?>>when(mockClusterGlobalServices.createCache(ClusteredDataStoreImpl.CONFIGURATION_DATA_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).thenReturn(mock(ConcurrentMap.class));
+
+        return mockClusterGlobalServices;
+    }
+}
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java b/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreManagerTest.java
new file mode 100644 (file)
index 0000000..84b07e7
--- /dev/null
@@ -0,0 +1,122 @@
+package org.opendaylight.controller.datastore.internal;
+
+import org.apache.felix.dm.Component;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+public class ClusteredDataStoreManagerTest {
+       
+       private  static ClusteredDataStoreManager clusteredDSMgr = null;
+       private IClusterGlobalServices icClusterGlbServices =  mock(IClusterGlobalServices.class);
+        
+       @BeforeClass
+       public static void construct(){
+               clusteredDSMgr = new ClusteredDataStoreManager();
+        assertNotNull(clusteredDSMgr);
+       }
+        
+       @Test
+       public void construct_OnSetClusterGlobalServices_AssertNoException(){
+               icClusterGlbServices =  mock(IClusterGlobalServices.class);
+                
+               clusteredDSMgr.setClusterGlobalServices(icClusterGlbServices);
+        }
+        
+        @Test
+        public void construct_OnUnSetClusterGlobalServices_AssertNoException(){
+                IClusterGlobalServices icClusterGlbServices =  mock(IClusterGlobalServices.class);
+                
+                clusteredDSMgr.unsetClusterGlobalServices(icClusterGlbServices);
+        }
+        
+        @Test
+        public void construct_init_AssertNoException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreImpl clusteredDSImpl =  mock(ClusteredDataStoreImpl.class);
+                
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+        }
+        
+        @Test(expected = IllegalStateException.class)
+        public void construct_init_AssertCacheExistException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doThrow(CacheExistException.class).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+        }
+        
+        @Test(expected = IllegalStateException.class)
+        public void construct_init_AssertCacheConfigException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doThrow(CacheConfigException.class).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+        }
+        
+        @Test
+        public void construct_readOperationalData_AssertNoException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreImpl clusteredDSImpl =  mock(ClusteredDataStoreImpl.class);
+                
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+                
+                Object o = mock(Object.class);
+                
+                when(clusteredDSImpl.readOperationalData(any(InstanceIdentifier.class))).thenReturn(o);
+                assertEquals(o,clusteredDSManager.readOperationalData(any(InstanceIdentifier.class)));
+        }
+        
+        
+        @Test
+        public void construct_readConfigurationData_AssertNoException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreImpl clusteredDSImpl =  mock(ClusteredDataStoreImpl.class);
+                
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+                Object o = mock(Object.class);
+                
+                when(clusteredDSImpl.readConfigurationData(any(InstanceIdentifier.class))).thenReturn(o);
+                assertEquals(o,clusteredDSManager.readConfigurationData(any(InstanceIdentifier.class)));
+        }
+        
+        @Test
+        public void construct_requestCommit_AssertNoException() throws CacheExistException,CacheConfigException{
+                ClusteredDataStoreImpl clusteredDSImpl =  mock(ClusteredDataStoreImpl.class);
+                
+                ClusteredDataStoreManager clusteredDSManager = spy(new ClusteredDataStoreManager());
+                doReturn(clusteredDSImpl).when(clusteredDSManager).createClusteredDataStore(any(Component.class));
+                Component c = mock(Component.class);
+                
+                clusteredDSManager.init(c);
+                DataCommitTransaction dataCommitTransaction = mock(DataCommitTransaction.class);
+                
+                when(clusteredDSImpl.requestCommit(any(DataModification.class))).thenReturn(dataCommitTransaction);
+                assertEquals(dataCommitTransaction,clusteredDSManager.requestCommit(any(DataModification.class)));
+        }
+}
diff --git a/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreTest.java b/opendaylight/md-sal/clustered-data-store/implementation/src/test/java/org/opendaylight/controller/datastore/internal/ClusteredDataStoreTest.java
deleted file mode 100644 (file)
index 7a8e8e8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.opendaylight.controller.datastore.internal;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertNotNull;
-
-public class ClusteredDataStoreTest {
-    @Test
-    public void construct(){
-        assertNotNull(new ClusteredDataStore());
-    }
-}
index 9ca025b393911d11ede993899a32e2488939c8a2..35264e74e6bd22bf1a69db6f97c3884270d3a5a5 100644 (file)
@@ -16,6 +16,7 @@
 
     <build>
         <plugins>
+        
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
                     <dependency>
                         <groupId>org.opendaylight.controller</groupId>
                         <artifactId>yang-jmx-generator-plugin</artifactId>
-                        <version>0.2.2-SNAPSHOT</version>
+                        <version>0.2.3-SNAPSHOT</version>
                     </dependency>
                 </dependencies>
             </plugin>
+            
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
             <version>${osgi.core.version}</version>
+        <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>javassist</artifactId>
             <version>3.17.1-GA</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>binding-generator-impl</artifactId>
+            <version>0.6.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-parser-impl</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-core-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>runtime</scope>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+       <dependency>
+       <groupId>org.eclipse.xtend</groupId>
+       <artifactId>org.eclipse.xtend.standalone</artifactId>
+       <version>2.4.3</version>
+       <scope>runtime</scope>
+       </dependency> 
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-config</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-impl</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-model-util</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 </project>
index 87cc42c6e413d15502c068431da14d10c851fc99..ea6dc131c6583b3587b23cc172e61f62c3ad68af 100644 (file)
@@ -33,7 +33,7 @@ import java.util.Arrays
 import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
 import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
 import java.util.HashSet
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker
 import java.util.Set
index d9a3dd547f67a1cc448272f7d0a67c2284fb9ddb..31d5d0126fc8115546d1d1b7709671e946b2e026 100644 (file)
@@ -40,10 +40,11 @@ import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
 import org.opendaylight.yangtools.yang.binding.BaseIdentity
 import com.google.common.collect.Multimap
 import com.google.common.collect.HashMultimap
-import static org.opendaylight.controller.sal.binding.impl.osgi.ClassLoaderUtils.*
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*
 import java.util.concurrent.Executors
 import java.util.Collections
 import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.controller.sal.binding.impl.connect.dom.ConnectorActivator
 
 class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
     private static val log = LoggerFactory.getLogger(BindingAwareBrokerImpl)
@@ -86,7 +87,8 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
     
     ServiceRegistration<DataBrokerService> dataConsumerRegistration
     
-    private HashMapDataStore store = new HashMapDataStore();
+    ConnectorActivator connectorActivator
+   
     
     public new(BundleContext bundleContext) {
         _brokerBundleContext = bundleContext;
@@ -115,11 +117,9 @@ class BindingAwareBrokerImpl implements BindingAwareBroker, AutoCloseable {
         notifyConsumerRegistration = brokerBundleContext.registerService(NotificationService, notifyBroker, brokerProperties)
         dataProviderRegistration = brokerBundleContext.registerService(DataProviderService, dataBroker, brokerProperties)
         dataConsumerRegistration = brokerBundleContext.registerService(DataBrokerService, dataBroker, brokerProperties)
-        
-        
-        getDataBroker().registerDataReader(root, store);
-        getDataBroker().registerCommitHandler(root, store)
-        
+
+        connectorActivator = new ConnectorActivator(dataBroker,brokerBundleContext);
+        connectorActivator.start();
         log.info("MD-SAL: Binding Aware Broker Started");
     }
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.java
new file mode 100644 (file)
index 0000000..7a1ca11
--- /dev/null
@@ -0,0 +1,93 @@
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier<? extends DataObject>, DataObject, DataChangeListener> implements
+        DataProviderService {
+
+    public DataBrokerImpl() {
+        setDataReadRouter(new BindingAwareDataReaderRouter());
+    }
+
+    @Override
+    public DataTransactionImpl beginTransaction() {
+        return new DataTransactionImpl(this);
+    }
+
+    @Override
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path,
+            DataChangeListener changeListener) {
+        // TODO Auto-generated method stub
+        
+    }
+    
+    
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/DataBrokerImpl.xtend
deleted file mode 100644 (file)
index 6ed63b2..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-package org.opendaylight.controller.sal.binding.impl
-
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.controller.sal.binding.api.data.DataChangeListener
-import org.opendaylight.controller.sal.binding.api.data.DataProviderService
-import org.opendaylight.yangtools.yang.binding.DataObject
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.controller.md.sal.common.api.TransactionStatus
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.yangtools.concepts.ListenerRegistration
-import com.google.common.collect.Multimap
-import static com.google.common.base.Preconditions.*;
-import java.util.List
-import com.google.common.collect.HashMultimap
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Callable
-import org.opendaylight.yangtools.yang.common.RpcResult
-import org.opendaylight.controller.sal.common.util.Rpcs
-import java.util.Collections
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
-import java.util.ArrayList
-import org.opendaylight.controller.sal.binding.impl.util.BindingAwareDataReaderRouter
-import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
-import java.util.Arrays
-
-class DataBrokerImpl extends DeprecatedDataAPISupport implements DataProviderService {
-
-    @Property
-    var ExecutorService executor;
-
-    val dataReadRouter = new BindingAwareDataReaderRouter;
-
-    Multimap<InstanceIdentifier, DataChangeListenerRegistration> listeners = HashMultimap.create();
-    Multimap<InstanceIdentifier, DataCommitHandlerRegistration> commitHandlers = HashMultimap.create();
-
-    override beginTransaction() {
-        return new DataTransactionImpl(this);
-    }
-
-    override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
-        return dataReadRouter.readConfigurationData(path);
-    }
-
-    override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        return dataReadRouter.readOperationalData(path);
-    }
-
-    override registerCommitHandler(InstanceIdentifier<? extends DataObject> path,
-        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> commitHandler) {
-            val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
-            commitHandlers.put(path,registration)
-            return registration;
-    }
-
-    override registerDataChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
-        val reg = new DataChangeListenerRegistration(path, listener, this);
-        listeners.put(path, reg);
-        return reg;
-    }
-
-    override registerDataReader(InstanceIdentifier<? extends DataObject> path,DataReader<InstanceIdentifier<? extends DataObject>,DataObject> reader) {
-        
-        val confReg = dataReadRouter.registerConfigurationReader(path,reader);
-        val dataReg = dataReadRouter.registerOperationalReader(path,reader);
-        
-        return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
-    }
-
-    protected def removeListener(DataChangeListenerRegistration registration) {
-        listeners.remove(registration.path, registration);
-    }
-
-    protected def removeCommitHandler(DataCommitHandlerRegistration registration) {
-        commitHandlers.remove(registration.path, registration);
-    }
-    
-    protected def getActiveCommitHandlers() {
-        return commitHandlers.entries.map[ value.instance].toSet
-    }
-
-    protected def commit(DataTransactionImpl transaction) {
-        checkNotNull(transaction);
-        transaction.changeStatus(TransactionStatus.SUBMITED);
-        val task = new TwoPhaseCommit(transaction, this);
-        return executor.submit(task);
-    }
-
-}
-
-package class DataChangeListenerRegistration extends AbstractObjectRegistration<DataChangeListener> implements ListenerRegistration<DataChangeListener> {
-
-    DataBrokerImpl dataBroker;
-
-    @Property
-    val InstanceIdentifier<?> path;
-
-    new(InstanceIdentifier<?> path, DataChangeListener instance, DataBrokerImpl broker) {
-        super(instance)
-        dataBroker = broker;
-        _path = path;
-    }
-
-    override protected removeRegistration() {
-        dataBroker.removeListener(this);
-        dataBroker = null;
-    }
-
-}
-
-package class DataCommitHandlerRegistration //
-extends AbstractObjectRegistration<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> {
-
-    DataBrokerImpl dataBroker;
-
-    @Property
-    val InstanceIdentifier<?> path;
-
-    new(InstanceIdentifier<?> path, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> instance,
-        DataBrokerImpl broker) {
-        super(instance)
-        dataBroker = broker;
-        _path = path;
-    }
-
-    override protected removeRegistration() {
-        dataBroker.removeCommitHandler(this);
-        dataBroker = null;
-    }
-
-}
-
-package class TwoPhaseCommit implements Callable<RpcResult<TransactionStatus>> {
-
-    val DataTransactionImpl transaction;
-    val DataBrokerImpl dataBroker;
-
-    new(DataTransactionImpl transaction, DataBrokerImpl broker) {
-        this.transaction = transaction;
-        this.dataBroker = broker;
-    }
-
-    override call() throws Exception {
-
-        val Iterable<DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject>> commitHandlers = dataBroker.activeCommitHandlers;
-
-        // requesting commits
-        val List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> handlerTransactions = new ArrayList();
-        try {
-            for (handler : commitHandlers) {
-                handlerTransactions.add(handler.requestCommit(transaction));
-            }
-        } catch (Exception e) {
-            return rollback(handlerTransactions,e);
-        }
-        val List<RpcResult<Void>> results = new ArrayList();
-        try {
-            for (subtransaction : handlerTransactions) {
-                results.add(subtransaction.finish());
-            }
-        } catch (Exception e) {
-            return rollback(handlerTransactions,e);
-        }
-
-        return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
-    }
-
-    def rollback(List<DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject>> transactions,Exception e) {
-        for (transaction : transactions) {
-            transaction.rollback()
-        }
-        // FIXME return encoutered error.
-        return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
-    }
-}
index c970fc5e920db0cfbfcd8a277ec9bcaa8a109fb6..f7967beaae6471a482885535e02d2aae26a06536 100644 (file)
@@ -1,89 +1,22 @@
 package org.opendaylight.controller.sal.binding.impl;
 
-import java.util.concurrent.Future;
-
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
-import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
-import org.opendaylight.controller.md.sal.common.impl.ListenerRegistry;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-
-public class DataTransactionImpl extends AbstractDataModification<InstanceIdentifier<? extends DataObject>, DataObject>
-        implements DataModificationTransaction {
-
-    private final Object identifier;
-
-    private TransactionStatus status;
-    private ListenerRegistry<DataTransactionListener> listeners;
-
-    final DataBrokerImpl broker;
 
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier<? extends DataObject>, DataObject> 
+    implements DataModificationTransaction {
+    private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+    
+    
+    
     public DataTransactionImpl(DataBrokerImpl dataBroker) {
         super(dataBroker);
-        identifier = new Object();
-        broker = dataBroker;
-        status = TransactionStatus.NEW;
-        listeners = new ListenerRegistry<>();
-    }
-
-    @Override
-    public Future<RpcResult<TransactionStatus>> commit() {
-        return broker.commit(this);
-    }
-
-    @Override
-    public DataObject readConfigurationData(
-            org.opendaylight.yangtools.yang.binding.InstanceIdentifier<? extends DataObject> path) {
-        return broker.readConfigurationData(path);
-    }
-
-    @Override
-    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        return broker.readOperationalData(path);
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((broker == null) ? 0 : broker.hashCode());
-        result = prime * result + ((identifier == null) ? 0 : identifier.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        DataTransactionImpl other = (DataTransactionImpl) obj;
-        if (broker == null) {
-            if (other.broker != null)
-                return false;
-        } else if (!broker.equals(other.broker))
-            return false;
-        if (identifier == null) {
-            if (other.identifier != null)
-                return false;
-        } else if (!identifier.equals(other.identifier))
-            return false;
-        return true;
-    }
-
-    @Override
-    public TransactionStatus getStatus() {
-        return status;
-    }
-
-    @Override
-    public Object getIdentifier() {
-        return identifier;
     }
 
     @Override
@@ -91,11 +24,9 @@ public class DataTransactionImpl extends AbstractDataModification<InstanceIdenti
         return listeners.register(listener);
     }
 
-    public void changeStatus(TransactionStatus status) {
-        this.status = status;
-        Iterable<ListenerRegistration<DataTransactionListener>> listenersToNotify = listeners.getListeners();
-        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listenersToNotify) {
+    protected void onStatusChange(TransactionStatus status) {
+        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
             listenerRegistration.getInstance().onStatusUpdated(this, status);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentDataServiceConnector.java
new file mode 100644 (file)
index 0000000..ff897aa
--- /dev/null
@@ -0,0 +1,151 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collections;
+import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.config.api.jmx.CommitStatus;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import com.google.common.base.Preconditions;
+
+public class BindingIndependentDataServiceConnector implements //
+        RuntimeDataProvider, //
+        DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+    private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
+
+    private BindingIndependentMappingService mappingService;
+
+    private DataBrokerService biDataService;
+
+    private DataProviderService baDataService;
+
+    @Override
+    public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+        // TODO Auto-generated method stub
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+        CompositeNode result = biDataService.readOperationalData(biPath);
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
+    @Override
+    public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
+        CompositeNode result = biDataService.readConfigurationData(biPath);
+        return mappingService.dataObjectFromDataDom(path, result);
+    }
+
+    @Override
+    public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> requestCommit(
+            DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+
+        DataModificationTransaction translated = translateTransaction(modification);
+        return new WrappedTransaction(translated, modification);
+    }
+
+    private DataModificationTransaction translateTransaction(
+            DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
+        DataModificationTransaction target = biDataService.beginTransaction();
+        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
+                .entrySet()) {
+            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+                    .toDataDom(entry);
+            target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+        }
+        for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
+                .entrySet()) {
+            Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
+                    .toDataDom(entry);
+            target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+        }
+        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeConfigurationData(biEntry);
+        }
+        for(InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
+            org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
+            target.removeOperationalData(biEntry);
+        }
+        return target;
+    }
+
+    private class WrappedTransaction implements
+            DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+
+        private DataModificationTransaction backing;
+        private DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification;
+
+        public WrappedTransaction(DataModificationTransaction backing,
+                DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
+            this.backing = backing;
+            this.modification = modification;
+        }
+
+        @Override
+        public DataModification<InstanceIdentifier<? extends DataObject>, DataObject> getModification() {
+            return modification;
+        }
+
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            Future<RpcResult<TransactionStatus>> result = backing.commit();
+            try {
+                RpcResult<TransactionStatus> biresult = result.get();
+            } catch (InterruptedException e) {
+                throw new IllegalStateException("", e);
+            } catch (ExecutionException e) {
+                throw new IllegalStateException("", e);
+            }
+            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        }
+
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            // backing.cancel();
+            return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+        }
+
+    }
+
+    public DataBrokerService getBiDataService() {
+        return biDataService;
+    }
+
+    public void setBiDataService(DataBrokerService biDataService) {
+        this.biDataService = biDataService;
+    }
+
+    public DataProviderService getBaDataService() {
+        return baDataService;
+    }
+
+    public void setBaDataService(DataProviderService baDataService) {
+        this.baDataService = baDataService;
+    }
+
+    public void start() {
+        baDataService.registerDataReader(ROOT, this);
+        baDataService.registerCommitHandler(ROOT, this);
+    }
+
+    public void setMappingService(BindingIndependentMappingService mappingService) {
+        this.mappingService = mappingService;
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentMappingService.java
new file mode 100644 (file)
index 0000000..d8fbc70
--- /dev/null
@@ -0,0 +1,19 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Map.Entry;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface BindingIndependentMappingService {
+
+    CompositeNode toDataDom(DataObject data);
+
+    Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+            Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry);
+
+    org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(InstanceIdentifier<? extends DataObject> path);
+
+    DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result);
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentRpcConnector.java
new file mode 100644 (file)
index 0000000..d22da30
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class BindingIndependentRpcConnector {
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend
new file mode 100644 (file)
index 0000000..9a6330e
--- /dev/null
@@ -0,0 +1,402 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext
+import java.util.List
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import java.util.Map
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import org.opendaylight.yangtools.binding.generator.util.Types
+import java.util.HashMap
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import java.util.Collections
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import org.opendaylight.yangtools.yang.model.util.ExtendedType
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import com.google.common.collect.FluentIterable
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+
+class BindingMapping {
+
+    val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
+    val Map<Type, SchemaNode> typeToSchemaNode = new HashMap();
+
+    def QName getSchemaNode(Class<?> cls) {
+        val ref = Types.typeForClass(cls);
+        return typeToSchemaNode.get(ref)?.QName;
+    }
+
+    def void updateBinding(SchemaContext schemaContext, ModuleContext moduleBindingContext) {
+        updateBindingFor(moduleBindingContext.childNodes, schemaContext);
+
+    }
+
+    def org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+        InstanceIdentifier<? extends DataObject> obj) {
+        val pathArguments = obj.path;
+        var Class<? extends DataObject> parent;
+        val dataDomArgs = new ArrayList<PathArgument>();
+        for (pathArgument : pathArguments) {
+            dataDomArgs.add(pathArgument.toDataDomPathArgument(parent));
+            parent = pathArgument.type;
+        }
+
+        return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(dataDomArgs);
+    }
+
+    
+
+    def DataObject dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> identifier, CompositeNode node) {
+        if (node == null) {
+            return null;
+        }
+        val targetClass = identifier.targetType;
+        val classLoader = targetClass.classLoader;
+        val ref = Types.typeForClass(targetClass);
+        val targetType = typeToDefinition.get(ref);
+        val targetSchema = typeToSchemaNode.get(ref);
+        return node.toDataObject(classLoader, targetType.toInstance, targetSchema);
+
+    }
+
+    def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
+        val Class rawType = argument.type;
+        val ref = Types.typeForClass(rawType);
+        val schemaType = typeToSchemaNode.get(ref);
+        val qname = schemaType.QName
+
+        val Object key = argument.key;
+        val predicates = key.toPredicates(schemaType as ListSchemaNode);
+
+        return new NodeIdentifierWithPredicates(qname, predicates);
+    }
+    
+    def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+        val ref = Types.typeForClass(argument.type);
+        val qname = typeToSchemaNode.get(ref).QName
+        return new NodeIdentifier(qname);
+    }
+
+    def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+        val keyDefinitions = node.keyDefinition;
+        val map = new HashMap<QName, Object>();
+        for (keydef : keyDefinitions) {
+            val keyNode = node.getDataChildByName(keydef) as LeafSchemaNode;
+            val value = identifier.getSimpleValue(keydef, keyNode.type);
+            map.put(keydef, value.value);
+        }
+        return map;
+    }
+
+    def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+        for (entry : map.entrySet) {
+            val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+            typeToDefinition.put(entry.value, entry.value);
+            typeToSchemaNode.put(entry.value, schemaNode)
+        }
+    }
+
+    def CompositeNode toCompositeNode(DataContainer data) {
+        val type = data.implementedInterface;
+        val typeRef = Types.typeForClass(type);
+        val schemaNode = typeToSchemaNode.get(typeRef);
+        val generatedType = typeToDefinition.get(typeRef);
+
+        return data.toDataDom(schemaNode, generatedType);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, ContainerSchemaNode node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, NotificationDefinition node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def dispatch CompositeNode toDataDom(DataContainer data, ListSchemaNode node,
+        GeneratedTypeBuilder builder) {
+        val subnodes = data.toDataDomComponents(node);
+        return new CompositeNodeTOImpl(node.QName, null, subnodes);
+    }
+
+    private def List<Node<?>> toDataDomComponents(DataContainer data, DataNodeContainer node) {
+        val subnodes = new ArrayList<Node<?>>();
+        for (childNode : node.childNodes) {
+            val value = childNode.dataDomFromParent(data);
+            if (value !== null) {
+                subnodes.addAll(value);
+            }
+        }
+        return subnodes;
+    }
+
+    private def List<Node<?>> dataDomFromParent(DataSchemaNode node, DataContainer container) {
+        if (node.augmenting) {
+            return Collections.emptyList();
+        }
+        return dataDomFromParentImpl(node, container);
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(LeafSchemaNode node, DataContainer container) {
+        val value = container.getSimpleValue(node.QName, node.type);
+        if (value !== null) {
+            return Collections.<Node<?>>singletonList(value);
+        }
+        return Collections.emptyList();
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(LeafListSchemaNode node, DataContainer container) {
+        val values = container.getSimpleValues(node);
+        if (values !== null) {
+            //val it = new ArrayList<Node<?>>();
+            //for (value : values) {
+            //}
+
+        }
+        return Collections.emptyList();
+    }
+
+    def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
+        return Collections.emptyList();
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(ListSchemaNode node, DataContainer container) {
+        val qname = node.QName;
+        val values = container.<List>getValue(qname, List) as List<? extends DataContainer>;
+        if (values === null) {
+            return Collections.emptyList;
+        }
+        val it = new ArrayList<Node<?>>();
+        for (value : values) {
+            add(value.toCompositeNode());
+        }
+
+        return it;
+    }
+
+    private def dispatch List<Node<?>> dataDomFromParentImpl(ChoiceNode node, DataContainer container) {
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(List<?> list, GeneratedTypeBuilder builder,
+        ListSchemaNode node) {
+        val it = new ArrayList<Node<?>>();
+        for (value : list) {
+
+            val serVal = value.serializeValueImpl(builder, node);
+            if (serVal !== null) {
+                addAll(serVal);
+            }
+        }
+        return it;
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
+        getSimpleValue(container, name, type.baseType);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
+        val value = container.getValue(name, String);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
+        val value = container.getValue(name, Object);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
+        val value = container.getValue(name, Boolean);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
+        val Object value = container.getValue(name, Object); //Constants.BYTES_CLASS);
+        if(value === null) return null;
+        return new SimpleNodeTOImpl(name, null, value);
+    }
+
+    private def <T> T getValue(Object object, QName node, Class<T> type) {
+        val methodName = BindingGeneratorImpl.getterMethodName(node.localName, Types.typeForClass(type));
+        var clz = object.class;
+        if (object instanceof DataContainer) {
+            clz = (object as DataContainer).implementedInterface;
+        }
+        val method = clz.getMethod(methodName);
+        if (method === null) {
+            return null;
+        }
+        val value = method.invoke(object);
+        if (value === null) {
+            return null;
+        }
+        if (type.isAssignableFrom(value.class)) {
+            return value  as T;
+        }
+        return value.getEncapsulatedValue(type);
+    }
+
+    private def <T> T getEncapsulatedValue(Object value, Class<T> type) {
+        val method = value.class.getMethod("getValue");
+        if (method !== null && type.isAssignableFrom(method.returnType)) {
+            return method.invoke(value) as T;
+        }
+        return null;
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(DataContainer data, GeneratedTypeBuilder builder,
+        SchemaNode node) {
+        return Collections.<Node<?>>singletonList(data.toDataDom(node, builder));
+    }
+
+    private def dispatch List<Node<?>> serializeValueImpl(Object object, GeneratedTypeBuilder builder,
+        SchemaNode node) {
+    }
+
+    def DataObject toDataObject(CompositeNode node, ClassLoader loader, GeneratedType type, SchemaNode schema) {
+
+        // Nasty reflection hack (for now)
+        val builderClass = loader.loadClass(type.builderFQN);
+        val builder = builderClass.newInstance;
+        val buildMethod = builderClass.getMethod("build");
+
+        node.fillDataObject(builder, loader, type, schema);
+
+        return buildMethod.invoke(builder) as DataObject;
+    }
+
+    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+        ListSchemaNode schema) {
+
+        if (schema.keyDefinition !== null && !schema.keyDefinition.empty) {
+
+            val value = node.keyToBindingKey(loader, type, schema);
+            builder.setProperty("key", value);
+        }
+    }
+
+    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+        ContainerSchemaNode schema) {
+    }
+
+    
+    def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
+        val keyClass = loader.loadClass(type.keyFQN);
+        val constructor = keyClass.constructors.get(0);
+        val keyType = type.keyTypeProperties;
+        val args = new ArrayList();
+        for (key : schema.keyDefinition) {
+            val keyProperty = keyType.get(BindingGeneratorUtil.parseToClassName(key.localName));
+            val domKeyValue = node.getFirstSimpleByName(key);
+            val keyValue = domKeyValue.deserializeSimpleValue(loader, keyProperty.returnType,
+                schema.getDataChildByName(key));
+            args.add(keyValue);
+        }
+        return ClassLoaderUtils.construct(constructor, args);
+    }
+
+    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        LeafSchemaNode node2) {
+        deserializeSimpleValueImpl(node, loader, type, node2.type);
+    }
+
+    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        LeafListSchemaNode node2) {
+        deserializeSimpleValueImpl(node, loader, type, node2.type);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        ExtendedType definition) {
+        deserializeSimpleValueImpl(node, loader, type, definition.baseType);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        StringTypeDefinition definition) {
+        if (type instanceof GeneratedTransferObject) {
+            val cls = loader.getClassForType(type);
+            val const = cls.getConstructor(String);
+            val str = String.valueOf(node.value);
+            return const.newInstance(str);
+        }
+        return node.value;
+    }
+
+    def Class<?> getClassForType(ClassLoader loader, Type type) {
+        loader.loadClass(type.fullyQualifiedName);
+    }
+
+    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+        TypeDefinition definition) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+    def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
+        val method = FluentIterable.from(type.methodDefinitions).findFirst[name == "getKey"]
+        val key = method.returnType as GeneratedTransferObject;
+        val ret = new HashMap<String, GeneratedProperty>();
+        for (prop : key.properties) {
+            ret.put(prop.name, prop);
+        }
+        return ret;
+    }
+
+    def void setProperty(Object object, String property, Object value) {
+        val cls = object.class;
+        val valMethod = cls.getMethod("set" + property.toFirstUpper, value.class);
+        if (valMethod != null)
+            valMethod.invoke(object, value);
+    }
+
+    def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
+
+    def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
+
+}
+
+@Data
+class PropertyCapture {
+
+    @Property
+    val Type returnType;
+    @Property
+    val String name;
+
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java
new file mode 100644 (file)
index 0000000..c96835b
--- /dev/null
@@ -0,0 +1,73 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Broker, Broker> {
+
+    BindingIndependentDataServiceConnector dataConnector;
+    BindingIndependentMappingService mappingService;
+
+    private final DataProviderService baDataService;
+    private BundleContext context;
+
+    private ServiceTracker<Broker, Broker> brokerTracker;
+
+    public ConnectorActivator(DataProviderService dataService, BundleContext context) {
+        baDataService = dataService;
+        this.context = context;
+        brokerTracker = new ServiceTracker<>(context, Broker.class, this);
+    }
+
+    @Override
+    public Collection<ProviderFunctionality> getProviderFunctionality() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+
+        MappingServiceImpl mappingImpl = new MappingServiceImpl();
+        mappingImpl.setSchemaService(session.getService(SchemaService.class));
+        mappingImpl.start();
+
+        mappingService = mappingImpl;
+        dataConnector = new BindingIndependentDataServiceConnector();
+        dataConnector.setBaDataService(baDataService);
+        dataConnector.setBiDataService(session.getService(DataBrokerService.class));
+        dataConnector.setMappingService(mappingService);
+        dataConnector.start();
+    }
+
+    @Override
+    public Broker addingService(ServiceReference<Broker> reference) {
+        Broker br= context.getService(reference);
+        br.registerProvider(this, context);
+        return br;
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<Broker> reference, Broker service) {
+        // NOOP
+    }
+
+    @Override
+    public void removedService(ServiceReference<Broker> reference, Broker service) {
+        // NOOP
+    }
+
+    public void start() {
+        brokerTracker.open();
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/Constants.java
new file mode 100644 (file)
index 0000000..1c9a59d
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class Constants {
+    public static final Class<byte[]> BYTES_CLASS = byte[].class;
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/MappingServiceImpl.xtend
new file mode 100644 (file)
index 0000000..84a0065
--- /dev/null
@@ -0,0 +1,68 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.yangtools.sal.binding.model.api.CodeGenerator
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import java.util.Collections
+import java.util.Map.Entry
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.AbstractMap.SimpleEntry
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+
+class MappingServiceImpl implements SchemaServiceListener, BindingIndependentMappingService {
+
+    var extension BindingMapping mapping = new BindingMapping;
+
+    @Property
+    BindingGeneratorImpl binding;
+
+    @Property
+    SchemaService schemaService;
+
+    override onGlobalContextUpdated(SchemaContext arg0) {
+        recreateBindingContext(arg0);
+    }
+
+    def recreateBindingContext(SchemaContext schemaContext) {
+        val newBinding = new BindingGeneratorImpl();
+        newBinding.generateTypes(schemaContext);
+        val newMapping = new BindingMapping();
+        for (entry : newBinding.moduleContexts.entrySet) {
+            val module = entry.key;
+            val context = entry.value;
+            
+            newMapping.updateBinding(schemaContext, context);
+        }
+        mapping = newMapping
+    }
+
+    override CompositeNode toDataDom(DataObject data) {
+        mapping.toCompositeNode(data);
+    }
+
+    override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+        Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+        val key = mapping.toDataDom(entry.key);
+        val data = mapping.toCompositeNode(entry.value);
+        return new SimpleEntry(key, data);
+    }
+
+    override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+        InstanceIdentifier<? extends DataObject> path) {
+        return mapping.toDataDom(path);
+    }
+    
+    override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) {
+        return mapping.dataObjectFromDataDom(path,result);
+    }
+    
+    public def void start() {
+        schemaService.registerSchemaServiceListener(this);
+        recreateBindingContext(schemaService.globalContext);
+    }
+}
@@ -1,10 +1,17 @@
-package org.opendaylight.controller.sal.binding.impl.osgi;
+package org.opendaylight.controller.sal.binding.impl.util;
 
 
 
 import java.util.concurrent.Callable;
+
 import static com.google.common.base.Preconditions.*;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+import org.opendaylight.yangtools.yang.binding.Identifier;
+
 public class ClassLoaderUtils {
     
     public static <V> V withClassLoader(ClassLoader cls,Callable<V> function) throws Exception {
@@ -21,4 +28,9 @@ public class ClassLoaderUtils {
             throw new Exception(e);
         }
     }
+
+    public static Object construct(Constructor<? extends Object> constructor, ArrayList<Object> objects) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    Object[] initargs = objects.toArray(new Object[]{});
+    return constructor.newInstance(initargs);
+    }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java
new file mode 100644 (file)
index 0000000..0448238
--- /dev/null
@@ -0,0 +1,136 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+public class BrokerIntegrationTest {
+
+    DataBrokerService biDataService;
+    DataProviderService baDataService;
+    private MappingServiceImpl mappingServiceImpl;
+    private MappingServiceImpl mappingService;
+    private DataBrokerImpl baDataImpl;
+    private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
+    private ListeningExecutorService executor;
+    private BindingIndependentDataServiceConnector connectorServiceImpl;
+    private HashMapDataStore dataStore;
+    
+    
+    @Before
+    public void setUp() {
+        executor = MoreExecutors.sameThreadExecutor();
+        baDataImpl = new DataBrokerImpl();
+        baDataService = baDataImpl;
+        baDataImpl.setExecutor(executor);
+        
+        biDataImpl = new org.opendaylight.controller.sal.dom.broker.DataBrokerImpl();
+        biDataService =  biDataImpl;
+        biDataImpl.setExecutor(executor);
+        
+        dataStore = new HashMapDataStore();
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier treeRoot = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.builder().toInstance();
+        biDataImpl.registerConfigurationReader(treeRoot, dataStore);
+        biDataImpl.registerOperationalReader(treeRoot, dataStore);
+        biDataImpl.registerCommitHandler(treeRoot, dataStore);
+        
+        mappingServiceImpl = new MappingServiceImpl();
+        mappingService = mappingServiceImpl;
+        
+        
+        connectorServiceImpl = new BindingIndependentDataServiceConnector();
+        connectorServiceImpl.setBaDataService(baDataService);
+        connectorServiceImpl.setBiDataService(biDataService);
+        connectorServiceImpl.setMappingService(mappingServiceImpl);
+        connectorServiceImpl.start();
+        
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+        "node-inventory.yang" };
+        
+        mappingService.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+    }
+    
+    @Test
+    public void simpleModifyOperation() throws Exception {
+        
+        DataModificationTransaction transaction = baDataService.beginTransaction();
+        assertNotNull(transaction);
+        
+        NodeRef node1 = createNodeRef("0");
+        DataObject  node = baDataService.readConfigurationData(node1.getValue());
+        assertNull(node);
+        Node nodeData1 = createNode("0");
+        
+        transaction.putConfigurationData(node1.getValue(), nodeData1);
+        Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
+        assertNotNull(commitResult);
+        
+        RpcResult<TransactionStatus> result = commitResult.get();
+        
+        assertNotNull(result);
+        assertNotNull(result.getResult());
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        Node readedData = (Node) baDataService.readConfigurationData(node1.getValue());
+        assertNotNull(readedData);
+        assertEquals(nodeData1.getKey(), readedData.getKey());
+        
+        
+        DataModificationTransaction transaction2 = baDataService.beginTransaction();
+        assertNotNull(transaction);
+        
+        transaction2.removeConfigurationData(node1.getValue());
+        
+        Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
+        assertNotNull(commitResult2);
+        
+        RpcResult<TransactionStatus> result2 = commitResult2.get();
+        
+        assertNotNull(result2);
+        assertNotNull(result2.getResult());
+        assertEquals(TransactionStatus.COMMITED, result2.getResult());
+    
+        DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());
+        assertNull(readedData2);
+    }
+    
+    private static NodeRef createNodeRef(String string) {
+        NodeKey key = new NodeKey(new NodeId(string));
+        InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).node(Node.class, key)
+                .toInstance();
+        return new NodeRef(path);
+    }
+    
+    private static Node createNode(String string) {
+        NodeBuilder ret = new NodeBuilder();
+        ret.setId(new NodeId(string));
+        ret.setKey(new NodeKey(ret.getId()));
+        return ret.build();
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/MappingServiceTest.java
new file mode 100644 (file)
index 0000000..b0c2e75
--- /dev/null
@@ -0,0 +1,118 @@
+package org.opendaylight.controller.sal.binding.test.connect.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleContext;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+
+public class MappingServiceTest {
+
+    private static final QName NODES = QName.create("urn:opendaylight:inventory", "2013-08-19", "nodes");
+    private static final QName NODE = QName.create(NODES,"node");
+    private static final QName ID = QName.create(NODES,"id");
+    
+    BindingIndependentMappingService service;
+    private MappingServiceImpl impl;
+
+    @Before
+    public void setUp() {
+        impl = new MappingServiceImpl();
+        service = impl;
+    }
+
+    @Test
+    public void baDataToBiData() throws Exception {
+
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+                "node-inventory.yang" };
+
+        SchemaContext ctx = getContext(yangFiles);
+
+        impl.onGlobalContextUpdated(ctx);
+
+        NodesBuilder nodes = new NodesBuilder();
+
+        List<Node> nodeList = new ArrayList<>();
+        nodeList.add(createChildNode("foo"));
+        nodeList.add(createChildNode("bar"));
+
+        nodes.setNode(nodeList);
+        Nodes nodesTO = nodes.build();
+        CompositeNode xmlNodes = service.toDataDom(nodesTO);
+        assertNotNull(xmlNodes);
+        List<CompositeNode> invNodes = xmlNodes.getCompositesByName(NODE);
+        assertNotNull(invNodes);
+        assertEquals(2, invNodes.size());
+    }
+
+    @Test
+    public void instanceIdentifierTest() throws Exception {
+
+        String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
+                "node-inventory.yang" };
+        SchemaContext ctx = getContext(yangFiles);
+        impl.onGlobalContextUpdated(ctx);
+
+        NodeKey nodeKey = new NodeKey(new NodeId("foo"));
+        InstanceIdentifier<Node> path = InstanceIdentifier.builder().node(Nodes.class).child(Node.class, nodeKey).toInstance();
+        org.opendaylight.yangtools.yang.data.api.InstanceIdentifier result = service.toDataDom(path);
+        assertNotNull(result);
+        assertEquals(2, result.getPath().size());
+    }
+
+    public static SchemaContext getContext(String[] yangFiles) {
+
+        ClassLoader loader = MappingServiceTest.class.getClassLoader();
+
+        List<InputStream> streams = new ArrayList<>();
+        for (String string : yangFiles) {
+            InputStream stream = loader.getResourceAsStream("META-INF/yang/" + string);
+            streams.add(stream);
+
+        }
+        YangParserImpl parser = new YangParserImpl();
+
+        Set<Module> modules = parser.parseYangModelsFromStreams(streams);
+        return parser.resolveSchemaContext(modules);
+    }
+
+    private Node createChildNode(String id) {
+        NodeBuilder node = new NodeBuilder();
+        NodeId nodeId = new NodeId(id);
+
+        node.setId(nodeId);
+        node.setKey(new NodeKey(nodeId));
+
+        FlowCapableNodeBuilder aug = new FlowCapableNodeBuilder();
+        aug.setManufacturer(id);
+        node.addAugmentation(FlowCapableNode.class, aug.build());
+
+        return node.build();
+    }
+
+}
index 6638050ae0bc1484b8e9b476616a1b1899181bf9..3bc50cdd2ed1aecbf55d791f0c3fe02d9ed1bd04 100644 (file)
@@ -52,7 +52,7 @@
                     <dependency>
                         <groupId>org.opendaylight.controller</groupId>
                         <artifactId>yang-jmx-generator-plugin</artifactId>
-                        <version>0.2.2-SNAPSHOT</version>
+                        <version>0.2.3-SNAPSHOT</version>
                     </dependency>
                 </dependencies>
             </plugin>
@@ -82,7 +82,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.2-SNAPSHOT</version>
+            <version>0.2.3-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
index 2b632b4ab0bccfaf1e34df182afe8d9c53021f05..e242b9ecee2c3e8f9cc8ff1d9b777a036d1f07eb 100644 (file)
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>config-manager</artifactId>
-      <version>0.2.2-SNAPSHOT</version>
+      <version>0.2.3-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <version>1.0-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+            <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+            <version>4.0</version>
+    </dependency>
   </dependencies>
 </project>
index 3e3ee3a8742e1af5ca3a14a30382217064e1d931..2f9c397632795d334799f32030be734fe38ae113 100644 (file)
@@ -25,6 +25,7 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "sal-common-api").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "sal-common-impl").versionAsInProject(), //
                 
+                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
                 mavenBundle("com.google.guava", "guava").versionAsInProject(), //
                 mavenBundle(YANGTOOLS + ".thirdparty", "xtend-lib-osgi").versionAsInProject() //
         );
@@ -44,8 +45,32 @@ public class TestHelper {
                 mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
                 mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
                 mavenBundle("org.javassist", "javassist").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject() //
-        );
+                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+        
+                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                
+                
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+                
+                
+                mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+                
+                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject() //
+       );
 
     }
 
index d26f2e7aa161fe4dbb247f301db414cfa703c4ff..e1f109b88dc2e923f8580b47e57c1795cc50d947 100644 (file)
@@ -11,6 +11,7 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
@@ -21,9 +22,15 @@ import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
+import com.google.inject.Inject;
+
 public class DataServiceTest extends AbstractTest {
 
     protected DataBrokerService consumerDataService;
+    
+    
+    @Inject
+    Broker broker2;
 
     @Before
     public void setUp() throws Exception {
@@ -61,9 +68,9 @@ public class DataServiceTest extends AbstractTest {
         assertNotNull(result.getResult());
         assertEquals(TransactionStatus.COMMITED, result.getResult());
         
-        DataObject readedData = consumerDataService.readConfigurationData(node1.getValue());
+        Node readedData = (Node) consumerDataService.readConfigurationData(node1.getValue());
         assertNotNull(readedData);
-        assertEquals(nodeData1, readedData);
+        assertEquals(nodeData1.getKey(), readedData.getKey());
         
         
         DataModificationTransaction transaction2 = consumerDataService.beginTransaction();
@@ -97,7 +104,9 @@ public class DataServiceTest extends AbstractTest {
     
     private static Node createNode(String string) {
         NodeBuilder ret = new NodeBuilder();
-        ret.setId(new NodeId(string));
+        NodeId id = new NodeId(string);
+        ret.setKey(new NodeKey(id));
+        ret.setId(id);
         return ret.build();
     }
 }
index 3bd51ec7d8b68dabe567857101a098cf2d2f4928..7fb05806df36f1925a936fb49615212f64339a8d 100644 (file)
@@ -1,50 +1,59 @@
 <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>
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>sal-parent</artifactId>
-    <version>1.0-SNAPSHOT</version>
-  </parent>
-  <artifactId>sal-common-impl</artifactId>
-  <packaging>bundle</packaging>
-  <scm>
-    <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
-    <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
-    <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
-  </scm>
+    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>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>sal-parent</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>sal-common-impl</artifactId>
+    <packaging>bundle</packaging>
+    <scm>
+        <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+    </scm>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal-common-api</artifactId>
-      <version>1.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.xtend</groupId>
-      <artifactId>org.eclipse.xtend.lib</artifactId>
-    </dependency>
-  </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-common-api</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-common-util</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.xtend</groupId>
+            <artifactId>org.eclipse.xtend.lib</artifactId>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <configuration>
-          <instructions>
-            <Export-Package>
-                org.opendaylight.controller.md.sal.common.impl,
-                org.opendaylight.controller.md.sal.common.impl.*
-            </Export-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.opendaylight.controller.md.sal.common.impl,
+                            org.opendaylight.controller.md.sal.common.impl.*
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
 
 </project>
index f83c61f8049205977e998c61295072fe84176624..d6b3c5334aa1c4d02563d51cef0a0d27d8939c61 100644 (file)
@@ -35,7 +35,7 @@ public abstract class AbstractDataReadRouter<P extends Path<?>, D> implements Da
     @Override
     public D readOperationalData(P path) {
         FluentIterable<D> dataBits = FluentIterable //
-                .from(getReaders(configReaders, path)).transform(operationalRead(path));
+                .from(getReaders(operationalReaders, path)).transform(operationalRead(path));
         return merge(path,dataBits);
 
     }
@@ -75,7 +75,7 @@ public abstract class AbstractDataReadRouter<P extends Path<?>, D> implements Da
         return new Function<DataReader<P, D>, D>() {
             @Override
             public D apply(DataReader<P, D> input) {
-                return input.readConfigurationData(path);
+                return input.readOperationalData(path);
             }
         };
     }
diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.xtend
new file mode 100644 (file)
index 0000000..b878071
--- /dev/null
@@ -0,0 +1,259 @@
+package org.opendaylight.controller.md.sal.common.impl.service
+
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
+import org.opendaylight.yangtools.concepts.ListenerRegistration
+import com.google.common.collect.Multimap
+import static com.google.common.base.Preconditions.*;
+import java.util.List
+import com.google.common.collect.HashMultimap
+import java.util.concurrent.ExecutorService
+import java.util.concurrent.Callable
+import org.opendaylight.yangtools.yang.common.RpcResult
+import java.util.Collections
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
+import java.util.ArrayList
+import org.opendaylight.yangtools.concepts.CompositeObjectRegistration
+import java.util.Arrays
+import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
+import org.opendaylight.controller.md.sal.common.api.data.DataModificationTransactionFactory
+import org.opendaylight.controller.md.sal.common.api.data.DataChangePublisher
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeListener
+import org.opendaylight.controller.sal.common.util.Rpcs
+import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification
+import java.util.concurrent.Future
+import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
+import org.opendaylight.yangtools.concepts.Path
+import org.slf4j.LoggerFactory
+
+abstract class AbstractDataBroker<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> implements 
+DataModificationTransactionFactory<P, D>, //
+DataReader<P, D>, //
+DataChangePublisher<P, D, DCL>, //
+DataProvisionService<P,D> {
+
+    @Property
+    var ExecutorService executor;
+
+    @Property
+    var AbstractDataReadRouter<P,D> dataReadRouter;
+
+    Multimap<P, DataChangeListenerRegistration<P,D,DCL>> listeners = HashMultimap.create();
+    Multimap<P, DataCommitHandlerRegistration<P,D>> commitHandlers = HashMultimap.create();
+
+
+    public new() {
+        
+    }
+
+    override final readConfigurationData(P path) {
+        return dataReadRouter.readConfigurationData(path);
+    }
+
+    override final readOperationalData(P path) {
+        return dataReadRouter.readOperationalData(path);
+    }
+
+    override final registerCommitHandler(P path,
+        DataCommitHandler<P, D> commitHandler) {
+            val registration = new DataCommitHandlerRegistration(path,commitHandler,this);
+            commitHandlers.put(path,registration)
+            return registration;
+    }
+
+    override final def registerDataChangeListener(P path, DCL listener) {
+        val reg = new DataChangeListenerRegistration(path, listener, this);
+        listeners.put(path, reg);
+        return reg;
+    }
+
+     final def registerDataReader(P path,DataReader<P,D> reader) {
+        
+        val confReg = dataReadRouter.registerConfigurationReader(path,reader);
+        val dataReg = dataReadRouter.registerOperationalReader(path,reader);
+        
+        return new CompositeObjectRegistration(reader,Arrays.asList(confReg,dataReg));
+    }
+
+    protected  final def removeListener(DataChangeListenerRegistration<P,D,DCL> registration) {
+        listeners.remove(registration.path, registration);
+    }
+
+    protected  final def removeCommitHandler(DataCommitHandlerRegistration<P,D> registration) {
+        commitHandlers.remove(registration.path, registration);
+    }
+    
+    protected  final def getActiveCommitHandlers() {
+        return commitHandlers.entries.map[ value.instance].toSet
+    }
+
+    package final def Future<RpcResult<TransactionStatus>>  commit(AbstractDataTransaction<P,D> transaction) {
+        checkNotNull(transaction);
+        transaction.changeStatus(TransactionStatus.SUBMITED);
+        val task = new TwoPhaseCommit(transaction, this);
+        return executor.submit(task);
+    }
+
+}
+
+package class DataChangeListenerRegistration<P extends Path<P>,D,DCL extends DataChangeListener<P,D>> extends AbstractObjectRegistration<DCL> implements ListenerRegistration<DCL> {
+
+    AbstractDataBroker<P,D,DCL> dataBroker;
+
+    @Property
+    val P path;
+
+    new(P path, DCL instance, AbstractDataBroker<P,D,DCL> broker) {
+        super(instance)
+        dataBroker = broker;
+        _path = path;
+    }
+
+    override protected removeRegistration() {
+        dataBroker.removeListener(this);
+        dataBroker = null;
+    }
+
+}
+
+package class DataCommitHandlerRegistration<P extends Path<P>,D>
+extends AbstractObjectRegistration<DataCommitHandler<P, D>> {
+
+    AbstractDataBroker<P,D,?> dataBroker;
+
+    @Property
+    val P path;
+
+    new(P path, DataCommitHandler<P, D> instance,
+        AbstractDataBroker<P,D,?> broker) {
+        super(instance)
+        dataBroker = broker;
+        _path = path;
+    }
+
+    override protected removeRegistration() {
+        dataBroker.removeCommitHandler(this);
+        dataBroker = null;
+    }
+
+}
+
+package class TwoPhaseCommit<P extends Path<P>,D> implements Callable<RpcResult<TransactionStatus>> {
+    
+    private static val log = LoggerFactory.getLogger(TwoPhaseCommit);
+
+    val AbstractDataTransaction<P,D> transaction;
+    val AbstractDataBroker<P,D,?> dataBroker;
+
+    new(AbstractDataTransaction<P,D> transaction, AbstractDataBroker<P,D,?> broker) {
+        this.transaction = transaction;
+        this.dataBroker = broker;
+    }
+
+    override call() throws Exception {
+
+        val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.activeCommitHandlers;
+
+        // requesting commits
+        val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();
+        try {
+            for (handler : commitHandlers) {
+                handlerTransactions.add(handler.requestCommit(transaction));
+            }
+        } catch (Exception e) {
+            log.error("Request Commit failded",e);
+            return rollback(handlerTransactions,e);
+        }
+        val List<RpcResult<Void>> results = new ArrayList();
+        try {
+            for (subtransaction : handlerTransactions) {
+                results.add(subtransaction.finish());
+            }
+        } catch (Exception e) {
+            log.error("Finish Commit failed",e);
+            return rollback(handlerTransactions,e);
+        }
+
+        return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());
+    }
+
+    def rollback(List<DataCommitTransaction<P, D>> transactions,Exception e) {
+        for (transaction : transactions) {
+            transaction.rollback()
+        }
+        // FIXME return encountered error.
+        return Rpcs.getRpcResult(false, TransactionStatus.FAILED, Collections.emptySet());
+    }
+}
+
+public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {
+
+    @Property
+    private val Object identifier;
+
+    
+    var TransactionStatus status;
+    
+    
+    var AbstractDataBroker<P, D, ?> broker;
+
+    protected new (AbstractDataBroker<P,D,?> dataBroker) {
+        super(dataBroker);
+        _identifier = new Object();
+        broker = dataBroker;
+        status = TransactionStatus.NEW;
+        //listeners = new ListenerRegistry<>();
+    }
+
+    override  commit() {
+        return broker.commit(this);
+    }
+
+    override readConfigurationData(P path) {
+        return broker.readConfigurationData(path);
+    }
+
+    override readOperationalData(P path) {
+        return broker.readOperationalData(path);
+    }
+
+    override hashCode() {
+        return identifier.hashCode;
+    }
+
+    override equals(Object obj) {
+        if (this === obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        val other = (obj as AbstractDataTransaction<P,D>) ;
+        if (broker == null) {
+            if (other.broker != null)
+                return false;
+        } else if (!broker.equals(other.broker))
+            return false;
+        if (identifier == null) {
+            if (other.identifier != null)
+                return false;
+        } else if (!identifier.equals(other.identifier))
+            return false;
+        return true;
+    }
+
+    override TransactionStatus getStatus() {
+        return status;
+    }
+
+    
+    protected abstract def void onStatusChange(TransactionStatus status);
+    
+    public def changeStatus(TransactionStatus status) {
+        this.status = status;
+        onStatusChange(status);
+    }
+    
+}
index 8f6a5d0a90cb4fed609fb94a997c44ebe42ae02a..92542bc3455e497a6082fe64cf6607a290b30723 100644 (file)
@@ -1,8 +1,13 @@
 package org.opendaylight.controller.sal.core.api.mount;
 
 import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
 
-public interface MountProvisionInstance extends MountInstance, NotificationPublishService, RpcProvisionRegistry {
+public interface MountProvisionInstance extends //
+        MountInstance,//
+        NotificationPublishService, //
+        RpcProvisionRegistry,//
+        DataProviderService {
 
 }
index 530b02b733a0ea945ddad4018a2d29e4f8050705..3180271c935311a64bb69a66b7264ab1ef72cb2a 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.controller.sal.core.api.mount;
 
+import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 
-public interface MountService {
+public interface MountService extends BrokerService {
 
     MountInstance getMountPoint(InstanceIdentifier path);
 }
index 74dd1a99012a0565e16963149fb84f46dc5a6c7f..62dbe16e4135de42001f6fde721799128b8dbebd 100644 (file)
             <artifactId>sal-common-util</artifactId>
             <version>1.0-SNAPSHOT</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-impl</artifactId>
+            <version>0.5.9-SNAPSHOT</version>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-common-impl</artifactId>
@@ -55,7 +61,7 @@
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.2-SNAPSHOT</version>
+            <version>0.2.3-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index 2bab4dbd26ca5896f3703978171e5ff72274b9db..3af645a2b8a48753b79659f58877c1044ff83394 100644 (file)
@@ -6,6 +6,10 @@ import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.core.api.mount.MountService;
+import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -13,6 +17,7 @@ import org.osgi.framework.ServiceRegistration;
 
 public class BrokerActivator implements BundleActivator {
 
+    private static final InstanceIdentifier ROOT = InstanceIdentifier.builder().toInstance();
     BrokerImpl broker;
     private ServiceRegistration<Broker> brokerReg;
     private ServiceRegistration<SchemaService> schemaReg;
@@ -20,13 +25,17 @@ public class BrokerActivator implements BundleActivator {
     private ServiceRegistration<DataProviderService> dataProviderReg;
     private SchemaServiceImpl schemaService;
     private DataBrokerImpl dataService;
+    private MountPointManagerImpl mountService;
+    private ServiceRegistration<MountService> mountReg;
+    private ServiceRegistration<MountProvisionService> mountProviderReg;
+    private HashMapDataStore hashMapStore;
 
     @Override
     public void start(BundleContext context) throws Exception {
         Hashtable<String, String> emptyProperties = new Hashtable<String, String>();
         broker = new BrokerImpl();
         broker.setBundleContext(context);
-        brokerReg = context.registerService(Broker.class, broker, emptyProperties);
+        
 
         schemaService = new SchemaServiceImpl();
         schemaService.setContext(context);
@@ -35,10 +44,24 @@ public class BrokerActivator implements BundleActivator {
         schemaReg = context.registerService(SchemaService.class, schemaService, new Hashtable<String, String>());
         
         dataService = new DataBrokerImpl();
+        dataService.setExecutor(broker.getExecutor());
+        
         dataReg = context.registerService(DataBrokerService.class, dataService, emptyProperties);
         dataProviderReg = context.registerService(DataProviderService.class, dataService, emptyProperties);
         
+        hashMapStore = new HashMapDataStore();
+        
+        dataService.registerConfigurationReader(ROOT, hashMapStore);
+        dataService.registerCommitHandler(ROOT, hashMapStore);
+        dataService.registerOperationalReader(ROOT, hashMapStore);
         
+        mountService = new MountPointManagerImpl();
+        mountService.setDataBroker(dataService);
+        
+        mountReg = context.registerService(MountService.class, mountService, emptyProperties);
+        mountProviderReg =  context.registerService(MountProvisionService.class, mountService, emptyProperties);
+        
+        brokerReg = context.registerService(Broker.class, broker, emptyProperties);
     }
 
     @Override
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.java
new file mode 100644 (file)
index 0000000..d95fdcc
--- /dev/null
@@ -0,0 +1,66 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
+import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataBrokerImpl extends AbstractDataBroker<InstanceIdentifier, CompositeNode, DataChangeListener> implements
+        DataProviderService {
+
+    public DataBrokerImpl() {
+        setDataReadRouter(new DataReaderRouter());
+    }
+
+    @Override
+    public DataTransactionImpl beginTransaction() {
+        return new DataTransactionImpl(this);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
+            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+        return getDataReadRouter().registerConfigurationReader(path, reader);
+    }
+
+    @Override
+    public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
+            InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
+        return getDataReadRouter().registerOperationalReader(path, reader);
+    }
+
+    @Deprecated
+    @Override
+    public void addValidator(DataStoreIdentifier store, DataValidator validator) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+        // TODO Auto-generated method stub
+
+    }
+
+    @Deprecated
+    @Override
+    public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+        // TODO Auto-generated method stub
+
+    }
+
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataBrokerImpl.xtend
deleted file mode 100644 (file)
index 8a17c83..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.opendaylight.controller.sal.dom.broker
-
-import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.controller.sal.common.DataStoreIdentifier
-import org.opendaylight.controller.sal.core.api.data.DataProviderService.DataRefresher
-import org.opendaylight.controller.sal.core.api.data.DataValidator
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter
-import org.opendaylight.controller.sal.core.api.data.DataChangeListener
-import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.controller.md.sal.common.api.data.DataReader
-
-class DataBrokerImpl implements DataProviderService {
-
-    val readRouter = new DataReaderRouter();
-
-    override addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // NOOP
-    }
-
-    override addValidator(DataStoreIdentifier store, DataValidator validator) {
-        // NOOP
-    }
-
-    override beginTransaction() {
-        // NOOP
-    }
-
-    override readConfigurationData(InstanceIdentifier path) {
-        readRouter.readConfigurationData(path)
-    }
-
-    override readOperationalData(InstanceIdentifier path) {
-        readRouter.readOperationalData(path)
-    }
-
-    override registerConfigurationReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
-        readRouter.registerConfigurationReader(path, reader);
-    }
-
-    override registerOperationalReader(InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
-        readRouter.registerOperationalReader(path, reader);
-    }
-
-    override removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
-        // NOOP
-    }
-
-    override removeValidator(DataStoreIdentifier store, DataValidator validator) {
-        // NOOP
-    }
-
-    override registerDataChangeListener(InstanceIdentifier path, DataChangeListener listener) {
-        // NOOP
-    }
-
-    override registerCommitHandler(InstanceIdentifier path,
-        DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
-        // NOOP
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/DataTransactionImpl.java
new file mode 100644 (file)
index 0000000..5cb01c9
--- /dev/null
@@ -0,0 +1,31 @@
+package org.opendaylight.controller.sal.dom.broker;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class DataTransactionImpl extends AbstractDataTransaction<InstanceIdentifier, CompositeNode> 
+    implements DataModificationTransaction {
+    private final ListenerRegistry<DataTransactionListener> listeners = new ListenerRegistry<DataTransactionListener>();
+    
+    
+    
+    public DataTransactionImpl(DataBrokerImpl dataBroker) {
+        super(dataBroker);
+    }
+
+    @Override
+    public ListenerRegistration<DataTransactionListener> registerListener(DataTransactionListener listener) {
+        return listeners.register(listener);
+    }
+
+    protected void onStatusChange(TransactionStatus status) {
+        for (ListenerRegistration<DataTransactionListener> listenerRegistration : listeners) {
+            listenerRegistration.getInstance().onStatusUpdated(this, status);
+        }
+    }
+}
\ No newline at end of file
index 7037b46ce978dea4d717692498e526c8706cb7a8..eafc402ddcea6987b82980b5a2d92ffec5443108 100644 (file)
@@ -1,15 +1,19 @@
 package org.opendaylight.controller.sal.dom.broker;
 
+import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Future;
 
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
 import org.opendaylight.controller.sal.core.api.RpcImplementation;
 import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
 import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.core.api.data.DataValidator;
 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
@@ -23,17 +27,33 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 
 public class MountPointImpl implements MountProvisionInstance {
 
-    final RpcRouter rpcs;
-    final DataReaderRouter dataReader;
-    final NotificationRouter notificationRouter;
+    private final RpcRouter rpcs;
+    private final DataReaderRouter dataReader;
+    private final NotificationRouter notificationRouter;
+    private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
+    
+    
+    private final InstanceIdentifier mountPath;
 
     public MountPointImpl(InstanceIdentifier path) {
+        this.mountPath = path;
         rpcs = new RpcRouterImpl("");
         dataReader = new DataReaderRouter();
         notificationRouter = new NotificationRouterImpl();
+        readWrapper = new ReadWrapper();
+    }
+
+    public InstanceIdentifier getMountPath() {
+        return mountPath;
+    }
+
+    public DataReader<InstanceIdentifier, CompositeNode> getReadWrapper() {
+        return readWrapper;
     }
 
     @Override
@@ -113,6 +133,62 @@ public class MountPointImpl implements MountProvisionInstance {
     @Override
     public void sendNotification(CompositeNode notification) {
         publish(notification);
+    }
+    
+    @Override
+    public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
+            InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+    
+    @Override
+    public void removeRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+     // NOOP
+    }
+    
+    @Override
+    public void addRefresher(DataStoreIdentifier store, DataRefresher refresher) {
+     // NOOP
+    }
+    
+    @Override
+    public void addValidator(DataStoreIdentifier store, DataValidator validator) {
+     // NOOP
+    }
+    @Override
+    public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
+        // NOOP
+    }
+    
+    class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
+        
+        
+        private InstanceIdentifier shortenPath(InstanceIdentifier path) {
+            InstanceIdentifier ret = null;
+            if(mountPath.contains(path)) {
+                List<PathArgument> newArgs = path.getPath().subList(mountPath.getPath().size(), path.getPath().size());
+                ret = new InstanceIdentifier(newArgs);
+            }
+            return ret;
+        }
+        
+        @Override
+        public CompositeNode readConfigurationData(InstanceIdentifier path) {
+            InstanceIdentifier newPath = shortenPath(path);
+            if(newPath == null) {
+                return null;
+            }
+            return MountPointImpl.this.readConfigurationData(newPath);
+        }
         
+        @Override
+        public CompositeNode readOperationalData(InstanceIdentifier path) {
+            InstanceIdentifier newPath = shortenPath(path);
+            if(newPath == null) {
+                return null;
+            }
+            return MountPointImpl.this.readOperationalData(newPath);
+        }
     }
 }
index c64d1e56dd9638d28d9dee0d1d508aaead85e030..19634d79c2203fafe5aaa0156c41bf45a62f905f 100644 (file)
@@ -6,15 +6,27 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import java.util.concurrent.ConcurrentMap
 import java.util.concurrent.ConcurrentHashMap
 import static com.google.common.base.Preconditions.*;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService
 
 class MountPointManagerImpl implements MountProvisionService {
     
+    @Property
+    DataProviderService dataBroker;
+    
     ConcurrentMap<InstanceIdentifier,MountPointImpl> mounts = new ConcurrentHashMap();
     
     override createMountPoint(InstanceIdentifier path) {
         checkState(!mounts.containsKey(path),"Mount already created");
         val mount = new MountPointImpl(path);
+        registerMountPoint(mount);
         mounts.put(path,mount);
+        return mount;
+    }
+    
+    def registerMountPoint(MountPointImpl impl) {
+        dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
+        dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
+        
     }
     
     
@@ -30,6 +42,4 @@ class MountPointManagerImpl implements MountProvisionService {
     override getMountPoint(InstanceIdentifier path) {
         mounts.get(path);
     }
-    
-    
 }
index 1e0f3385ccf78bdf418261c15077d2d056fad1f1..fbed2ca113621c728dd00a5fa4b9ae932344d7db 100644 (file)
@@ -3,11 +3,16 @@ package org.opendaylight.controller.sal.dom.broker.impl
 import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
 import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
 
 class DataReaderRouter extends AbstractDataReadRouter<InstanceIdentifier, CompositeNode> {
 
     override protected merge(InstanceIdentifier path, Iterable<CompositeNode> data) {
-        return data.iterator.next
+        val iterator = data.iterator;
+        if(iterator.hasNext) {
+            return data.iterator.next
+        }
+        return null;
     }
 
 }
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataUtils.xtend
new file mode 100644 (file)
index 0000000..1a2f947
--- /dev/null
@@ -0,0 +1,50 @@
+package org.opendaylight.controller.sal.dom.broker.impl
+
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import java.util.Map
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import java.util.Map.Entry
+import java.util.HashSet
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+
+class DataUtils {
+
+    static def CompositeNode read(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
+        val root = map.get(path);
+        val childs = map.getChilds(path);
+        if(root === null && childs.empty) {
+            return null;
+        }
+        
+        return merge(path, root, childs);
+    }
+
+    static def CompositeNode merge(InstanceIdentifier path, CompositeNode node,
+        HashSet<Entry<InstanceIdentifier, CompositeNode>> entries) {
+        val it = new ArrayList<Node<?>>();
+        val qname = path.path.last.nodeType;
+        if (node != null) {
+            addAll(node.children);
+        }
+        for (entry : entries) {
+            val nesting = entry.key.path.size - path.path.size;
+            if (nesting === 1) {
+                add(entry.value);
+            }
+        }
+        return new CompositeNodeTOImpl(qname, null, it);
+    }
+
+    static def getChilds(Map<InstanceIdentifier, CompositeNode> map, InstanceIdentifier path) {
+        val it = new HashSet<Entry<InstanceIdentifier, CompositeNode>>();
+        for (entry : map.entrySet) {
+            if (path.contains(entry.key)) {
+                add(entry);
+            }
+        }
+        return it;
+    }
+
+}
@@ -1,10 +1,7 @@
-package org.opendaylight.controller.sal.binding.impl
+package org.opendaylight.controller.sal.dom.broker.impl
 
 import org.opendaylight.controller.md.sal.common.api.data.DataReader
-import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
-import org.opendaylight.yangtools.yang.binding.DataObject
 import org.opendaylight.controller.md.sal.common.api.data.DataModification
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction
 import org.opendaylight.yangtools.yang.common.RpcResult
@@ -12,58 +9,62 @@ import java.util.Map
 import java.util.concurrent.ConcurrentHashMap
 import org.opendaylight.controller.sal.common.util.Rpcs
 import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import static extension org.opendaylight.controller.sal.dom.broker.impl.DataUtils.*;
 
 class HashMapDataStore //
 implements //
-RuntimeDataProvider, DataCommitHandler<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataReader<InstanceIdentifier, CompositeNode>, DataCommitHandler<InstanceIdentifier, CompositeNode> {
 
-    val Map<InstanceIdentifier<? extends DataObject>,DataObject> configuration = new ConcurrentHashMap();
-    val Map<InstanceIdentifier<? extends DataObject>,DataObject> operational = new ConcurrentHashMap();
+    val Map<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap();
+    val Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap();
 
-
-    override readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
-        configuration.get(path);
+    override readConfigurationData(InstanceIdentifier path) {
+        configuration.read(path);
     }
 
-    override readOperationalData(InstanceIdentifier<? extends DataObject> path) {
-        operational.get(path);
+    override readOperationalData(InstanceIdentifier path) {
+        operational.read(path);
     }
+    
+
 
-    override requestCommit(DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification) {
-        return new HashMapDataStoreTransaction(modification,this);
+
+    override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
+        return new HashMapDataStoreTransaction(modification, this);
     }
-    
+
     def RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
-        return Rpcs.getRpcResult(true,null,Collections.emptySet);
+        return Rpcs.getRpcResult(true, null, Collections.emptySet);
     }
-    
+
     def RpcResult<Void> finish(HashMapDataStoreTransaction transaction) {
         val modification = transaction.modification;
         configuration.putAll(modification.updatedConfigurationData);
         operational.putAll(modification.updatedOperationalData);
-        
-        for(removal : modification.removedConfigurationData) {
+
+        for (removal : modification.removedConfigurationData) {
             configuration.remove(removal);
         }
-        for(removal : modification.removedOperationalData) {
+        for (removal : modification.removedOperationalData) {
             operational.remove(removal);
         }
-        return Rpcs.getRpcResult(true,null,Collections.emptySet);
+        return Rpcs.getRpcResult(true, null, Collections.emptySet);
     }
 
 }
 
 class HashMapDataStoreTransaction implements // 
-DataCommitTransaction<InstanceIdentifier<? extends DataObject>, DataObject> {
+DataCommitTransaction<InstanceIdentifier, CompositeNode> {
     @Property
-    val DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modification
+    val DataModification<InstanceIdentifier, CompositeNode> modification
 
     @Property
     val HashMapDataStore datastore;
-    
-    
+
     new(
-        DataModification<InstanceIdentifier<? extends DataObject>, DataObject> modify,
+        DataModification<InstanceIdentifier, CompositeNode> modify,
         HashMapDataStore store
     ) {
         _modification = modify;
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/MountProviderServiceProxy.java
new file mode 100644 (file)
index 0000000..0d18cb3
--- /dev/null
@@ -0,0 +1,27 @@
+package org.opendaylight.controller.sal.dom.broker.osgi;
+
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.osgi.framework.ServiceReference;
+
+public class MountProviderServiceProxy extends AbstractBrokerServiceProxy<MountProvisionService> implements MountProvisionService{
+
+    
+    public MountProviderServiceProxy(ServiceReference<MountProvisionService> ref, MountProvisionService delegate) {
+        super(ref, delegate);
+    }
+
+    public MountProvisionInstance getMountPoint(InstanceIdentifier path) {
+        return getDelegate().getMountPoint(path);
+    }
+
+    public MountProvisionInstance createMountPoint(InstanceIdentifier path) {
+        return getDelegate().createMountPoint(path);
+    }
+
+    public MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path) {
+        return getDelegate().createOrGetMountPoint(path);
+    }
+}
index eb738673cb9d724ab830cd16edc56f4d560e4c8b..938808facd58911411a60377b39061947ade2e23 100644 (file)
@@ -7,6 +7,7 @@ import org.opendaylight.controller.sal.core.api.data.DataProviderService
 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService
 import org.opendaylight.controller.sal.core.api.notify.NotificationService
 import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
 
 class ProxyFactory {
 
@@ -30,6 +31,11 @@ class ProxyFactory {
         new NotificationServiceProxy(ref as ServiceReference<NotificationService>, service);
     }
 
+    private static def dispatch createProxyImpl(ServiceReference<?> ref, MountProvisionService service) {
+        new MountProviderServiceProxy(ref as ServiceReference<MountProvisionService>, service);
+    }
+
+
     private static def dispatch createProxyImpl(ServiceReference<?> ref, SchemaService service) {
         new SchemaServiceProxy(ref as ServiceReference<SchemaService>, service);
     }
index 57e4d858c196beee2c9bf5a5d6ac04a7ed0d6d78..6ef5780c8a577c1bc93c97bd95420a50d608f5fc 100644 (file)
@@ -7,7 +7,7 @@
         <version>1.0-SNAPSHOT</version>
     </parent>
     <properties>
-        <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+        <netconf.version>0.2.3-SNAPSHOT</netconf.version>
     </properties>
     <artifactId>sal-netconf-connector</artifactId>
     <scm>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>netconf-client</artifactId>
-            <version>0.2.2-SNAPSHOT</version>
+            <version>${netconf.version}</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-data-impl</artifactId>
             <version>0.5.9-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-broker-impl</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+            <type>jar</type>
+        </dependency>
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
     </dependencies>
 
     <packaging>bundle</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-Activator>org.opendaylight.controller.sal.connect.netconf.NetconfProvider</Bundle-Activator>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/InventoryUtils.java
new file mode 100644 (file)
index 0000000..8350e39
--- /dev/null
@@ -0,0 +1,39 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.net.URI;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+public class InventoryUtils {
+
+    private static final URI INVENTORY_NAMESPACE = URI.create("urn:opendaylight:inventory");
+    private static final Date INVENTORY_REVISION = date();
+    public static final QName INVENTORY_NODES = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "nodes");
+    public static final QName INVENTORY_NODE = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "node");
+    public static final QName INVENTORY_ID = new QName(INVENTORY_NAMESPACE, INVENTORY_REVISION, "id");
+
+    public static final InstanceIdentifier INVENTORY_PATH = InstanceIdentifier.builder().node(INVENTORY_NODES)
+            .toInstance();
+    public static final QName NETCONF_INVENTORY_MOUNT = null;
+    
+    
+    
+    private static Date date() {
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            return formatter.parse("2013-08-19");
+        } catch (ParseException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    
+    
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDevice.xtend
new file mode 100644 (file)
index 0000000..0171c1f
--- /dev/null
@@ -0,0 +1,95 @@
+package org.opendaylight.controller.sal.connect.netconf
+
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.controller.md.sal.common.api.data.DataReader
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.controller.netconf.client.NetconfClient
+import org.opendaylight.controller.sal.core.api.RpcImplementation
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
+import java.net.InetSocketAddress
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.api.SimpleNode
+import org.opendaylight.yangtools.yang.common.QName
+import java.util.Collections
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import org.opendaylight.yangtools.concepts.Registration
+
+class NetconfDevice implements DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation {
+
+    var NetconfClient client;
+
+    @Property
+    var InetSocketAddress socketAddress;
+
+    @Property
+    val MountProvisionInstance mountInstance;
+
+    @Property
+    val InstanceIdentifier path;
+    
+    Registration<DataReader<InstanceIdentifier,CompositeNode>> operReaderReg
+    
+    Registration<DataReader<InstanceIdentifier,CompositeNode>> confReaderReg
+    
+    public new(MountProvisionInstance mount,InstanceIdentifier path) {
+        _mountInstance = mount;
+        _path = path;
+    }
+
+    def start(NetconfClientDispatcher dispatcher) {
+        client = new NetconfClient("sal-netconf-connector", socketAddress, dispatcher);
+        
+        confReaderReg = mountInstance.registerConfigurationReader(path,this);
+        operReaderReg = mountInstance.registerOperationalReader(path,this);
+    }
+
+    override readConfigurationData(InstanceIdentifier path) {
+        val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, path.toFilterStructure()));
+        val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
+        return data?.findNode(path) as CompositeNode;
+    }
+
+    override readOperationalData(InstanceIdentifier path) {
+        val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure()));
+        val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
+        return data?.findNode(path) as CompositeNode;
+    }
+
+    override getSupportedRpcs() {
+        Collections.emptySet;
+    }
+
+    override invokeRpc(QName rpc, CompositeNode input) {
+        val message = rpc.toRpcMessage(input);
+        val result = client.sendMessage(message);
+        return result.toRpcResult();
+    }
+
+    def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
+
+        var Node<?> current = node;
+        for (arg : identifier.path) {
+            if (current instanceof SimpleNode<?>) {
+                return null;
+            } else if (current instanceof CompositeNode) {
+                val currentComposite = (current as CompositeNode);
+
+                current = currentComposite.getFirstCompositeByName(arg.nodeType);
+                if (current == null) {
+                    current = currentComposite.getFirstSimpleByName(arg.nodeType);
+                }
+                if (current == null) {
+                    return null;
+                }
+            }
+        }
+        return current;
+    }
+    
+    public def stop() {
+        confReaderReg?.close()
+        operReaderReg?.close()
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfDeviceManager.xtend
new file mode 100644 (file)
index 0000000..2fe145e
--- /dev/null
@@ -0,0 +1,84 @@
+package org.opendaylight.controller.sal.connect.netconf
+
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
+import org.opendaylight.controller.md.sal.common.api.data.DataProvisionService
+import org.opendaylight.controller.sal.core.api.data.DataProviderService
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.QName
+import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
+import static extension org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils.*;
+
+import org.opendaylight.controller.sal.core.api.data.DataChangeListener
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent
+import java.util.Map
+import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
+import java.io.OptionalDataException
+import com.google.common.base.Optional
+import java.net.SocketAddress
+import java.net.InetSocketAddress
+
+class NetconfDeviceManager {
+
+    val Map<InstanceIdentifier, NetconfDevice> devices = new ConcurrentHashMap;
+
+    var ProviderSession session;
+
+    @Property
+    var DataProviderService dataService;
+    
+    @Property
+    var MountProvisionService mountService;
+    
+    val nodeUpdateListener = new NetconfInventoryListener(this);
+
+
+    @Property
+    var NetconfClientDispatcher dispatcher;
+
+    def void start() {
+        dataService?.registerDataChangeListener(INVENTORY_PATH, nodeUpdateListener);
+        if(dispatcher == null) {
+        dispatcher = new NetconfClientDispatcher(Optional.absent);
+        }
+    }
+
+    def netconfNodeAdded(InstanceIdentifier path, CompositeNode node) {
+        val address = node.endpointAddress;
+        val port = Integer.parseInt(node.endpointPort);
+        netconfNodeAdded(path,new InetSocketAddress(address,port))
+
+    }
+    
+    def netconfNodeAdded(InstanceIdentifier path, InetSocketAddress address) {
+    
+        val mountPointPath = path;
+        val mountPoint = mountService.createOrGetMountPoint(mountPointPath);
+        val localPath = InstanceIdentifier.builder().toInstance;
+        val netconfDevice = new NetconfDevice(mountPoint,localPath);
+        netconfDevice.setSocketAddress(address);
+        netconfDevice.start(dispatcher);
+    }
+
+    def netconfNodeRemoved(InstanceIdentifier path) {
+    
+    }
+
+}
+
+class NetconfInventoryListener implements DataChangeListener {
+
+    val NetconfDeviceManager manager;
+
+    new(NetconfDeviceManager manager) {
+        this.manager = manager;
+    }
+
+    override onDataChanged(DataChangeEvent<InstanceIdentifier, CompositeNode> change) {
+        
+        //manager.netconfNodeAdded(path, change);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfInventoryUtils.java
new file mode 100644 (file)
index 0000000..a69f670
--- /dev/null
@@ -0,0 +1,22 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public class NetconfInventoryUtils {
+
+    
+    public static final QName NETCONF_MOUNT = null;
+    public static final QName NETCONF_ENDPOINT = null;
+    public static final QName NETCONF_ENDPOINT_ADDRESS = null;
+    public static final QName NETCONF_ENDPOINT_PORT = null;
+
+
+    public static String getEndpointAddress(CompositeNode node) {
+        return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_ADDRESS).getValue().toString();
+    }
+    
+    public static String getEndpointPort(CompositeNode node) {
+        return node.getCompositesByName(NETCONF_ENDPOINT).get(0).getFirstSimpleByName(NETCONF_ENDPOINT_PORT).getValue().toString();
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfMapping.xtend
new file mode 100644 (file)
index 0000000..d23ec1c
--- /dev/null
@@ -0,0 +1,95 @@
+package org.opendaylight.controller.sal.connect.netconf
+
+import org.opendaylight.controller.netconf.api.NetconfMessage
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.common.RpcResult
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import java.net.URI
+import java.util.Collections
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.NodeUtils
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import java.util.concurrent.atomic.AtomicInteger
+import org.w3c.dom.Document
+import org.w3c.dom.Element
+import org.opendaylight.controller.sal.common.util.Rpcs
+
+class NetconfMapping {
+
+    public static val NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0")
+    public static val NETCONF_QNAME = new QName(NETCONF_URI,null,"netconf");
+    public static val NETCONF_RPC_QNAME = new QName(NETCONF_QNAME,"rpc");
+    public static val NETCONF_GET_QNAME = new QName(NETCONF_QNAME,"get");
+    public static val NETCONF_GET_CONFIG_QNAME = new QName(NETCONF_QNAME,"get-config");
+    public static val NETCONF_RPC_REPLY_QNAME = new QName(NETCONF_QNAME,"rpc-reply");
+    public static val NETCONF_OK_QNAME = new QName(NETCONF_QNAME,"ok");
+    public static val NETCONF_DATA_QNAME = new QName(NETCONF_QNAME,"data");
+    
+
+    static val messageId = new AtomicInteger(0);
+
+
+
+    static def Node<?> toFilterStructure(InstanceIdentifier identifier) {
+        var Node<?> previous = null;
+        for (component : identifier.path.reverse) {
+            val Node<?> current = component.toNode(previous);
+            previous = current;
+        }
+        return previous;
+    }
+    
+    static def dispatch Node<?> toNode(NodeIdentifierWithPredicates argument, Node<?> node) {
+        val list = new ArrayList<Node<?>>();
+        for( arg : argument.keyValues.entrySet) {
+            list.add = new SimpleNodeTOImpl(arg.key,null,arg.value);
+        }
+        return new CompositeNodeTOImpl(argument.nodeType,null,list)
+    }
+    
+    static def dispatch Node<?> toNode(PathArgument argument, Node<?> node) {
+        if(node != null) {
+            return new CompositeNodeTOImpl(argument.nodeType,null,Collections.singletonList(node));
+        } else {
+            return new SimpleNodeTOImpl(argument.nodeType,null,null);
+        }
+    }
+
+    static def CompositeNode toCompositeNode(NetconfMessage message) {
+        return message.toRpcResult().result;
+    }
+
+    static def NetconfMessage toRpcMessage(QName rpc, CompositeNode node) {
+        val rpcPayload = wrap(NETCONF_RPC_QNAME,node);
+        val w3cPayload = NodeUtils.buildShadowDomTree(rpcPayload);
+        w3cPayload.documentElement.setAttribute("message-id","m-"+ messageId.andIncrement);
+        return new NetconfMessage(w3cPayload);
+    }
+
+    static def RpcResult<CompositeNode> toRpcResult(NetconfMessage message) {
+        val rawRpc = message.document.toCompositeNode() as CompositeNode;
+        //rawRpc.
+        
+        return Rpcs.getRpcResult(true,rawRpc,Collections.emptySet());
+    }
+    
+    
+    static def wrap(QName name,Node<?> node) {
+        if(node != null) {
+            return new CompositeNodeTOImpl(name,null,Collections.singletonList(node));
+        }
+        else {
+            return new CompositeNodeTOImpl(name,null,Collections.emptyList());
+        }
+    }
+    
+    
+    public static def Node<?> toCompositeNode(Document document) {
+        return XmlDocumentUtils.toCompositeNode(document) as Node<?>
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/NetconfProvider.java
new file mode 100644 (file)
index 0000000..8cf5f02
--- /dev/null
@@ -0,0 +1,35 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.util.Hashtable;
+
+import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.osgi.framework.BundleContext;
+
+public class NetconfProvider extends AbstractProvider {
+
+    private NetconfDeviceManager netconfDeviceManager;
+
+    @Override
+    protected void startImpl(BundleContext context) {
+        netconfDeviceManager = new NetconfDeviceManager();
+        context.registerService(NetconfDeviceManager.class, netconfDeviceManager, new Hashtable<String,String>());
+    }
+    
+    
+    @Override
+    public void onSessionInitiated(ProviderSession session) {
+        MountProvisionService mountService = session.getService(MountProvisionService.class);
+        
+        
+        netconfDeviceManager.setMountService(mountService);
+        netconfDeviceManager.start();
+    }
+
+    @Override
+    protected void stopImpl(BundleContext context) {
+        
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/XmlDocumentUtils.java
new file mode 100644 (file)
index 0000000..3f6b4e1
--- /dev/null
@@ -0,0 +1,54 @@
+package org.opendaylight.controller.sal.connect.netconf;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class XmlDocumentUtils {
+
+    public static CompositeNode toCompositeNode(Document doc) {
+        return (CompositeNode) toCompositeNode(doc.getDocumentElement());
+    }
+
+    private static Node<?> toCompositeNode(Element element) {
+        String orgNamespace = element.getNamespaceURI();
+        URI biNamespace = null;
+        if (orgNamespace != null) {
+            biNamespace = URI.create(orgNamespace);
+        }
+        QName qname = new QName(biNamespace, element.getLocalName());
+
+        List<Node<?>> values = new ArrayList<>();
+        NodeList nodes = element.getChildNodes();
+        boolean isSimpleObject = false;
+        String value = null;
+        for (int i = 0; i < nodes.getLength(); i++) {
+            org.w3c.dom.Node child = nodes.item(i);
+            if (child instanceof Element) {
+                isSimpleObject = false;
+                values.add(toCompositeNode((Element) child));
+            }
+            if (!isSimpleObject && child instanceof org.w3c.dom.Text) {
+                value = element.getTextContent();
+                if (value.matches(".*\\w.*")) {
+                    isSimpleObject = true;
+                    break;
+                }
+            }
+        }
+
+        if (isSimpleObject) {
+            return new SimpleNodeTOImpl<>(qname, null, value);
+        }
+        return new CompositeNodeTOImpl(qname, null, values);
+    }
+}
diff --git a/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connector/netconf/test/MountTest.java b/opendaylight/md-sal/sal-netconf-connector/src/test/java/org/opendaylight/controller/sal/connector/netconf/test/MountTest.java
new file mode 100644 (file)
index 0000000..4abf0e1
--- /dev/null
@@ -0,0 +1,197 @@
+package org.opendaylight.controller.sal.connector.netconf.test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.*;
+import io.netty.channel.ChannelFuture;
+import io.netty.util.HashedWheelTimer;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
+import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
+import org.opendaylight.controller.config.spi.ModuleFactory;
+import org.opendaylight.controller.config.yang.store.api.YangStoreException;
+import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.config.yang.test.impl.DepTestImplModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
+import org.opendaylight.controller.config.yang.test.impl.TestImplModuleFactory;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.client.NetconfClient;
+import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
+import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
+import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
+import org.opendaylight.controller.netconf.impl.NetconfServerSessionNegotiatorFactory;
+import org.opendaylight.controller.netconf.impl.SessionIdProvider;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
+import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
+import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDevice;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
+import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.data.DataProviderService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
+import org.opendaylight.controller.sal.dom.broker.DataBrokerImpl;
+import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+
+public class MountTest extends AbstractConfigTest {
+
+    private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 12023);
+    private static final InetSocketAddress tlsAddress = new InetSocketAddress("127.0.0.1", 12024);
+    private static final URI NETCONF_MONITORING_NS = URI.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring");
+    
+    private static final QName NETCONF_MONITORING = new QName(NETCONF_MONITORING_NS, new Date(2010,10,04), "ietf-netconf-monitoring");
+    private static final QName NETCONF_MONITORING_STATE = new QName(NETCONF_MONITORING,"netconf-state");
+    
+
+    private NetconfMessage getConfig, getConfigCandidate, editConfig, closeSession;
+    private DefaultCommitNotificationProducer commitNot;
+    private NetconfServerDispatcher dispatch;
+    private DataProviderService dataBroker;
+    private MountPointManagerImpl mountManager;
+    private NetconfDeviceManager netconfManager;
+
+    private static QName CONFIG_MODULES = new QName(
+            URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+    private static QName CONFIG_SERVICES = new QName(
+            URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+
+    private NetconfClient createSession(final InetSocketAddress address, NetconfClientDispatcher dispatcher) throws InterruptedException {
+        final NetconfClient netconfClient = new NetconfClient("test " + address.toString(), address, 5000, dispatcher);
+        return netconfClient;
+    }
+    
+    @Before
+    public void setUp() throws Exception {
+        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(getModuleFactories().toArray(
+                new ModuleFactory[0])));
+
+        loadMessages();
+
+        NetconfOperationServiceFactoryListenerImpl factoriesListener = new NetconfOperationServiceFactoryListenerImpl();
+        factoriesListener.onAddNetconfOperationServiceFactory(new NetconfOperationServiceFactoryImpl(getYangStore()));
+
+        commitNot = new DefaultCommitNotificationProducer(ManagementFactory.getPlatformMBeanServer());
+
+        dispatch = createDispatcher(Optional.<SSLContext> absent(), factoriesListener);
+        ChannelFuture s = dispatch.createServer(tcpAddress);
+        s.await();
+
+        dataBroker = new DataBrokerImpl();
+        mountManager = new MountPointManagerImpl();
+        mountManager.setDataBroker(dataBroker);
+        netconfManager = new NetconfDeviceManager();
+
+        netconfManager.setMountService(mountManager);
+        netconfManager.setDataService(dataBroker);
+        netconfManager.start();
+
+        try (NetconfClient netconfClient = createSession(tcpAddress, netconfManager.getDispatcher())) {
+            // send edit_config.xml
+            final Document rpcReply = netconfClient.sendMessage(this.editConfig).getDocument();
+            assertNotNull(rpcReply);
+        }
+    }
+
+
+    protected List<ModuleFactory> getModuleFactories() {
+        return getModuleFactoriesS();
+    }
+
+    static List<ModuleFactory> getModuleFactoriesS() {
+        return Lists.newArrayList(new TestImplModuleFactory(), new DepTestImplModuleFactory(),
+                new NetconfTestImplModuleFactory());
+    }
+
+    private void loadMessages() throws IOException, SAXException, ParserConfigurationException {
+        this.editConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/edit_config.xml");
+        this.getConfig = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+        this.getConfigCandidate = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/getConfig_candidate.xml");
+        this.closeSession = XmlFileLoader.xmlFileToNetconfMessage("netconfMessages/closeSession.xml");
+    }
+
+    private NetconfServerDispatcher createDispatcher(Optional<SSLContext> sslC,
+            NetconfOperationServiceFactoryListenerImpl factoriesListener) {
+        SessionIdProvider idProvider = new SessionIdProvider();
+        NetconfServerSessionNegotiatorFactory serverNegotiatorFactory = new NetconfServerSessionNegotiatorFactory(
+                new HashedWheelTimer(5000, TimeUnit.MILLISECONDS), factoriesListener, idProvider);
+
+        NetconfServerSessionListenerFactory listenerFactory = new NetconfServerSessionListenerFactory(
+                factoriesListener, commitNot, idProvider);
+
+        return new NetconfServerDispatcher(sslC, serverNegotiatorFactory, listenerFactory);
+    }
+
+    private HardcodedYangStoreService getYangStore() throws YangStoreException, IOException {
+        final Collection<InputStream> yangDependencies = getBasicYangs();
+        return new HardcodedYangStoreService(yangDependencies);
+    }
+
+    private Collection<InputStream> getBasicYangs() throws IOException {
+        List<String> paths = Arrays.asList("/META-INF/yang/config.yang", "/META-INF/yang/rpc-context.yang",
+                "/META-INF/yang/config-test.yang", "/META-INF/yang/config-test-impl.yang",
+                "/META-INF/yang/ietf-inet-types.yang");
+        final Collection<InputStream> yangDependencies = new ArrayList<>();
+        for (String path : paths) {
+            final InputStream is = Preconditions
+                    .checkNotNull(getClass().getResourceAsStream(path), path + " not found");
+            yangDependencies.add(is);
+        }
+        return yangDependencies;
+    }
+
+    @Test
+    public void test() {
+        // MountProvisionInstance mount =
+        // Mockito.mock(MountProvisionInstance.class);
+        InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
+                .node(InventoryUtils.INVENTORY_NODE).toInstance();
+        netconfManager.netconfNodeAdded(path, tcpAddress);
+        InstanceIdentifier mountPointPath = path;
+        MountProvisionInstance mountPoint = mountManager.getMountPoint(mountPointPath);
+
+        CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES)
+                .toInstance());
+        assertNotNull(data);
+        assertEquals(CONFIG_MODULES, data.getNodeType());
+
+        CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance());
+        assertNotNull(data2);
+
+        InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance();
+
+        CompositeNode data3 = dataBroker.readOperationalData(fullPath);
+        assertNotNull(data3);
+        assertEquals(CONFIG_MODULES, data.getNodeType());
+    }
+
+}
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft02.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/Draft02.java
new file mode 100644 (file)
index 0000000..70b2cf5
--- /dev/null
@@ -0,0 +1,17 @@
+package org.opendaylight.controller.sal.rest.api;
+
+public class Draft02 {
+    public static class MediaTypes {
+        public static final String API = "application/yang.api";
+        public static final String DATASTORE = "application/yang.datastore";
+        public static final String DATA = "application/yang.data";
+        public static final String OPERATION = "application/yang.operation";
+        public static final String PATCH = "application/yang.patch";
+        public static final String PATCH_STATUS = "application/yang.patch-status";
+        public static final String STREAM = "application/yang.stream";
+    }
+    
+    public static class Paths {
+        
+    }
+}
index b8cb2292542b8da4ecf7f8573d6b578a47ff3810..c36a79c5d901093ad3bf79d1a4a354ebcf161209 100644 (file)
@@ -16,7 +16,9 @@ import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 /**
@@ -25,7 +27,9 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  *  Section 5 for details on each URI.
  *    <ul>
  *    <li><b>/restconf</b> - {@link #getRoot()}
- *     <ul><li><b>/datastore</b> - {@link #readAllData()}
+ *     <ul><li><b>/config</b> 
+ *         <li><b>/operational</b> - {@link #readAllData()} - Added in Draft02
+ *         <li><b>/datastore</b> - {@link #readAllData()}
  *         <ul>
  *            <li>/(top-level-data-nodes) (config=true or false)
  *         </ul>
@@ -45,7 +49,7 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  *     </ul>
  */
 @Path("/")
-public interface RestconfService {
+public interface RestconfService extends RestconfServiceLegacy {
 
     public static final String XML = "+xml";
     public static final String JSON = "+json";
@@ -53,33 +57,49 @@ public interface RestconfService {
     @GET
     public Object getRoot();
 
+
     @GET
-    @Path("/datastore")
+    @Path("/modules")
     @Produces({API+JSON,API+XML})
-    public Object readAllData();
+    public StructuredData getModules();
 
+    @POST
+    @Path("/operations/{identifier}")
+    @Produces({Draft02.MediaTypes.API+JSON,Draft02.MediaTypes.API+XML,API+JSON,API+XML})
+    public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+    
+    
     @GET
-    @Path("/datastore/{identifier:.+}")
-    @Produces({API+JSON,API+XML})
-    public StructuredData readData(@PathParam("identifier") String identifier);
+    @Path("/config/{identifier:.+}")
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    public StructuredData readConfigurationData(@PathParam("identifier") String identifier);
 
+    
+    
     @PUT
-    @Path("/datastore/{identifier:.+}")
+    @Path("/config/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public Object createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public RpcResult<TransactionStatus> createConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @POST
-    @Path("/datastore/{identifier:.+}")
+    @Path("/config/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public Object updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
+    public RpcResult<TransactionStatus> updateConfigurationData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @GET
-    @Path("/modules")
+    @Path("/operational/{identifier:.+}")
+    @Produces({Draft02.MediaTypes.DATA+JSON,Draft02.MediaTypes.DATA+XML})
+    public StructuredData readOperationalData(@PathParam("identifier") String identifier);
+
+    @PUT
+    @Path("/operational/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public Object getModules();
+    public RpcResult<TransactionStatus> createOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
 
     @POST
-    @Path("/operations/{identifier}")
+    @Path("/operational/{identifier:.+}")
     @Produces({API+JSON,API+XML})
-    public StructuredData invokeRpc(@PathParam("identifier") String identifier, CompositeNode payload);
+    public RpcResult<TransactionStatus> updateOperationalData(@PathParam("identifier") String identifier, CompositeNode payload);
+
+    
 }
diff --git a/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java b/opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/rest/api/RestconfServiceLegacy.java
new file mode 100644 (file)
index 0000000..6683fd1
--- /dev/null
@@ -0,0 +1,46 @@
+package org.opendaylight.controller.sal.rest.api;
+
+import static org.opendaylight.controller.sal.restconf.impl.MediaTypes.API;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.restconf.impl.StructuredData;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+public interface RestconfServiceLegacy {
+
+    public static final String XML = "+xml";
+    public static final String JSON = "+json";
+    
+    @Deprecated
+    @GET
+    @Path("/datastore")
+    @Produces({API+JSON,API+XML})
+    public StructuredData readAllData();
+
+    @Deprecated
+    @GET
+    @Path("/datastore/{identifier:.+}")
+    @Produces({API+JSON,API+XML})
+    public StructuredData readData(@PathParam("identifier") String identifier);
+
+    @Deprecated
+    @PUT
+    @Path("/datastore/{identifier:.+}")
+    @Produces({API+JSON,API+XML})
+    public RpcResult<TransactionStatus> createConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+
+    @Deprecated
+    @POST
+    @Path("/datastore/{identifier:.+}")
+    @Produces({API+JSON,API+XML})
+    public RpcResult<TransactionStatus> updateConfigurationDataLegacy(@PathParam("identifier") String identifier, CompositeNode payload);
+
+}
index 8e18661db6ecdfcc65d822dff5bf1e4c115c0b96..3c31c5a313ec0b45a9a8390729638331d4a7a7a0 100644 (file)
@@ -42,15 +42,15 @@ class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
         return future.get;
     }
 
-    def commitConfigurationDataUpdate(InstanceIdentifier path, CompositeNode payload) {
+    def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
         val transaction = dataService.beginTransaction;
         transaction.putConfigurationData(path, payload);
         return transaction.commit()
     }
 
-    def commitConfigurationDataCreate(InstanceIdentifier path, CompositeNode payload) {
+    def commitOperationalDataPut(InstanceIdentifier path, CompositeNode payload) {
         val transaction = dataService.beginTransaction;
-        transaction.putConfigurationData(path, payload);
+        transaction.putOperationalData(path, payload);
         return transaction.commit()
     }
     
index 2b3a3042c2ce9119c9ee9d0176dcf88ed52807cb..400850103d7be35f72beeb39088a1618a23feff5 100644 (file)
@@ -25,6 +25,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext
 
 import static com.google.common.base.Preconditions.*
 import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
+import java.util.concurrent.ConcurrentHashMap
 
 class ControllerContext implements SchemaServiceListener {
 
@@ -37,6 +39,8 @@ class ControllerContext implements SchemaServiceListener {
 
     private val BiMap<URI, String> uriToModuleName = HashBiMap.create();
     private val Map<String, URI> moduleNameToUri = uriToModuleName.inverse();
+    private val Map<QName,RpcDefinition> qnameToRpc = new ConcurrentHashMap();
+    
 
     private new() {
         if (INSTANCE != null) {
@@ -272,11 +276,23 @@ class ControllerContext implements SchemaServiceListener {
         }
     }
 
-    public def QName toRpcQName(String name) {
+    public def QName toQName(String name) {
+        val module = name.toModuleName;
+        val node = name.toNodeName;
+        val namespace = moduleNameToUri.get(module);
+        return new QName(namespace,null,node);
     }
 
     override onGlobalContextUpdated(SchemaContext context) {
         this.schemas = context;
+        for(operation : context.operations) {
+            val qname = new QName(operation.QName.namespace,null,operation.QName.localName);
+            qnameToRpc.put(qname,operation);
+        }
+    }
+    
+    def ContainerSchemaNode getRpcOutputSchema(QName name) {
+        qnameToRpc.get(name)?.output;
     }
 
 }
index fc0dd1017fea6fbb9e77cd5f3b5a84d616b9e58f..31fbe8ec876876b0d677ffaa90df95fddbdfa91a 100644 (file)
@@ -25,7 +25,7 @@ class RestconfImpl implements RestconfService {
 
     override readAllData() {
 //        return broker.readOperationalData("".toInstanceIdentifier.getInstanceIdentifier);
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        throw new UnsupportedOperationException("Reading all data is currently not supported.")
     }
 
     override getModules() {
@@ -33,8 +33,7 @@ class RestconfImpl implements RestconfService {
     }
 
     override getRoot() {
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
-
+        return null;
     }
 
     override readData(String identifier) {
@@ -44,18 +43,50 @@ class RestconfImpl implements RestconfService {
     }
 
     override createConfigurationData(String identifier, CompositeNode payload) {
-//        return broker.commitConfigurationDataCreate(identifier.toInstanceIdentifier.getInstanceIdentifier, payload);
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
     }
 
     override updateConfigurationData(String identifier, CompositeNode payload) {
-//        return broker.commitConfigurationDataCreate(identifier.toInstanceIdentifier.getInstanceIdentifier, payload);
-        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        return broker.commitConfigurationDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
     }
 
     override invokeRpc(String identifier, CompositeNode payload) {
-        val rpcResult = broker.invokeRpc(identifier.toRpcQName, payload);
-        return new StructuredData(rpcResult.result, identifier.toInstanceIdentifier.getSchemaNode)
+        val rpc = identifier.toQName;
+        val rpcResult = broker.invokeRpc(rpc, payload);
+        val schema = controllerContext.getRpcOutputSchema(rpc);
+        return new StructuredData(rpcResult.result, schema);
+    }
+    
+    override readConfigurationData(String identifier) {
+        val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+        val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
+        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+    }
+    
+    override readOperationalData(String identifier) {
+        val instanceIdentifierWithSchemaNode = identifier.toInstanceIdentifier
+        val data = broker.readOperationalData(instanceIdentifierWithSchemaNode.getInstanceIdentifier);
+        return new StructuredData(data, instanceIdentifierWithSchemaNode.schemaNode)
+    }
+    
+    override updateConfigurationDataLegacy(String identifier, CompositeNode payload) {
+        updateConfigurationData(identifier,payload);
+    }
+    
+    override createConfigurationDataLegacy(String identifier, CompositeNode payload) {
+        createConfigurationData(identifier,payload);
+    }
+    
+    override createOperationalData(String identifier, CompositeNode payload) {
+        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
+    }
+    
+    override updateOperationalData(String identifier, CompositeNode payload) {
+        val identifierWithSchemaNode = identifier.toInstanceIdentifier
+        return broker.commitOperationalDataPut(identifierWithSchemaNode.instanceIdentifier,payload).get();
     }
 
 }
index 3db4a65840dd6e1f4356cee52075878796da6d6f..72e49be4de49899f111aeb55ffe65426b0eb3d1e 100644 (file)
 <?xml version="1.0" encoding="UTF-8"?>
 <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>
-    <parent>
-        <groupId>org.opendaylight.controller</groupId>
-        <artifactId>sal-parent</artifactId>
-        <version>1.0-SNAPSHOT</version>
-    </parent>
+         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>
+  <parent>
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>sal-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
 
+  <artifactId>sal-zeromq-connector</artifactId>
+  <packaging>bundle</packaging>
 
-    <artifactId>sal-zeromq-connector</artifactId>
-    <packaging>bundle</packaging>
+  <properties>
+    <scala.version>2.10.3</scala.version>
+  </properties>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <version>${bundle.plugin.version}</version>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                        <Import-Package>
-                        org.opendaylight.controller.sal.connector.api,
-                        org.opendaylight.controller.sal.core.api,
-                        org.opendaylight.yangtools.concepts;version="[0.1,1)",
-                        org.opendaylight.yangtools.yang.common;version="[0.5,1)",
-                        org.opendaylight.yangtools.yang.data.api;version="[0.5,1)",
-                        org.zeromq;version="[0.3,1)"
-                        </Import-Package>
-                        <Bundle-Activator>org.opendaylight.controller.sal.connector.zeromq.Activator</Bundle-Activator>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-    <dependencies>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>containermanager</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>commons.northbound</artifactId>
-            <version>0.4.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal</artifactId>
-            <version>0.5.1-SNAPSHOT</version>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-binding</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>yang-common</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-connector-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common-util</artifactId>
-            <version>1.0-SNAPSHOT</version>
-        </dependency>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${bundle.plugin.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Import-Package>
+              org.opendaylight.controller.sal.connector.api,
+              org.opendaylight.controller.sal.core.api,
+              org.opendaylight.yangtools.concepts;version="[0.1,1)",
+              org.opendaylight.yangtools.yang.common;version="[0.5,1)",
+              org.opendaylight.yangtools.yang.data.api;version="[0.5,1)",
+              org.zeromq;version="[0.3,1)"
+            </Import-Package>
+            <Bundle-Activator>org.opendaylight.controller.sal.connector.remoterpc.router.zeromq.Activator</Bundle-Activator>
+          </instructions>
+        </configuration>
+      </plugin>
 
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.jeromq</groupId>
-            <artifactId>jeromq</artifactId>
-            <version>0.3.0-SNAPSHOT</version>
-        </dependency>
+      <plugin>
+        <groupId>net.alchim31.maven</groupId>
+        <artifactId>scala-maven-plugin</artifactId>
+        <version>3.1.6</version>
+        <configuration>
+          <recompileMode>incremental</recompileMode>
+          <args>
+            <arg>-target:jvm-1.7</arg>
+          </args>
+          <javacArgs>
+            <javacArg>-source</javacArg><javacArg>1.7</javacArg>
+            <javacArg>-target</javacArg><javacArg>1.7</javacArg>
+          </javacArgs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>scala-compile</id>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>scala-test-compile</id>
+            <goals>
+              <goal>testCompile</goal>
+            </goals>
+          </execution>
+        </executions>
 
-    </dependencies>
-    <repositories>
-        <repository>
-            <id>sonatype-nexus-snapshots</id>
-            <url>https://oss.sonatype.org/content/repositories/snapshots</url>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-            <snapshots>
-                <enabled>true</enabled>
-            </snapshots>
-        </repository>
-    </repositories>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>default-compile</id>
+            <phase>none</phase>
+          </execution>
+          <execution>
+            <id>default-testCompile</id>
+            <phase>none</phase>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.scala-lang</groupId>
+      <artifactId>scala-library</artifactId>
+      <version>${scala.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager</artifactId>
+      <version>0.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>commons.northbound</artifactId>
+      <version>0.4.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-binding</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>yang-common</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-connector-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-common-util</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.jeromq</groupId>
+      <artifactId>jeromq</artifactId>
+      <version>0.3.0-SNAPSHOT</version>
+    </dependency>
+
+  </dependencies>
+  <repositories>
+    <repository>
+      <id>sonatype-nexus-snapshots</id>
+      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <snapshots>
+        <enabled>true</enabled>
+      </snapshots>
+    </repository>
+  </repositories>
 
 </project>
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChange.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChange.java
new file mode 100644 (file)
index 0000000..ba90f37
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import java.util.Map;
+import java.util.Set;
+
+public interface RouteChange<I, R> {
+
+  Map<I, Set<R>> getRemovals();
+  Map<I, Set<R>> getAnnouncements();
+}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RouteChangeListener.java
new file mode 100644 (file)
index 0000000..701cfaf
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+
+import java.util.EventListener;
+
+public interface RouteChangeListener extends EventListener {
+
+  public void onRouteChanged(RouteChange<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>  change);
+}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/api/RoutingTable.java
new file mode 100644 (file)
index 0000000..3c6c42e
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.api;
+
+import java.util.Set;
+
+public interface RoutingTable<I,R> {
+
+  /**
+   * Adds a network address for the route. If address for route
+   * exists, appends the address to the list
+   *
+   * @param routeId route identifier
+   * @param route network address
+   */
+  public void addRoute(I routeId, R route);
+
+  /**
+   * Adds a network address for the route. If the route already exists,
+   * it throws. This method would be used when registering a global service.
+   *
+   * @param routeId route identifier
+   * @param route network address
+   * @throws DuplicateRouteException
+   */
+  public void addGlobalRoute(I routeId, R route) throws DuplicateRouteException;
+
+  /**
+   * Removes the network address for the route from routing table. If only
+   * one network address existed, remove the route as well.
+   * @param routeId
+   * @param route
+   */
+  public void removeRoute(I routeId, R route);
+
+  /**
+   * Returns a set of network addresses associated with this route
+   * @param routeId
+   * @return
+   */
+  public Set<R> getRoutes(I routeId);
+
+  /**
+   * Returns only one address from the list of network addresses
+   * associated with the route. The algorithm to determine that
+   * one address is upto the implementer
+   * @param route
+   * @return
+   */
+  public R getARoute(I routeId);
+
+  public void registerRouteChangeListener(RouteChangeListener listener);
+
+  public class DuplicateRouteException extends Exception {}
+}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/Activator.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/Activator.java
new file mode 100644 (file)
index 0000000..5b927a5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
+
+import org.opendaylight.controller.sal.core.api.AbstractProvider;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends AbstractProvider {
+
+  ZeroMqRpcRouter router;
+
+  @Override
+  public void onSessionInitiated(ProviderSession session) {
+    router = ZeroMqRpcRouter.getInstance();
+    router.setBrokerSession(session);
+    router.start();
+  }
+
+  @Override
+  protected void stopImpl(BundleContext context) {
+    router.stop();
+  }
+
+}
@@ -1,16 +1,23 @@
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
 
 
 import org.codehaus.jackson.map.ObjectMapper;
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 
 import java.io.*;
-import java.util.Arrays;
 
 public class Message implements Serializable {
 
- public enum MessageType {
-    ANNOUNCE((byte) 0),
+ public static enum MessageType {
+    ANNOUNCE((byte) 0),  //TODO: Remove announce, add rpc registration and deregistration
     HEARTBEAT((byte) 1),
     REQUEST((byte) 2),
     RESPONSE((byte) 3);
@@ -101,27 +108,15 @@ public class Message implements Serializable {
     return o.readObject();
   }
 
-  public static byte[] toJsonBytes(Message m){
+  public static byte[] toJsonBytes(Message m) throws IOException {
     ObjectMapper o = new ObjectMapper();
-    try {
-      System.out.println(o.writeValueAsString(m));
-      return o.writeValueAsBytes(m);
-    } catch (IOException e) {
-      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-    }
-    return null;
+    return o.writeValueAsBytes(m);
   }
 
-  public static Message fromJsonBytes(byte [] bytes){
+  public static Message fromJsonBytes(byte [] bytes) throws IOException {
 
     ObjectMapper o = new ObjectMapper();
-    Message m = null;
-    try {
-      m = o.readValue(bytes, Message.class);
-    } catch (IOException e) {
-      e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-    }
-    return m;
+    return o.readValue(bytes, Message.class);
   }
 
   public static class Response extends Message implements RpcRouter.RpcReply {
@@ -146,5 +141,41 @@ public class Message implements Serializable {
     }
   }
 
+  /**
+   * Builds a {@link Message} object
+   */
+  public static class MessageBuilder{
+
+    private Message message;
+
+    public MessageBuilder(){
+      message = new Message();
+    }
+
+
+    public MessageBuilder type(MessageType type){
+      message.setType(type);
+      return this;
+    }
+
+    public MessageBuilder sender(String sender){
+      message.setSender(sender);
+      return this;
+    }
+
+    public MessageBuilder route(RpcRouter.RouteIdentifier route){
+      message.setRoute(route);
+      return this;
+    }
+
+    public MessageBuilder payload(Object obj){
+      message.setPayload(obj);
+      return this;
+    }
+
+    public Message build(){
+      return message;
+    }
+  }
 }
 
@@ -1,4 +1,11 @@
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
 
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -1,4 +1,11 @@
-package org.opendaylight.controller.sal.connector.zeromq;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
 
 import org.opendaylight.controller.sal.connector.api.RpcRouter;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -6,13 +13,6 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
 import java.io.Serializable;
 
-/**
- * Created with IntelliJ IDEA.
- * User: abhishk2
- * Date: 10/25/13
- * Time: 12:32 PM
- * To change this template use File | Settings | File Templates.
- */
 public class RpcRequestImpl implements RpcRouter.RpcRequest<QName, QName, InstanceIdentifier, Object>,Serializable {
 
   private RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier;
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/ZeroMqRpcRouter.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/router/zeromq/ZeroMqRpcRouter.java
new file mode 100644 (file)
index 0000000..af94804
--- /dev/null
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc.router.zeromq;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.controller.sal.connector.remoterpc.router.zeromq.Message.MessageType;
+import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+/**
+ * ZeroMq based implementation of RpcRouter
+ * TODO:
+ *    1. Make it multi VM aware
+ *    2. Make rpc request handling async and non-blocking. Note zmq socket is not thread safe
+ *    3. sendRpc() should use connection pooling
+ *    4. Read properties from config file using existing(?) ODL properties framework
+ */
+public class ZeroMqRpcRouter implements RpcRouter<QName, QName, InstanceIdentifier, Object> {
+
+  private ExecutorService serverPool;
+  private static ExecutorService handlersPool;
+
+  private Map<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
+
+  private ProviderSession brokerSession;
+
+  private ZMQ.Context context;
+  private ZMQ.Socket publisher;
+  private ZMQ.Socket subscriber;
+  private ZMQ.Socket replySocket;
+
+  private static ZeroMqRpcRouter _instance = new ZeroMqRpcRouter();
+
+  private final RpcFacade facade = new RpcFacade();
+  private final RpcListener listener = new RpcListener();
+
+  private final String localIp = getLocalIpAddress();
+
+  private String pubPort = System.getProperty("pub.port");// port on which announcements are sent
+  private String subPort = System.getProperty("sub.port");// other controller's pub port
+  private String pubIp = System.getProperty("pub.ip"); // other controller's ip
+  private String rpcPort = System.getProperty("rpc.port");// port on which RPC messages are received
+
+  private Logger _logger = LoggerFactory.getLogger(ZeroMqRpcRouter.class);
+
+  //Prevent instantiation
+  private ZeroMqRpcRouter() {
+  }
+
+  public static ZeroMqRpcRouter getInstance() {
+    return _instance;
+  }
+
+  public void start() {
+    context = ZMQ.context(2);
+    publisher = context.socket(ZMQ.PUB);
+    int ret = publisher.bind("tcp://*:" + pubPort);
+    // serverPool = Executors.newSingleThreadExecutor();
+    serverPool = Executors.newCachedThreadPool();
+    handlersPool = Executors.newCachedThreadPool();
+    routingTable = new ConcurrentHashMap<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
+
+    // Start listening for announce and rpc messages
+    serverPool.execute(receive());
+
+    brokerSession.addRpcRegistrationListener(listener);
+
+    Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
+    for (QName rpc : currentlySupported) {
+      listener.onRpcImplementationAdded(rpc);
+    }
+
+  }
+
+  public void stop() {
+    if (handlersPool != null)
+      handlersPool.shutdown();
+    if (serverPool != null)
+      serverPool.shutdown();
+    if (publisher != null) {
+      publisher.setLinger(0);
+      publisher.close();
+    }
+    if (replySocket != null) {
+      replySocket.setLinger(0);
+      replySocket.close();
+    }
+    if (subscriber != null) {
+      subscriber.setLinger(0);
+      subscriber.close();
+    }
+    if (context != null)
+      context.term();
+
+  }
+
+  private Runnable receive() {
+    return new Runnable() {
+      public void run() {
+        try {
+          // Bind to RPC reply socket
+          replySocket = context.socket(ZMQ.REP);
+          replySocket.bind("tcp://*:" + rpcPort);
+
+          // Bind to publishing controller
+          subscriber = context.socket(ZMQ.SUB);
+          String pubAddress = "tcp://" + pubIp + ":" + subPort;
+          subscriber.connect(pubAddress);
+          _logger.debug("{} Subscribing at[{}]", Thread.currentThread().getName(), pubAddress);
+
+          //subscribe for announcements
+          //TODO: Message type would be changed. Update this
+          subscriber.subscribe(Message.serialize(Message.MessageType.ANNOUNCE));
+
+          // Poller enables listening on multiple sockets using a single thread
+          ZMQ.Poller poller = new ZMQ.Poller(2);
+          poller.register(replySocket, ZMQ.Poller.POLLIN);
+          poller.register(subscriber, ZMQ.Poller.POLLIN);
+
+          //TODO: Add code to restart the thread after exception
+          while (!Thread.currentThread().isInterrupted()) {
+
+            poller.poll();
+
+            if (poller.pollin(0)) {
+              handleRpcCall();
+            }
+            if (poller.pollin(1)) {
+              handleAnnouncement();
+            }
+          }
+        } catch (Exception e) {
+          e.printStackTrace();
+        }
+        replySocket.setLinger(0);
+        replySocket.close();
+        subscriber.setLinger(0);
+        subscriber.close();
+      }
+    };
+  }
+
+  /**
+   * @throws IOException
+   * @throws ClassNotFoundException
+   */
+  private void handleAnnouncement() throws IOException, ClassNotFoundException {
+
+    _logger.info("Announcement received");
+    Message.MessageType topic = (MessageType) Message.deserialize(subscriber.recv());
+
+    if (subscriber.hasReceiveMore()) {
+      try {
+        Message m = (Message) Message.deserialize(subscriber.recv());
+        _logger.debug("Announcement message [{}]", m);
+
+        // TODO: check on msg type or topic. Both
+        // should be same. Need to normalize.
+        if (Message.MessageType.ANNOUNCE == m.getType())
+          updateRoutingTable(m);
+      } catch (IOException | ClassNotFoundException e) {
+        e.printStackTrace();
+      }
+    }
+
+  }
+
+  /**
+   * @throws InterruptedException
+   * @throws ExecutionException
+   */
+  private void handleRpcCall() throws InterruptedException, ExecutionException {
+    try {
+      Message request = parseMessage(replySocket);
+
+      _logger.debug("Received rpc request [{}]", request);
+
+      // Call broker to process the message then reply
+      Future<RpcResult<CompositeNode>> rpc = brokerSession.rpc(
+          (QName) request.getRoute().getType(), (CompositeNode) request.getPayload());
+
+      RpcResult<CompositeNode> result = rpc.get();
+
+      Message response = new Message.MessageBuilder()
+          .type(MessageType.RESPONSE)
+          .sender(localIp + ":" + rpcPort)
+          .route(request.getRoute())
+          //.payload(result)    TODO: enable and test
+          .build();
+
+      replySocket.send(Message.serialize(response));
+
+      _logger.debug("Sent rpc response [{}]", response);
+
+    } catch (IOException ex) {
+      //TODO: handle exception and send error codes to caller
+      ex.printStackTrace();
+    }
+  }
+
+
+  @Override
+  public Future<RpcReply<Object>> sendRpc(
+      final RpcRequest<QName, QName, InstanceIdentifier, Object> input) {
+
+    return handlersPool.submit(new Callable<RpcReply<Object>>() {
+
+      @Override
+      public RpcReply<Object> call() {
+        ZMQ.Socket requestSocket = context.socket(ZMQ.REQ);
+
+        // TODO pick the ip and port from routing table based on routing identifier
+        requestSocket.connect("tcp://" + pubIp + ":5554");
+
+        Message requestMessage = new Message.MessageBuilder()
+            .type(MessageType.REQUEST)
+            .sender(localIp + ":" + rpcPort)
+            .route(input.getRoutingInformation())
+            .payload(input.getPayload())
+            .build();
+
+        _logger.debug("Sending rpc request [{}]", requestMessage);
+
+        RpcReply<Object> reply = null;
+
+        try {
+
+          requestSocket.send(Message.serialize(requestMessage));
+          final Message response = parseMessage(requestSocket);
+
+          _logger.debug("Received response [{}]", response);
+
+          reply = new RpcReply<Object>() {
+
+            @Override
+            public Object getPayload() {
+              return response.getPayload();
+            }
+          };
+        } catch (IOException ex) {
+          // TODO: Pass exception back to the caller
+          ex.printStackTrace();
+        }
+
+        return reply;
+      }
+    });
+  }
+
+  /**
+   * TODO: Remove this implementation and use RoutingTable implementation to send announcements
+   * Publishes a notice to other controllers in the cluster
+   *
+   * @param notice
+   */
+  public void publish(final Message notice) {
+    Runnable task = new Runnable() {
+      public void run() {
+
+        try {
+
+          publisher.sendMore(Message.serialize(Message.MessageType.ANNOUNCE));
+          publisher.send(Message.serialize(notice));
+          _logger.debug("Announcement sent [{}]", notice);
+        } catch (IOException ex) {
+          _logger.error("Error in sending announcement [{}]", notice);
+          ex.printStackTrace();
+        }
+      }
+    };
+    handlersPool.execute(task);
+  }
+
+  /**
+   * Finds IPv4 address of the local VM
+   * TODO: This method is non-deterministic. There may be more than one IPv4 address. Cant say which
+   * address will be returned. Read IP from a property file or enhance the code to make it deterministic.
+   * Should we use IP or hostname?
+   *
+   * @return
+   */
+  private String getLocalIpAddress() {
+    String hostAddress = null;
+    Enumeration e = null;
+    try {
+      e = NetworkInterface.getNetworkInterfaces();
+    } catch (SocketException e1) {
+      e1.printStackTrace();
+    }
+    while (e.hasMoreElements()) {
+
+      NetworkInterface n = (NetworkInterface) e.nextElement();
+
+      Enumeration ee = n.getInetAddresses();
+      while (ee.hasMoreElements()) {
+        InetAddress i = (InetAddress) ee.nextElement();
+        if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
+          hostAddress = i.getHostAddress();
+      }
+    }
+    return hostAddress;
+
+  }
+
+  /**
+   * TODO: Change to use external routing table implementation
+   *
+   * @param msg
+   */
+  private void updateRoutingTable(Message msg) {
+    routingTable.put(msg.getRoute(), msg.getSender());
+    RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> route = msg.getRoute();
+
+    // Currently only registers rpc implementation.
+    // TODO: do registration for instance based routing
+    QName rpcType = route.getType();
+    RpcRegistration registration = brokerSession.addRpcImplementation(rpcType, facade);
+    _logger.debug("Routing table updated");
+  }
+
+  /**
+   * @param socket
+   * @return
+   */
+  private Message parseMessage(ZMQ.Socket socket) {
+
+    Message msg = null;
+    try {
+      byte[] bytes = socket.recv();
+      _logger.debug("Received bytes:[{}]", bytes.length);
+      msg = (Message) Message.deserialize(bytes);
+    } catch (Throwable t) {
+      t.printStackTrace();
+    }
+    return msg;
+  }
+
+  private class RpcFacade implements RpcImplementation {
+
+    @Override
+    public Set<QName> getSupportedRpcs() {
+      return Collections.emptySet();
+    }
+
+    @Override
+    public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+      routeId.setType(rpc);
+
+      RpcRequestImpl request = new RpcRequestImpl();
+      request.setRouteIdentifier(routeId);
+      request.setPayload(input);
+
+      final Future<RpcReply<Object>> ret = sendRpc(request);
+
+      //TODO: Review result handling
+      RpcResult<CompositeNode> result = new RpcResult<CompositeNode>() {
+        @Override
+        public boolean isSuccessful() {
+          try {
+            ret.get();
+          } catch (InterruptedException | ExecutionException e) {
+            e.printStackTrace();
+            return false;
+          }
+          return true;
+        }
+
+        @Override
+        public CompositeNode getResult() {
+          return null;
+        }
+
+        @Override
+        public Collection<RpcError> getErrors() {
+          return Collections.EMPTY_LIST;
+        }
+      };
+      return result;
+    }
+  }
+
+  /**
+   * Listener for rpc registrations
+   */
+  private class RpcListener implements RpcRegistrationListener {
+
+    @Override
+    public void onRpcImplementationAdded(QName name) {
+
+      _logger.debug("Announcing registration for [{}]", name);
+      RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+      routeId.setType(name);
+
+      //TODO: Make notice immutable and change message type
+      Message notice = new Message.MessageBuilder()
+          .type(MessageType.ANNOUNCE)
+          .sender("tcp://" + localIp + ":" + rpcPort)
+          .route(routeId)
+          .build();
+
+      publish(notice);
+    }
+
+    @Override
+    public void onRpcImplementationRemoved(QName name) {
+      // TODO: send a rpc-deregistrtation notice
+
+    }
+  }
+
+  public void setBrokerSession(ProviderSession session) {
+    this.brokerSession = session;
+
+  }
+
+}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/Activator.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/Activator.java
deleted file mode 100644 (file)
index b8933ec..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.core.api.AbstractProvider;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.osgi.framework.BundleContext;
-
-public class Activator extends AbstractProvider {
-    
-    ZeroMqRpcRouter router;
-    
-    @Override
-    public void onSessionInitiated(ProviderSession session) {
-        router = ZeroMqRpcRouter.getInstance();
-        router.setBrokerSession(session);
-        router.start();
-    }
-    
-    @Override
-    protected void stopImpl(BundleContext context) {
-       router.stop();
-    }
-
-}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/RpcReplyImpl.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/RpcReplyImpl.java
deleted file mode 100644 (file)
index 66ff714..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-
-import java.io.Serializable;
-
-/**
- * Created with IntelliJ IDEA.
- * User: abhishk2
- * Date: 10/24/13
- * Time: 4:25 PM
- * To change this template use File | Settings | File Templates.
- */
-public class RpcReplyImpl implements RpcRouter.RpcReply<Object>,Serializable {
-
-  private Object payload;
-
-  @Override
-  public Object getPayload() {
-    return payload;  //To change body of implemented methods use File | Settings | File Templates.
-  }
-
-  public void setPayload(Object payload){
-    this.payload = payload;
-  }
-}
diff --git a/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/ZeroMqRpcRouter.java b/opendaylight/md-sal/sal-zeromq-connector/src/main/java/org/opendaylight/controller/sal/connector/zeromq/ZeroMqRpcRouter.java
deleted file mode 100644 (file)
index 7e5efda..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-package org.opendaylight.controller.sal.connector.zeromq;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.*;
-import java.util.concurrent.*;
-
-public class ZeroMqRpcRouter implements RpcRouter<QName, QName, InstanceIdentifier, Object> {
-
-  private ExecutorService serverPool;
-  private static ExecutorService handlersPool;
-
-  private Map<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
-
-  private ProviderSession brokerSession;
-
-  private ZMQ.Context context;
-  private ZMQ.Socket publisher;
-  private ZMQ.Socket subscriber;
-  private ZMQ.Socket replySocket;
-
-  private static ZeroMqRpcRouter _instance = new ZeroMqRpcRouter();
-
-  private final RpcFacade facade = new RpcFacade();
-  private final RpcListener listener = new RpcListener();
-
-  private String pubPort = System.getProperty("pub.port");//port on which announcements are sent
-  private String subPort = System.getProperty("sub.port");//other controller's pub port
-  private String pubIp = System.getProperty("pub.ip");    //other controller's ip
-  private String rpcPort = System.getProperty("rpc.port");//port on which RPC messages are received
-
-
-  private ZeroMqRpcRouter() {
-  }
-
-  public static ZeroMqRpcRouter getInstance() {
-    return _instance;
-  }
-
-  public void start() {
-    context = ZMQ.context(2);
-    serverPool = Executors.newSingleThreadExecutor();
-    handlersPool = Executors.newCachedThreadPool();
-    routingTable = new ConcurrentHashMap<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
-
-    // Start listening for announce and rpc messages
-    serverPool.execute(receive());
-
-    
-    brokerSession.addRpcRegistrationListener(listener);
-    Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
-    for(QName rpc : currentlySupported) {
-        listener.onRpcImplementationAdded(rpc);
-    }
-
-
-  }
-
-  public void stop() {
-    if (handlersPool != null) handlersPool.shutdown();
-    if (serverPool != null) serverPool.shutdown();
-    if (publisher != null) {
-      publisher.setLinger(0);
-      publisher.close();
-    }
-    if (replySocket != null) {
-      replySocket.setLinger(0);
-      replySocket.close();
-    }
-    if (subscriber != null) {
-      subscriber.setLinger(0);
-      subscriber.close();
-    }
-    if (context != null) context.term();
-
-
-  }
-
-  private Runnable receive() {
-    return new Runnable() {
-      public void run() {
-        try {
-          // Bind to RPC reply socket
-          replySocket = context.socket(ZMQ.REP);
-          replySocket.bind("tcp://*:" + rpcPort);
-
-          // Bind to publishing controller
-          subscriber = context.socket(ZMQ.SUB);
-          subscriber.connect("tcp://" + pubIp + ":" + subPort);
-          System.out.println("Subscribing at[" + "tcp://" + pubIp + ":" + subPort + "]");
-
-          subscriber.subscribe(Message.serialize(Message.MessageType.ANNOUNCE));
-
-          // Initialize poll set
-          ZMQ.Poller poller = new ZMQ.Poller(2);
-          poller.register(replySocket, ZMQ.Poller.POLLIN);
-          poller.register(subscriber, ZMQ.Poller.POLLIN);
-
-          while (!Thread.currentThread().isInterrupted()) {
-
-            poller.poll(250);
-            //TODO: Fix this
-            if (poller.pollin(0)) {
-              //receive rpc request and reply
-              try {
-                Message req = parseMessage(replySocket);
-                Message resp = new Message();
-                //Call broker to process the message then reply
-                Future<RpcResult<CompositeNode>> rpc = brokerSession.rpc((QName) req.getRoute().getType(), (CompositeNode) req.getPayload());
-                RpcResult<CompositeNode> result = rpc.get();
-                resp.setType(Message.MessageType.RESPONSE);
-                resp.setSender(getLocalIpAddress() + ":" + rpcPort);
-                resp.setRoute(req.getRoute());
-                resp.setPayload(result.isSuccessful());
-                replySocket.send(Message.serialize(resp));
-
-              } catch (IOException ex) {// | ClassNotFoundException ex) {
-                System.out.println("Rpc request could not be handled" + ex);
-              }
-            }
-            if (poller.pollin(1)) {
-              //get subscription and update routing table
-              //try {
-              Message.MessageType topic = (Message.MessageType)Message.deserialize(subscriber.recv());
-              System.out.println("Topic:[" + topic + "]");
-
-              if (subscriber.hasReceiveMore()) {
-                try {
-                  Message m = (Message) Message.deserialize(subscriber.recv());
-                  System.out.println(m);
-                  //TODO: check on msg type or topic. Both should be same. Need to normalize.
-                  if (Message.MessageType.ANNOUNCE == m.getType()) updateRoutingTable(m);
-                } catch (IOException | ClassNotFoundException e) {
-                  e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-                }
-              }
-//
-            }
-          }
-        } catch (Exception e) {
-          e.printStackTrace();
-        }
-        replySocket.setLinger(0);
-        replySocket.close();
-        subscriber.setLinger(0);
-        subscriber.close();
-      }
-    };
-  }
-
-  private void updateRoutingTable(Message msg) {
-    routingTable.put(msg.getRoute(), msg.getSender());
-    RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> route = msg.getRoute();
-    QName rpcType = route.getType();
-    System.out.println("Routing Table\n" + routingTable);
-
-    RpcRegistration registration = brokerSession.addRpcImplementation(rpcType, facade);
-  }
-
-  private Message parseMessage(ZMQ.Socket socket) {
-    //Message m = new Message();
-    //socket.setReceiveBufferSize(40000);
-    Message msg = null;
-    try {
-      byte[] bytes = socket.recv();
-      System.out.println("Received bytes:[" + bytes.length + "]");
-      msg = (Message) Message.deserialize(bytes);
-    } catch (Throwable t) {
-      System.out.println("Caught exception");
-      t.printStackTrace();
-    }
-    return msg;
-    /*m.setType((Message.MessageType) Message.deserialize(socket.recv()));
-
-    if (socket.hasReceiveMore()) {
-      m.setSender((String) Message.deserialize(socket.recv()));
-    }
-    if (socket.hasReceiveMore()) {
-      m.setRoute((RouteIdentifier) Message.deserialize(socket.recv()));
-    }
-    if (socket.hasReceiveMore()) {
-      m.setPayload(Message.deserialize(socket.recv()));
-    }
-    return m;*/
-  }
-
-  @Override
-  public Future<RpcReply<Object>> sendRpc(final RpcRequest<QName, QName, InstanceIdentifier, Object> input) {
-
-    return handlersPool.submit(new Callable<RpcReply<Object>>() {
-
-      @Override
-      public RpcReply<Object> call() {
-        ZMQ.Socket requestSocket = context.socket(ZMQ.REQ);
-        Message req = new Message();
-        Message resp = null;
-        RpcReplyImpl reply = new RpcReplyImpl();
-        requestSocket.connect((String) routingTable.get(input.getRoutingInformation().getRoute()));
-
-        req.setType(Message.MessageType.REQUEST);
-        req.setSender(getLocalIpAddress() + ":" + rpcPort);
-        req.setRoute(input.getRoutingInformation());
-        req.setPayload(input.getPayload());
-        try {
-          requestSocket.send(Message.serialize(req));
-          resp = parseMessage(requestSocket);
-          reply.setPayload(resp.getPayload());
-        } catch (IOException ex) {//| ClassNotFoundException ex) {
-          //Log and ignore
-          System.out.println("Error in RPC send. Input could not be serialized[" + input + "]");
-        }
-
-        return reply;
-      }
-    });
-  }
-
-  public void publish(final Message message) {
-    Runnable task = new Runnable() {
-      public void run() {
-        // Bind to publishing port
-        publisher = context.socket(ZMQ.PUB);
-        publisher.bind("tcp://*:" + pubPort);
-        System.out.println("Publisher started at port[" + pubPort + "]");
-        try {
-          Message outMessage =  new Message();
-          outMessage.setType(Message.MessageType.ANNOUNCE);
-          outMessage.setSender("tcp://" + getLocalIpAddress() + ":" + rpcPort);
-          outMessage.setRoute(message.getRoute());
-
-          System.out.println("Sending announcement[" + outMessage + "]");
-          publisher.sendMore(Message.serialize(Message.MessageType.ANNOUNCE));
-          publisher.send(Message.serialize(outMessage));
-
-        } catch (IOException ex) {
-          //Log and ignore
-          System.out.println("Error in publishing");
-          ex.printStackTrace();
-        }
-        System.out.println("Published message[" + message + "]");
-        publisher.close();
-      }
-    };
-    handlersPool.execute(task);
-  }
-
-  private String getLocalIpAddress() {
-    String hostAddress = null;
-    Enumeration e = null;
-    try {
-      e = NetworkInterface.getNetworkInterfaces();
-    } catch (SocketException e1) {
-      e1.printStackTrace();
-    }
-    while (e.hasMoreElements()) {
-
-      NetworkInterface n = (NetworkInterface) e.nextElement();
-      Enumeration ee = n.getInetAddresses();
-      while (ee.hasMoreElements()) {
-        InetAddress i = (InetAddress) ee.nextElement();
-        if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
-          hostAddress = i.getHostAddress();
-      }
-    }
-
-    return hostAddress;
-
-
-  }
-
-
-  private class RpcFacade implements RpcImplementation {
-
-
-    @Override
-    public Set<QName> getSupportedRpcs() {
-      return Collections.emptySet();
-    }
-
-    @Override
-    public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
-
-      RpcRequestImpl request = new RpcRequestImpl();
-      RouteIdentifierImpl routeId = new RouteIdentifierImpl();
-      routeId.setContext(null);
-      routeId.setRoute(null);
-      routeId.setType(rpc);
-
-      request.setRouteIdentifier(routeId);
-      request.setPayload(input);
-      // Create message
-
-      Future<org.opendaylight.controller.sal.connector.api.RpcRouter.RpcReply<Object>> ret = sendRpc(request);
-
-      return null;
-    }
-  }
-
-  private class RpcListener implements RpcRegistrationListener {
-
-    @Override
-    public void onRpcImplementationAdded(QName name) {
-
-      Message msg = new Message();
-      RouteIdentifierImpl routeId = new RouteIdentifierImpl();
-      routeId.setType(name);
-      msg.setRoute(routeId);
-      publish(msg);
-    }
-
-    @Override
-    public void onRpcImplementationRemoved(QName name) {
-      // TODO Auto-generated method stub
-
-    }
-  }
-
-  public void setBrokerSession(ProviderSession session) {
-    this.brokerSession = session;
-
-  }
-
-}
index f66bfd4b74aafecec742cf803ee58688edc70eb1..a1925a53b505a616b1dc3cd6b6d99146a7fe97f7 100644 (file)
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-manager</artifactId>
-            <version>0.2.2-SNAPSHOT</version>
+            <version>0.2.3-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>equinoxSDK381</groupId>
             <artifactId>logback-classic</artifactId>
             <version>1.0.9</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+            <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+            <version>4.0</version>
+        </dependency>
     </dependencies>
 </project>
index 7cd4fa52c6318eb620b28aa94fa86838a9a8867f..337648ab03d4cea9d9229ffb2eb83b711144157a 100644 (file)
@@ -23,6 +23,10 @@ public class ToasterTest {
 
     public static final String ODL = "org.opendaylight.controller";
     public static final String YANG = "org.opendaylight.yangtools";
+    public static final String CONTROLLER = "org.opendaylight.controller";
+    public static final String YANGTOOLS = "org.opendaylight.yangtools";
+    
+    
     public static final String SAMPLE = "org.opendaylight.controller.samples";
 
     @Test
@@ -50,9 +54,6 @@ public class ToasterTest {
                 mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
-                mavenBundle(ODL, "sal-binding-api").versionAsInProject(), //
-                mavenBundle(ODL, "sal-binding-config").versionAsInProject(), 
-                mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject(), //
                 
                 mavenBundle(ODL, "sal-common").versionAsInProject(), //
                 mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
@@ -62,7 +63,37 @@ public class ToasterTest {
                 mavenBundle(ODL, "config-api").versionAsInProject(), //
                 mavenBundle(ODL, "config-manager").versionAsInProject(), //
                 mavenBundle("commons-io", "commons-io").versionAsInProject(),
+                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
                 
+                mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
+                mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
+                mavenBundle("org.javassist", "javassist").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
+        
+                mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                
+                
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
+                mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
+                mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
+                
+                
+                mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
+                mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
+                mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
+                
+                mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
                 
                 mavenBundle(SAMPLE, "sample-toaster").versionAsInProject(), //
                 mavenBundle(SAMPLE, "sample-toaster-consumer").versionAsInProject(), //
index b5b1642797ab6dcbbeb4e789c353dfde0733c6f4..8569783ad79818056eb45303692ec869f57c0671 100644 (file)
@@ -21,6 +21,8 @@
         <spring.version>3.1.3.RELEASE</spring.version>
         <jersey.version>1.17</jersey.version>
         <spring-security.version>3.1.3.RELEASE</spring-security.version>
+        <netconf.version>0.2.2-SNAPSHOT</netconf.version>
+        <config.version>0.2.2-SNAPSHOT</config.version>
     </properties>
 
     <build>
             <version>1.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-netconf-connector</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal-binding-it</artifactId>
             <version>1.0-SNAPSHOT</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+        <groupId>org.opendaylight.controller.thirdparty</groupId>
+        <artifactId>exificient</artifactId>
+        <version>0.9.2</version>
+        </dependency>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam-container-native</artifactId>
             <version>${exam.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.0.10.Final</version>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.ops4j.pax.exam</groupId>
             <artifactId>pax-exam-link-mvn</artifactId>
             <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
             <version>7.0.42</version>
         </dependency>
+
+
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-api</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-manager</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-util</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-jmx-generator</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-store-api</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>yang-store-impl</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>logback-config</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-api</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-file-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-api</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-impl</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-util</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-client</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>netconf-mapping-api</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-netconf-connector</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-impl</artifactId>
+            <version>${netconf.version}</version>
+        </dependency>
     </dependencies>
 </project>
index 1087da22f9b2ddcbdb54e9e441530124ba175771..23ba8aaea41e5866fc1934290bfd17f6154aadd9 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.test.restconf.it;
 
+import static junit.framework.Assert.assertEquals;
 import static org.junit.Assert.*;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
@@ -8,14 +9,27 @@ import static org.ops4j.pax.exam.CoreOptions.systemPackages;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 import static org.ops4j.pax.exam.CoreOptions.maven;
 
+import java.net.InetSocketAddress;
+import java.net.URI;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
 
 import javax.inject.Inject;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.connect.netconf.InventoryUtils;
+import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceManager;
+import org.opendaylight.controller.sal.connect.netconf.NetconfInventoryUtils;
+import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
+import org.opendaylight.controller.sal.core.api.mount.MountProvisionService;
 import org.opendaylight.controller.test.sal.binding.it.TestHelper;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.ops4j.pax.exam.Configuration;
 import org.ops4j.pax.exam.CoreOptions;
 import org.ops4j.pax.exam.Option;
@@ -34,23 +48,55 @@ public class ServiceProviderController {
     public static final String YANG = "org.opendaylight.yangtools";
     public static final String SAMPLE = "org.opendaylight.controller.samples";
 
+    private static QName CONFIG_MODULES = new QName(
+            URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+    private static QName CONFIG_SERVICES = new QName(
+            URI.create("urn:opendaylight:params:xml:ns:yang:controller:config"), null, "modules");
+    @Inject
+    BundleContext context;
+
+    @Inject
+    MountProvisionService mountService;
+
+    @Inject
+    DataBrokerService dataBroker;
+
+    @Inject
+    NetconfDeviceManager netconfManager;
+
     @Test
     public void properInitialized() throws Exception {
 
-        Thread.sleep(30*60*1000); // Waiting for services to get wired.
-        assertTrue(true);
-        // assertTrue(consumer.createToast(WhiteBread.class, 5));
+        Map<QName, String> arg = Collections.singletonMap(InventoryUtils.INVENTORY_ID, "foo");
 
-    }
+        InstanceIdentifier path = InstanceIdentifier.builder(InventoryUtils.INVENTORY_PATH)
+                .nodeWithKey(InventoryUtils.INVENTORY_NODE, InventoryUtils.INVENTORY_ID, "foo").toInstance();
 
-    // @Inject
-    // BindingAwareBroker broker;
+        netconfManager.netconfNodeAdded(path, new InetSocketAddress("127.0.0.1", 8383));
 
-    // @Inject
-    // ToastConsumer consumer;
+        
+        InstanceIdentifier mountPointPath = path;
+        
+        /** We retrive a mountpoint **/
+        MountProvisionInstance mountPoint = mountService.getMountPoint(mountPointPath);
+        CompositeNode data = mountPoint.readOperationalData(InstanceIdentifier.builder().node(CONFIG_MODULES)
+                .toInstance());
+        assertNotNull(data);
+        assertEquals(CONFIG_MODULES, data.getNodeType());
 
-    @Inject
-    BundleContext ctx;
+        CompositeNode data2 = mountPoint.readOperationalData(InstanceIdentifier.builder().toInstance());
+        assertNotNull(data2);
+
+        InstanceIdentifier fullPath = InstanceIdentifier.builder(mountPointPath).node(CONFIG_MODULES).toInstance();
+
+        CompositeNode data3 = dataBroker.readOperationalData(fullPath);
+        assertNotNull(data3);
+        assertEquals(CONFIG_MODULES, data.getNodeType());
+
+        //Thread.sleep(30 * 60 * 1000); // Waiting for services to get wired.
+        //assertTrue(true);
+        // assertTrue(consumer.createToast(WhiteBread.class, 5));
+    }
 
     @Configuration
     public Option[] config() {
@@ -63,6 +109,7 @@ public class ServiceProviderController {
                 mdSalCoreBundles(),
                 baseModelBundles(),
                 flowCapableModelBundles(),
+                configMinumumBundles(),
 
                 // mavenBundle(ODL,
                 // "sal-binding-broker-impl").versionAsInProject().update(), //
@@ -79,6 +126,7 @@ public class ServiceProviderController {
                 // mavenBundle(SAMPLE,
                 // "zeromq-test-provider").versionAsInProject(), //
                 mavenBundle(ODL, "sal-rest-connector").versionAsInProject(), //
+                mavenBundle(ODL, "sal-netconf-connector").versionAsInProject(), //
 
                 mavenBundle(YANG, "concepts").versionAsInProject(),
                 mavenBundle(YANG, "yang-binding").versionAsInProject(), //
@@ -89,6 +137,7 @@ public class ServiceProviderController {
                 mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
                 mavenBundle(YANG, "yang-parser-api").versionAsInProject(),
                 mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
+
                 mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), //
                 mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
                 mavenBundle("com.google.guava", "guava").versionAsInProject(), //
@@ -105,8 +154,15 @@ public class ServiceProviderController {
                 // earlier.
                 systemProperty("osgi.bundles.defaultStartLevel").value("4"),
 
+                systemProperty("netconf.tcp.address").value("127.0.0.1"),
+                systemProperty("netconf.tcp.port").value("8383"),
+
                 // Set the systemPackages (used by clustering)
                 systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
+
+                mavenBundle("org.apache.servicemix.bundles", "org.apache.servicemix.bundles.xerces", "2.11.0_1"),
+                mavenBundle("org.eclipse.birt.runtime.3_7_1", "org.apache.xml.resolver", "1.2.0"),
+
                 mavenBundle("org.slf4j", "jcl-over-slf4j").versionAsInProject(),
                 mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(),
                 mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(),
@@ -140,6 +196,40 @@ public class ServiceProviderController {
                 // mavenBundle("commons-fileupload",
                 // "commons-fileupload").versionAsInProject(),
 
+                mavenBundle("io.netty", "netty-handler").versionAsInProject(),
+                mavenBundle("io.netty", "netty-codec").versionAsInProject(),
+                mavenBundle("io.netty", "netty-buffer").versionAsInProject(),
+                mavenBundle("io.netty", "netty-transport").versionAsInProject(),
+                mavenBundle("io.netty", "netty-common").versionAsInProject(),
+
+                mavenBundle(ODL, "config-api").versionAsInProject(),
+                mavenBundle(ODL, "config-manager").versionAsInProject(),
+                mavenBundle(ODL, "config-util").versionAsInProject(),
+                mavenBundle(ODL, "yang-jmx-generator").versionAsInProject(),
+                mavenBundle(ODL, "yang-store-api").versionAsInProject(),
+                mavenBundle(ODL, "yang-store-impl").versionAsInProject(),
+                mavenBundle(ODL, "logback-config").versionAsInProject(),
+                mavenBundle(ODL, "config-persister-api").versionAsInProject(),
+                // mavenBundle(ODL,"config-persister-file-adapter").versionAsInProject(),
+                mavenBundle(ODL, "netconf-api").versionAsInProject(),
+                mavenBundle(ODL, "netconf-impl").versionAsInProject(),
+                mavenBundle(ODL, "netconf-client").versionAsInProject(),
+                mavenBundle(ODL, "netconf-util").versionAsInProject(),
+                mavenBundle(ODL + ".thirdparty", "ganymed", "1.0-SNAPSHOT"),
+                mavenBundle(ODL, "netconf-mapping-api").versionAsInProject(),
+                mavenBundle(ODL, "config-netconf-connector").versionAsInProject(),
+                mavenBundle(ODL, "config-persister-impl").versionAsInProject(),
+
+                mavenBundle("org.opendaylight.bgpcep", "framework").versionAsInProject(),
+                mavenBundle("org.opendaylight.bgpcep", "util").versionAsInProject(),
+                mavenBundle(YANG, "binding-generator-spi").versionAsInProject(), //
+                mavenBundle(YANG, "binding-model-api").versionAsInProject(), //
+                mavenBundle(YANG, "binding-generator-util").versionAsInProject(),
+                mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
+                mavenBundle(YANG, "binding-type-provider").versionAsInProject(),
+
+                mavenBundle("org.opendaylight.controller.thirdparty", "exificient", "0.9.2"),
+
                 mavenBundle("equinoxSDK381", "javax.servlet").versionAsInProject(),
                 mavenBundle("equinoxSDK381", "javax.servlet.jsp").versionAsInProject(),
                 mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(),
index 989bd9e676464b669b1ba96c1c2a1a0511879328..74c08e379ffa86f4b47593a75058ce13d9d70d1f 100755 (executable)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <artifactId>config-netconf-connector</artifactId>
     <name>${project.artifactId}</name>
index fe2fc1c5da9b43ff673fd7e8e780ea5285edd69d..d404a964686596c0428a63d9f060219f4d44e3af 100644 (file)
@@ -441,8 +441,6 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         Element response = get();
 
-        System.err.println(XmlUtil.toString(response));
-
         assertEquals(2, getElementsSize(response, "instance"));
         assertEquals(2, getElementsSize(response, "asdf"));
         assertEquals(5, getElementsSize(response, "inner-running-data"));
index 603f40b020eed1858397374b49890061c815b75f..85592e5aa209a717f32c1144a839e8c23eed4e47 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <artifactId>config-persister-impl</artifactId>
     <name>${project.artifactId}</name>
@@ -72,7 +72,6 @@
                             javax.management,
                             javax.xml.parsers,
                             org.opendaylight.controller.config.persist.api,
-                            org.opendaylight.controller.config.stat,
                             org.opendaylight.controller.config.persist.api.storage,
                             org.opendaylight.controller.netconf.api,
                             org.opendaylight.controller.netconf.api.jmx,
index 08b0d1a511012803b665ea909a98610be7247a83..cd604312f4d0318fa2f55ed637e00c01b392e206 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.netconf.persist.impl;
 
 import com.google.common.base.Optional;
 import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -20,8 +20,8 @@ public class NoOpStorageAdapter implements StorageAdapter {
     private static final Logger logger = LoggerFactory.getLogger(NoOpStorageAdapter.class);
 
     @Override
-    public void setProperties(ConfigProvider configProvider) {
-        logger.debug("setProperties called with {}", configProvider);
+    public void setProperties(BundleContext bundleContext) {
+        logger.debug("setProperties called with {}", bundleContext);
     }
 
     @Override
index 03892f0da74dfafa1476eea5ac7c7d8ec85b0331..e06968e86844f1e65148e1a9e06bc08092ff8d68 100644 (file)
@@ -12,7 +12,7 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
 
 import java.io.IOException;
 
@@ -36,8 +36,8 @@ public final class PersisterImpl implements Persister {
         this.storage = storage;
     }
 
-    public static Optional<PersisterImpl> createFromProperties(ConfigProvider configProvider) {
-        String storageAdapterClass = configProvider.getProperty(STORAGE_ADAPTER_CLASS_PROP);
+    public static Optional<PersisterImpl> createFromProperties(BundleContext bundleContext) {
+        String storageAdapterClass = bundleContext.getProperty(STORAGE_ADAPTER_CLASS_PROP);
         StorageAdapter storage;
         if (storageAdapterClass == null || storageAdapterClass.equals("")) {
             return Optional.absent();
@@ -45,7 +45,7 @@ public final class PersisterImpl implements Persister {
 
         try {
             storage = StorageAdapter.class.cast(resolveClass(storageAdapterClass, StorageAdapter.class).newInstance());
-            storage.setProperties(configProvider);
+            storage.setProperties(bundleContext);
 
         } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
             throw new IllegalArgumentException("Unable to instantiate storage adapter from " + storageAdapterClass, e);
index cf1b0af454905d8aa6091085f3f3d538d3dd9029..ae6c95312c9143d29f384571ffe9182b227aa862 100644 (file)
@@ -12,7 +12,6 @@ import com.google.common.base.Optional;
 import org.opendaylight.controller.netconf.persist.impl.ConfigPersisterNotificationHandler;
 import org.opendaylight.controller.netconf.persist.impl.NoOpStorageAdapter;
 import org.opendaylight.controller.netconf.persist.impl.PersisterImpl;
-import org.opendaylight.controller.config.stat.ConfigProvider;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.TLSConfiguration;
 import org.osgi.framework.BundleActivator;
@@ -38,16 +37,15 @@ public class ConfigPersisterActivator implements BundleActivator {
     public void start(BundleContext context) throws Exception {
         logger.debug("ConfigPersister activator started");
 
-        ConfigProvider configProvider = new ConfigProvider.ConfigProviderImpl(context);
-        Optional<PersisterImpl> maybePersister = PersisterImpl.createFromProperties(configProvider);
+        Optional<PersisterImpl> maybePersister = PersisterImpl.createFromProperties(context);
         if (maybePersister.isPresent() == false) {
             throw new IllegalStateException("No persister is defined in " + PersisterImpl.STORAGE_ADAPTER_CLASS_PROP
                     + " property. For noop persister use " + NoOpStorageAdapter.class.getCanonicalName()
                     + " . Persister is not operational");
         }
 
-        Optional<TLSConfiguration> maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(configProvider);
-        Optional<InetSocketAddress> maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(configProvider);
+        Optional<TLSConfiguration> maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context);
+        Optional<InetSocketAddress> maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context);
 
         InetSocketAddress address;
         if (maybeTLSConfiguration.isPresent()) {
index df6b1db97a6fe6ed9016fbd0d4149f53584940a9..44b3b610434038aba7cfb68a20c763e97f2f7cff 100644 (file)
@@ -16,7 +16,7 @@ import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.config.persist.api.Persister;
 import org.opendaylight.controller.config.persist.api.storage.StorageAdapter;
 import org.opendaylight.controller.config.persist.storage.file.FileStorageAdapter;
-import org.opendaylight.controller.config.stat.ConfigProvider;
+import org.osgi.framework.BundleContext;
 
 import java.io.File;
 import java.io.IOException;
@@ -34,7 +34,7 @@ import static org.mockito.Mockito.verify;
 
 public class PersisterImplTest {
     @Mock
-    ConfigProvider mockedConfigProvider;
+    BundleContext mockedContext;
 
     @Before
     public void setUpMocks() {
@@ -43,10 +43,10 @@ public class PersisterImplTest {
 
     @Test
     public void testFromProperties() throws Exception {
-        doReturn(MockAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+        doReturn(MockAdapter.class.getName()).when(mockedContext).getProperty(
                 PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
 
-        PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedConfigProvider).get();
+        PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedContext).get();
         persisterImpl.persistConfig(null);
         persisterImpl.loadLastConfig();
         persisterImpl.persistConfig(null);
@@ -59,29 +59,29 @@ public class PersisterImplTest {
 
     @Test
     public void testFromProperties2() throws Exception {
-        mockedConfigProvider = mock(ConfigProvider.class);
-        doReturn(FileStorageAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+        mockedContext = mock(BundleContext.class);
+        doReturn(FileStorageAdapter.class.getName()).when(mockedContext).getProperty(
                 PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
         doReturn("target" + File.separator + "generated-test-sources" + File.separator + "testFile").when(
-                mockedConfigProvider).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
-        doReturn("mockedConfigProvider").when(mockedConfigProvider).toString();
-        doReturn(null).when(mockedConfigProvider).getProperty("numberOfBackups");
+                mockedContext).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
+        doReturn("mockedContext").when(mockedContext).toString();
+        doReturn(null).when(mockedContext).getProperty("numberOfBackups");
 
-        PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedConfigProvider).get();
+        PersisterImpl persisterImpl = PersisterImpl.createFromProperties(mockedContext).get();
         assertTrue(persisterImpl.getStorage() instanceof FileStorageAdapter);
     }
 
     @Test
     public void testFromProperties3() throws Exception {
-        mockedConfigProvider = mock(ConfigProvider.class);
-        doReturn(FileStorageAdapter.class.getName()).when(mockedConfigProvider).getProperty(
+        mockedContext = mock(BundleContext.class);
+        doReturn(FileStorageAdapter.class.getName()).when(mockedContext).getProperty(
                 PersisterImpl.STORAGE_ADAPTER_CLASS_PROP);
         doReturn("target" + File.separator + "generated-test-sources" + File.separator + "testFile").when(
-                mockedConfigProvider).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
-        doReturn("mockedConfigProvider").when(mockedConfigProvider).toString();
-        doReturn("0").when(mockedConfigProvider).getProperty("numberOfBackups");
+                mockedContext).getProperty(FileStorageAdapter.FILE_STORAGE_PROP);
+        doReturn("mockedContext").when(mockedContext).toString();
+        doReturn("0").when(mockedContext).getProperty("numberOfBackups");
         try {
-            PersisterImpl.createFromProperties(mockedConfigProvider).get();
+            PersisterImpl.createFromProperties(mockedContext).get();
             fail();
         } catch (RuntimeException e) {
             assertThat(
@@ -123,7 +123,7 @@ public class PersisterImplTest {
         static int props = 0;
 
         @Override
-        public void setProperties(ConfigProvider configProvider) {
+        public void setProperties(BundleContext configProvider) {
             props++;
         }
 
index 902cf2a8632a71dc1eac99ad46b3d79ca9a769c0..0e9b421229873365a9fe08785f41f1b93ff6834e 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>netconf-api</artifactId>
index 0864a52356e63aa59a6b4ccc4397e9ba3e98e1f6..ffd46e882c60f4a86b47470159d18139863ffff9 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <artifactId>netconf-client</artifactId>
     <name>${project.artifactId}</name>
index 1bd3a78326b67aca7f663038c1a15fa430b55cef..028e9b4bd41c2b55b2f71676275049e0dee28d4e 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>netconf-impl</artifactId>
                             org.w3c.dom,
                             org.xml.sax,
                             org.opendaylight.controller.netconf.util.messages,
-                            org.opendaylight.controller.config.stat,
                             com.siemens.ct.exi.exceptions
                         </Import-Package>
                     </instructions>
index 824518a5efc8d48062443266ba0473de45c6c9cc..fc240f91c9d168397a82c82f42577310aeb5b408 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.netconf.impl.osgi;
 
 import com.google.common.base.Optional;
 import io.netty.util.HashedWheelTimer;
-import org.opendaylight.controller.config.stat.ConfigProvider;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.NetconfServerDispatcher;
 import org.opendaylight.controller.netconf.impl.NetconfServerSessionListenerFactory;
@@ -39,9 +38,8 @@ public class NetconfImplActivator implements BundleActivator {
 
     @Override
     public void start(final BundleContext context) throws Exception {
-        final ConfigProvider configProvider = new ConfigProvider.ConfigProviderImpl(context);
-        maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(configProvider);
-        maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(configProvider);
+        maybeTCPAddress = NetconfConfigUtil.extractTCPNetconfAddress(context);
+        maybeTLSConfiguration = NetconfConfigUtil.extractTLSConfiguration(context);
         if (maybeTCPAddress.isPresent() == false && maybeTLSConfiguration.isPresent() == false) {
             throw new IllegalStateException("TCP nor TLS is configured, netconf not available.");
         }
index 6facfa8fba7d6da08d291abec853164ffb586832..8606421ab9b547d427a57d08412218ddea9f9b06 100644 (file)
@@ -7,7 +7,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
 
     <artifactId>netconf-it</artifactId>
index 9fb820695adbf18216afe20886e47133e70457ea..d7775d156d3ab8e830d9c8e1220ec02caed626ac 100644 (file)
@@ -6,7 +6,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     <artifactId>netconf-mapping-api</artifactId>
index 4638a1009e503245c58e78278cd8b0f6f83cd305..c19506b236a2d8b9cacdc7e03cc263f20a131bfb 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>netconf-subsystem</artifactId>
         <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.2-SNAPSHOT</version>
+        <version>0.2.3-SNAPSHOT</version>
     </parent>
     <artifactId>netconf-util</artifactId>
     <name>${project.artifactId}</name>
@@ -78,7 +78,6 @@
                             org.opendaylight.controller.netconf.util.handler,
                         </Export-Package>
                         <Import-Package>
-                            org.opendaylight.controller.config.stat,
                             com.google.common.base,
                             com.google.common.collect,
                             ch.ethz.ssh2,
index 54041e6602c52adc996b3d06c29f6461b5e7e4b1..76068399c17f470b249c0ba35027f89d723b5d81 100644 (file)
@@ -8,21 +8,19 @@
 
 package org.opendaylight.controller.netconf.util.osgi;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Optional;
+import org.opendaylight.protocol.util.SSLUtil;
+import org.osgi.framework.BundleContext;
 
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-
-import org.opendaylight.controller.config.stat.ConfigProvider;
-import org.opendaylight.protocol.util.SSLUtil;
-
-import com.google.common.base.Optional;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
 
 public class NetconfConfigUtil {
     private static final String PREFIX_PROP = "netconf.";
@@ -37,19 +35,19 @@ public class NetconfConfigUtil {
     private static final String NETCONF_TLS_KEYSTORE_PROP = PREFIX_PROP + InfixProp.tls + ".keystore";
     private static final String NETCONF_TLS_KEYSTORE_PASSWORD_PROP = NETCONF_TLS_KEYSTORE_PROP + ".password";
 
-    public static Optional<InetSocketAddress> extractTCPNetconfAddress(ConfigProvider configProvider) {
-        return extractSomeNetconfAddress(configProvider, InfixProp.tcp);
+    public static Optional<InetSocketAddress> extractTCPNetconfAddress(BundleContext context) {
+        return extractSomeNetconfAddress(context, InfixProp.tcp);
     }
 
-    public static Optional<TLSConfiguration> extractTLSConfiguration(ConfigProvider configProvider) {
-        Optional<InetSocketAddress> address = extractSomeNetconfAddress(configProvider, InfixProp.tls);
+    public static Optional<TLSConfiguration> extractTLSConfiguration(BundleContext context) {
+        Optional<InetSocketAddress> address = extractSomeNetconfAddress(context, InfixProp.tls);
         if (address.isPresent()) {
-            String keystoreFileName = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PROP);
+            String keystoreFileName = context.getProperty(NETCONF_TLS_KEYSTORE_PROP);
             File keystoreFile = new File(keystoreFileName);
             checkState(keystoreFile.exists() && keystoreFile.isFile() && keystoreFile.canRead(),
                     "Keystore file %s does not exist or is not readable file", keystoreFileName);
             keystoreFile = keystoreFile.getAbsoluteFile();
-            String keystorePassword = configProvider.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
+            String keystorePassword = context.getProperty(NETCONF_TLS_KEYSTORE_PASSWORD_PROP);
             checkNotNull(keystoreFileName, "Property %s must be defined for tls netconf server",
                     NETCONF_TLS_KEYSTORE_PROP);
             keystorePassword = keystorePassword != null ? keystorePassword : "";
@@ -98,7 +96,7 @@ public class NetconfConfigUtil {
     }
 
     /**
-     * @param configProvider
+     * @param context
      *            from which properties are being read.
      * @param infixProp
      *            either tcp or tls
@@ -107,14 +105,14 @@ public class NetconfConfigUtil {
      * @throws IllegalStateException
      *             if address or port are invalid
      */
-    private static Optional<InetSocketAddress> extractSomeNetconfAddress(ConfigProvider configProvider,
+    private static Optional<InetSocketAddress> extractSomeNetconfAddress(BundleContext context,
             InfixProp infixProp) {
-        String address = configProvider.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
+        String address = context.getProperty(PREFIX_PROP + infixProp + ADDRESS_SUFFIX_PROP);
         if (address == null) {
             return Optional.absent();
         }
         String portKey = PREFIX_PROP + infixProp + PORT_SUFFIX_PROP;
-        String portString = configProvider.getProperty(portKey);
+        String portString = context.getProperty(portKey);
         checkNotNull(portString, "Netconf port must be specified in properties file with " + portKey);
         try {
             int port = Integer.valueOf(portString);
index 5efff5d9a0dbcbb455a0193dcc24402478c30261..b22732e630bf0b5263d1221c9684faf2e0a14f52 100644 (file)
@@ -9,7 +9,7 @@
         <relativePath>../commons/opendaylight</relativePath>
     </parent>
 
-    <version>0.2.2-SNAPSHOT</version>
+    <version>0.2.3-SNAPSHOT</version>
     <artifactId>netconf-subsystem</artifactId>
     <packaging>pom</packaging>
     <name>${project.artifactId}</name>
index 7e5b093c072f20aa093014a56b873871977f9bd6..4202856774b81a19403a0de2f193c8aa24bf185e 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.util.Hashtable;\r
-import java.util.Dictionary;\r
-import org.apache.felix.dm.Component;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;\r
-\r
-public class Activator extends ComponentActivatorAbstractBase {\r
-    protected static final Logger logger = LoggerFactory\r
-    .getLogger(Activator.class);\r
-\r
-    /**\r
-     * Function called when the activator starts just after some\r
-     * initializations are done by the\r
-     * ComponentActivatorAbstractBase.\r
-     *\r
-     */\r
-    public void init() {\r
-\r
-    }\r
-\r
-    /**\r
-     * Function called when the activator stops just before the\r
-     * cleanup done by ComponentActivatorAbstractBase\r
-     *\r
-     */\r
-    public void destroy() {\r
-\r
-    }\r
-\r
-    /**\r
-     * Function that is used to communicate to dependency manager the\r
-     * list of known implementations for services inside a container\r
-     *\r
-     *\r
-     * @return An array containing all the CLASS objects that will be\r
-     * instantiated in order to get an fully working implementation\r
-     * Object\r
-     */\r
-    public Object[] getImplementations() {\r
-        Object[] res = { NeutronFloatingIPInterface.class,\r
-                NeutronRouterInterface.class,\r
-                NeutronPortInterface.class,\r
-                NeutronSubnetInterface.class,\r
-                NeutronNetworkInterface.class };\r
-        return res;\r
-    }\r
-\r
-    /**\r
-     * Function that is called when configuration of the dependencies\r
-     * is required.\r
-     *\r
-     * @param c dependency manager Component object, used for\r
-     * configuring the dependencies exported and imported\r
-     * @param imp Implementation class that is being configured,\r
-     * needed as long as the same routine can configure multiple\r
-     * implementations\r
-     * @param containerName The containerName being configured, this allow\r
-     * also optional per-container different behavior if needed, usually\r
-     * should not be the case though.\r
-     */\r
-    public void configureInstance(Component c, Object imp, String containerName) {\r
-        if (imp.equals(NeutronFloatingIPInterface.class)) {\r
-            // export the service\r
-            c.setInterface(\r
-                    new String[] { INeutronFloatingIPCRUD.class.getName() }, null);\r
-            Dictionary<String, String> props = new Hashtable<String, String>();\r
-            props.put("salListenerName", "neutron");\r
-            c.add(createContainerServiceDependency(containerName)\r
-                    .setService(IClusterContainerServices.class)\r
-                    .setCallbacks("setClusterContainerService",\r
-                    "unsetClusterContainerService").setRequired(true));\r
-        }\r
-        if (imp.equals(NeutronRouterInterface.class)) {\r
-            // export the service\r
-            c.setInterface(\r
-                    new String[] { INeutronRouterCRUD.class.getName() }, null);\r
-            Dictionary<String, String> props = new Hashtable<String, String>();\r
-            props.put("salListenerName", "neutron");\r
-            c.add(createContainerServiceDependency(containerName)\r
-                    .setService(IClusterContainerServices.class)\r
-                    .setCallbacks("setClusterContainerService",\r
-                    "unsetClusterContainerService").setRequired(true));\r
-        }\r
-        if (imp.equals(NeutronPortInterface.class)) {\r
-            // export the service\r
-            c.setInterface(\r
-                    new String[] { INeutronPortCRUD.class.getName() }, null);\r
-            Dictionary<String, String> props = new Hashtable<String, String>();\r
-            props.put("salListenerName", "neutron");\r
-            c.add(createContainerServiceDependency(containerName)\r
-                    .setService(IClusterContainerServices.class)\r
-                    .setCallbacks("setClusterContainerService",\r
-                    "unsetClusterContainerService").setRequired(true));\r
-        }\r
-        if (imp.equals(NeutronSubnetInterface.class)) {\r
-            // export the service\r
-            c.setInterface(\r
-                    new String[] { INeutronSubnetCRUD.class.getName() }, null);\r
-            Dictionary<String, String> props = new Hashtable<String, String>();\r
-            props.put("salListenerName", "neutron");\r
-            c.add(createContainerServiceDependency(containerName)\r
-                    .setService(IClusterContainerServices.class)\r
-                    .setCallbacks("setClusterContainerService",\r
-                    "unsetClusterContainerService").setRequired(true));\r
-        }\r
-        if (imp.equals(NeutronNetworkInterface.class)) {\r
-            // export the service\r
-            c.setInterface(\r
-                    new String[] { INeutronNetworkCRUD.class.getName() }, null);\r
-            Dictionary<String, String> props = new Hashtable<String, String>();\r
-            props.put("salListenerName", "neutron");\r
-            c.add(createContainerServiceDependency(containerName)\r
-                    .setService(IClusterContainerServices.class)\r
-                    .setCallbacks("setClusterContainerService",\r
-                    "unsetClusterContainerService").setRequired(true));\r
-        }\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.util.Hashtable;
+import java.util.Dictionary;
+import org.apache.felix.dm.Component;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
+
+public class Activator extends ComponentActivatorAbstractBase {
+    protected static final Logger logger = LoggerFactory
+    .getLogger(Activator.class);
+
+    /**
+     * Function called when the activator starts just after some
+     * initializations are done by the
+     * ComponentActivatorAbstractBase.
+     *
+     */
+    public void init() {
+
+    }
+
+    /**
+     * Function called when the activator stops just before the
+     * cleanup done by ComponentActivatorAbstractBase
+     *
+     */
+    public void destroy() {
+
+    }
+
+    /**
+     * Function that is used to communicate to dependency manager the
+     * list of known implementations for services inside a container
+     *
+     *
+     * @return An array containing all the CLASS objects that will be
+     * instantiated in order to get an fully working implementation
+     * Object
+     */
+    public Object[] getImplementations() {
+        Object[] res = { NeutronFloatingIPInterface.class,
+                NeutronRouterInterface.class,
+                NeutronPortInterface.class,
+                NeutronSubnetInterface.class,
+                NeutronNetworkInterface.class };
+        return res;
+    }
+
+    /**
+     * Function that is called when configuration of the dependencies
+     * is required.
+     *
+     * @param c dependency manager Component object, used for
+     * configuring the dependencies exported and imported
+     * @param imp Implementation class that is being configured,
+     * needed as long as the same routine can configure multiple
+     * implementations
+     * @param containerName The containerName being configured, this allow
+     * also optional per-container different behavior if needed, usually
+     * should not be the case though.
+     */
+    public void configureInstance(Component c, Object imp, String containerName) {
+        if (imp.equals(NeutronFloatingIPInterface.class)) {
+            // export the service
+            c.setInterface(
+                    new String[] { INeutronFloatingIPCRUD.class.getName() }, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(IClusterContainerServices.class)
+                    .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+        }
+        if (imp.equals(NeutronRouterInterface.class)) {
+            // export the service
+            c.setInterface(
+                    new String[] { INeutronRouterCRUD.class.getName() }, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(IClusterContainerServices.class)
+                    .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+        }
+        if (imp.equals(NeutronPortInterface.class)) {
+            // export the service
+            c.setInterface(
+                    new String[] { INeutronPortCRUD.class.getName() }, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(IClusterContainerServices.class)
+                    .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+        }
+        if (imp.equals(NeutronSubnetInterface.class)) {
+            // export the service
+            c.setInterface(
+                    new String[] { INeutronSubnetCRUD.class.getName() }, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(IClusterContainerServices.class)
+                    .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+        }
+        if (imp.equals(NeutronNetworkInterface.class)) {
+            // export the service
+            c.setInterface(
+                    new String[] { INeutronNetworkCRUD.class.getName() }, null);
+            Dictionary<String, String> props = new Hashtable<String, String>();
+            props.put("salListenerName", "neutron");
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(IClusterContainerServices.class)
+                    .setCallbacks("setClusterContainerService",
+                    "unsetClusterContainerService").setRequired(true));
+        }
+    }
+}
index 7b10756d1cd749f4d9b153b2d758e14cc6cd91ef..7d9a2e657675e767d78a774c484e07a39f81d7d9 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {\r
-    private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);\r
-    private String containerName = null;\r
-\r
-    private IClusterContainerServices clusterContainerService = null;\r
-    private ConcurrentMap<String, NeutronFloatingIP> floatingIPDB;\r
-\r
-    // methods needed for creating caches\r
-\r
-    void setClusterContainerService(IClusterContainerServices s) {\r
-        logger.debug("Cluster Service set");\r
-        this.clusterContainerService = s;\r
-    }\r
-\r
-    void unsetClusterContainerService(IClusterContainerServices s) {\r
-        if (this.clusterContainerService == s) {\r
-            logger.debug("Cluster Service removed!");\r
-            this.clusterContainerService = null;\r
-        }\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void allocateCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't create cache");\r
-            return;\r
-        }\r
-        logger.debug("Creating Cache for Neutron FloatingIPs");\r
-        try {\r
-            // neutron caches\r
-            this.clusterContainerService.createCache("neutronFloatingIPs",\r
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
-        } catch (CacheConfigException cce) {\r
-            logger.error("Cache couldn't be created for Neutron -  check cache mode");\r
-        } catch (CacheExistException cce) {\r
-            logger.error("Cache for Neutron already exists, destroy and recreate");\r
-        }\r
-        logger.debug("Cache successfully created for NeutronFloatingIps");\r
-    }\r
-\r
-    @SuppressWarnings({ "unchecked", "deprecation" })\r
-    private void retrieveCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
-            return;\r
-        }\r
-\r
-        logger.debug("Retrieving cache for Neutron FloatingIPs");\r
-        floatingIPDB = (ConcurrentMap<String, NeutronFloatingIP>) this.clusterContainerService\r
-        .getCache("neutronFloatingIPs");\r
-        if (floatingIPDB == null) {\r
-            logger.error("Cache couldn't be retrieved for Neutron FloatingIPs");\r
-        }\r
-        logger.debug("Cache was successfully retrieved for Neutron FloatingIPs");\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void destroyCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterMger, can't destroy cache");\r
-            return;\r
-        }\r
-        logger.debug("Destroying Cache for HostTracker");\r
-        this.clusterContainerService.destroyCache("neutronFloatingIPs");\r
-    }\r
-\r
-    private void startUp() {\r
-        allocateCache();\r
-        retrieveCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when all the required\r
-     * dependencies are satisfied\r
-     *\r
-     */\r
-    void init(Component c) {\r
-        Dictionary<?, ?> props = c.getServiceProperties();\r
-        if (props != null) {\r
-            this.containerName = (String) props.get("containerName");\r
-            logger.debug("Running containerName: {}", this.containerName);\r
-        } else {\r
-            // In the Global instance case the containerName is empty\r
-            this.containerName = "";\r
-        }\r
-        startUp();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when at least one dependency\r
-     * become unsatisfied or when the component is shutting down because for\r
-     * example bundle is being stopped.\r
-     *\r
-     */\r
-    void destroy() {\r
-        destroyCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by dependency manager after "init ()" is called and after\r
-     * the services provided by the class are registered in the service registry\r
-     *\r
-     */\r
-    void start() {\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager before the services exported by\r
-     * the component are unregistered, this will be followed by a "destroy ()"\r
-     * calls\r
-     *\r
-     */\r
-    void stop() {\r
-    }\r
-\r
-    // this method uses reflection to update an object from it's delta.\r
-\r
-    private boolean overwrite(Object target, Object delta) {\r
-        Method[] methods = target.getClass().getMethods();\r
-\r
-        for(Method toMethod: methods){\r
-            if(toMethod.getDeclaringClass().equals(target.getClass())\r
-                    && toMethod.getName().startsWith("set")){\r
-\r
-                String toName = toMethod.getName();\r
-                String fromName = toName.replace("set", "get");\r
-\r
-                try {\r
-                    Method fromMethod = delta.getClass().getMethod(fromName);\r
-                    Object value = fromMethod.invoke(delta, (Object[])null);\r
-                    if(value != null){\r
-                        toMethod.invoke(target, value);\r
-                    }\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    // IfNBFloatingIPCRUD interface methods\r
-\r
-    public boolean floatingIPExists(String uuid) {\r
-        return floatingIPDB.containsKey(uuid);\r
-    }\r
-\r
-    public NeutronFloatingIP getFloatingIP(String uuid) {\r
-        if (!floatingIPExists(uuid))\r
-            return null;\r
-        return floatingIPDB.get(uuid);\r
-    }\r
-\r
-    public List<NeutronFloatingIP> getAllFloatingIPs() {\r
-        Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();\r
-        for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {\r
-            NeutronFloatingIP floatingip = entry.getValue();\r
-            allIPs.add(floatingip);\r
-        }\r
-        logger.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());\r
-        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
-        ans.addAll(allIPs);\r
-        return ans;\r
-    }\r
-\r
-    public boolean addFloatingIP(NeutronFloatingIP input) {\r
-        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
-        if (floatingIPExists(input.getID()))\r
-            return false;\r
-        //if floating_ip_address isn't there, allocate from the subnet pool\r
-        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(input.getFloatingNetworkUUID()).getSubnets().get(0));\r
-        if (input.getFloatingIPAddress() == null)\r
-            input.setFloatingIPAddress(subnet.getLowAddr());\r
-        subnet.allocateIP(input.getFloatingIPAddress());\r
-\r
-        //if port_id is there, bind port to this floating ip\r
-        if (input.getPortUUID() != null) {\r
-            NeutronPort port = portCRUD.getPort(input.getPortUUID());\r
-            port.addFloatingIP(input.getFixedIPAddress(), input);\r
-        }\r
-\r
-        floatingIPDB.putIfAbsent(input.getID(), input);\r
-        return true;\r
-    }\r
-\r
-    public boolean removeFloatingIP(String uuid) {\r
-        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
-        if (!floatingIPExists(uuid))\r
-            return false;\r
-        NeutronFloatingIP floatIP = getFloatingIP(uuid);\r
-        //if floating_ip_address isn't there, allocate from the subnet pool\r
-        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(floatIP.getFloatingNetworkUUID()).getSubnets().get(0));\r
-        subnet.releaseIP(floatIP.getFloatingIPAddress());\r
-        if (floatIP.getPortUUID() != null) {\r
-            NeutronPort port = portCRUD.getPort(floatIP.getPortUUID());\r
-            port.removeFloatingIP(floatIP.getFixedIPAddress());\r
-        }\r
-        floatingIPDB.remove(uuid);\r
-        return true;\r
-    }\r
-\r
-    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {\r
-        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-\r
-        if (!floatingIPExists(uuid))\r
-            return false;\r
-        NeutronFloatingIP target = floatingIPDB.get(uuid);\r
-        if (target.getPortUUID() != null) {\r
-            NeutronPort port = portCRUD.getPort(target.getPortUUID());\r
-            port.removeFloatingIP(target.getFixedIPAddress());\r
-        }\r
-\r
-        //if port_id is there, bind port to this floating ip\r
-        if (delta.getPortUUID() != null) {\r
-            NeutronPort port = portCRUD.getPort(delta.getPortUUID());\r
-            port.addFloatingIP(delta.getFixedIPAddress(), delta);\r
-        }\r
-\r
-        target.setPortUUID(delta.getPortUUID());\r
-        target.setFixedIPAddress(delta.getFixedIPAddress());\r
-        return true;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronFloatingIPInterface implements INeutronFloatingIPCRUD {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronFloatingIPInterface.class);
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private ConcurrentMap<String, NeutronFloatingIP> floatingIPDB;
+
+    // methods needed for creating caches
+
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        this.clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (this.clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            this.clusterContainerService = null;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron FloatingIPs");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronFloatingIPs",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for NeutronFloatingIps");
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron FloatingIPs");
+        floatingIPDB = (ConcurrentMap<String, NeutronFloatingIP>) this.clusterContainerService
+        .getCache("neutronFloatingIPs");
+        if (floatingIPDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron FloatingIPs");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron FloatingIPs");
+    }
+
+    @SuppressWarnings("deprecation")
+    private void destroyCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for HostTracker");
+        this.clusterContainerService.destroyCache("neutronFloatingIPs");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    // IfNBFloatingIPCRUD interface methods
+
+    public boolean floatingIPExists(String uuid) {
+        return floatingIPDB.containsKey(uuid);
+    }
+
+    public NeutronFloatingIP getFloatingIP(String uuid) {
+        if (!floatingIPExists(uuid))
+            return null;
+        return floatingIPDB.get(uuid);
+    }
+
+    public List<NeutronFloatingIP> getAllFloatingIPs() {
+        Set<NeutronFloatingIP> allIPs = new HashSet<NeutronFloatingIP>();
+        for (Entry<String, NeutronFloatingIP> entry : floatingIPDB.entrySet()) {
+            NeutronFloatingIP floatingip = entry.getValue();
+            allIPs.add(floatingip);
+        }
+        logger.debug("Exiting getAllFloatingIPs, Found {} FloatingIPs", allIPs.size());
+        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+        ans.addAll(allIPs);
+        return ans;
+    }
+
+    public boolean addFloatingIP(NeutronFloatingIP input) {
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+        if (floatingIPExists(input.getID()))
+            return false;
+        //if floating_ip_address isn't there, allocate from the subnet pool
+        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(input.getFloatingNetworkUUID()).getSubnets().get(0));
+        if (input.getFloatingIPAddress() == null)
+            input.setFloatingIPAddress(subnet.getLowAddr());
+        subnet.allocateIP(input.getFloatingIPAddress());
+
+        //if port_id is there, bind port to this floating ip
+        if (input.getPortUUID() != null) {
+            NeutronPort port = portCRUD.getPort(input.getPortUUID());
+            port.addFloatingIP(input.getFixedIPAddress(), input);
+        }
+
+        floatingIPDB.putIfAbsent(input.getID(), input);
+        return true;
+    }
+
+    public boolean removeFloatingIP(String uuid) {
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+        INeutronSubnetCRUD subnetCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+        if (!floatingIPExists(uuid))
+            return false;
+        NeutronFloatingIP floatIP = getFloatingIP(uuid);
+        //if floating_ip_address isn't there, allocate from the subnet pool
+        NeutronSubnet subnet = subnetCRUD.getSubnet(networkCRUD.getNetwork(floatIP.getFloatingNetworkUUID()).getSubnets().get(0));
+        subnet.releaseIP(floatIP.getFloatingIPAddress());
+        if (floatIP.getPortUUID() != null) {
+            NeutronPort port = portCRUD.getPort(floatIP.getPortUUID());
+            port.removeFloatingIP(floatIP.getFixedIPAddress());
+        }
+        floatingIPDB.remove(uuid);
+        return true;
+    }
+
+    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta) {
+        INeutronPortCRUD portCRUD = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+
+        if (!floatingIPExists(uuid))
+            return false;
+        NeutronFloatingIP target = floatingIPDB.get(uuid);
+        if (target.getPortUUID() != null) {
+            NeutronPort port = portCRUD.getPort(target.getPortUUID());
+            port.removeFloatingIP(target.getFixedIPAddress());
+        }
+
+        //if port_id is there, bind port to this floating ip
+        if (delta.getPortUUID() != null) {
+            NeutronPort port = portCRUD.getPort(delta.getPortUUID());
+            port.addFloatingIP(delta.getFixedIPAddress(), delta);
+        }
+
+        target.setPortUUID(delta.getPortUUID());
+        target.setFixedIPAddress(delta.getFixedIPAddress());
+        return true;
+    }
+}
index a2454217a64327c2d8adfc707598c904c7d395ce..b1e382107adcb5e52b58da3e41a5f4b91e9881bf 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronNetworkInterface implements INeutronNetworkCRUD {\r
-    private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);\r
-    private String containerName = null;\r
-\r
-    private ConcurrentMap<String, NeutronNetwork> networkDB;\r
-    private IClusterContainerServices clusterContainerService = null;\r
-\r
-    // methods needed for creating caches\r
-\r
-    void setClusterContainerService(IClusterContainerServices s) {\r
-        logger.debug("Cluster Service set");\r
-        this.clusterContainerService = s;\r
-    }\r
-\r
-    void unsetClusterContainerService(IClusterContainerServices s) {\r
-        if (this.clusterContainerService == s) {\r
-            logger.debug("Cluster Service removed!");\r
-            this.clusterContainerService = null;\r
-        }\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void allocateCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't create cache");\r
-            return;\r
-        }\r
-        logger.debug("Creating Cache for Neutron Networks");\r
-        try {\r
-            // neutron caches\r
-            this.clusterContainerService.createCache("neutronNetworks",\r
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
-        } catch (CacheConfigException cce) {\r
-            logger.error("Cache couldn't be created for Neutron Networks -  check cache mode");\r
-        } catch (CacheExistException cce) {\r
-            logger.error("Cache for Neutron Networks already exists, destroy and recreate");\r
-        }\r
-        logger.debug("Cache successfully created for Neutron Networks");\r
-    }\r
-\r
-    @SuppressWarnings({ "unchecked", "deprecation" })\r
-    private void retrieveCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
-            return;\r
-        }\r
-        logger.debug("Retrieving cache for Neutron Networks");\r
-        networkDB = (ConcurrentMap<String, NeutronNetwork>) this.clusterContainerService.getCache("neutronNetworks");\r
-        if (networkDB == null) {\r
-            logger.error("Cache couldn't be retrieved for Neutron Networks");\r
-        }\r
-        logger.debug("Cache was successfully retrieved for Neutron Networks");\r
-    }\r
-\r
-    private void startUp() {\r
-        allocateCache();\r
-        retrieveCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when all the required\r
-     * dependencies are satisfied\r
-     *\r
-     */\r
-    void init(Component c) {\r
-        Dictionary<?, ?> props = c.getServiceProperties();\r
-        if (props != null) {\r
-            this.containerName = (String) props.get("containerName");\r
-            logger.debug("Running containerName: {}", this.containerName);\r
-        } else {\r
-            // In the Global instance case the containerName is empty\r
-            this.containerName = "";\r
-        }\r
-        startUp();\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void destroyCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterMger, can't destroy cache");\r
-            return;\r
-        }\r
-        logger.debug("Destroying Cache for Neutron Networks");\r
-        this.clusterContainerService.destroyCache("Neutron Networks");\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when at least one dependency\r
-     * become unsatisfied or when the component is shutting down because for\r
-     * example bundle is being stopped.\r
-     *\r
-     */\r
-    void destroy() {\r
-        destroyCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by dependency manager after "init ()" is called and after\r
-     * the services provided by the class are registered in the service registry\r
-     *\r
-     */\r
-    void start() {\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager before the services exported by\r
-     * the component are unregistered, this will be followed by a "destroy ()"\r
-     * calls\r
-     *\r
-     */\r
-    void stop() {\r
-    }\r
-\r
-    // this method uses reflection to update an object from it's delta.\r
-\r
-    private boolean overwrite(Object target, Object delta) {\r
-        Method[] methods = target.getClass().getMethods();\r
-\r
-        for(Method toMethod: methods){\r
-            if(toMethod.getDeclaringClass().equals(target.getClass())\r
-                    && toMethod.getName().startsWith("set")){\r
-\r
-                String toName = toMethod.getName();\r
-                String fromName = toName.replace("set", "get");\r
-\r
-                try {\r
-                    Method fromMethod = delta.getClass().getMethod(fromName);\r
-                    Object value = fromMethod.invoke(delta, (Object[])null);\r
-                    if(value != null){\r
-                        toMethod.invoke(target, value);\r
-                    }\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    // IfNBNetworkCRUD methods\r
-\r
-    public boolean networkExists(String uuid) {\r
-        return networkDB.containsKey(uuid);\r
-    }\r
-\r
-    public NeutronNetwork getNetwork(String uuid) {\r
-        if (!networkExists(uuid))\r
-            return null;\r
-        return networkDB.get(uuid);\r
-    }\r
-\r
-    public List<NeutronNetwork> getAllNetworks() {\r
-        Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();\r
-        for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {\r
-            NeutronNetwork network = entry.getValue();\r
-            allNetworks.add(network);\r
-        }\r
-        logger.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());\r
-        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
-        ans.addAll(allNetworks);\r
-        return ans;\r
-    }\r
-\r
-    public boolean addNetwork(NeutronNetwork input) {\r
-        if (networkExists(input.getID()))\r
-            return false;\r
-        networkDB.putIfAbsent(input.getID(), input);\r
-      //TODO: add code to find INeutronNetworkAware services and call newtorkCreated on them\r
-        return true;\r
-    }\r
-\r
-    public boolean removeNetwork(String uuid) {\r
-        if (!networkExists(uuid))\r
-            return false;\r
-        networkDB.remove(uuid);\r
-      //TODO: add code to find INeutronNetworkAware services and call newtorkDeleted on them\r
-        return true;\r
-    }\r
-\r
-    public boolean updateNetwork(String uuid, NeutronNetwork delta) {\r
-        if (!networkExists(uuid))\r
-            return false;\r
-        NeutronNetwork target = networkDB.get(uuid);\r
-        return overwrite(target, delta);\r
-    }\r
-\r
-    public boolean networkInUse(String netUUID) {\r
-        if (!networkExists(netUUID))\r
-            return true;\r
-        NeutronNetwork target = networkDB.get(netUUID);\r
-        if (target.getPortsOnNetwork().size() > 0)\r
-            return true;\r
-        return false;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronNetworkInterface implements INeutronNetworkCRUD {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronNetworkInterface.class);
+    private String containerName = null;
+
+    private ConcurrentMap<String, NeutronNetwork> networkDB;
+    private IClusterContainerServices clusterContainerService = null;
+
+    // methods needed for creating caches
+
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        this.clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (this.clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            this.clusterContainerService = null;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron Networks");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronNetworks",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron Networks -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron Networks already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for Neutron Networks");
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+        logger.debug("Retrieving cache for Neutron Networks");
+        networkDB = (ConcurrentMap<String, NeutronNetwork>) this.clusterContainerService.getCache("neutronNetworks");
+        if (networkDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Networks");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Networks");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    @SuppressWarnings("deprecation")
+    private void destroyCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for Neutron Networks");
+        this.clusterContainerService.destroyCache("Neutron Networks");
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    // IfNBNetworkCRUD methods
+
+    public boolean networkExists(String uuid) {
+        return networkDB.containsKey(uuid);
+    }
+
+    public NeutronNetwork getNetwork(String uuid) {
+        if (!networkExists(uuid))
+            return null;
+        return networkDB.get(uuid);
+    }
+
+    public List<NeutronNetwork> getAllNetworks() {
+        Set<NeutronNetwork> allNetworks = new HashSet<NeutronNetwork>();
+        for (Entry<String, NeutronNetwork> entry : networkDB.entrySet()) {
+            NeutronNetwork network = entry.getValue();
+            allNetworks.add(network);
+        }
+        logger.debug("Exiting getAllNetworks, Found {} OpenStackNetworks", allNetworks.size());
+        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+        ans.addAll(allNetworks);
+        return ans;
+    }
+
+    public boolean addNetwork(NeutronNetwork input) {
+        if (networkExists(input.getID()))
+            return false;
+        networkDB.putIfAbsent(input.getID(), input);
+      //TODO: add code to find INeutronNetworkAware services and call newtorkCreated on them
+        return true;
+    }
+
+    public boolean removeNetwork(String uuid) {
+        if (!networkExists(uuid))
+            return false;
+        networkDB.remove(uuid);
+      //TODO: add code to find INeutronNetworkAware services and call newtorkDeleted on them
+        return true;
+    }
+
+    public boolean updateNetwork(String uuid, NeutronNetwork delta) {
+        if (!networkExists(uuid))
+            return false;
+        NeutronNetwork target = networkDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    public boolean networkInUse(String netUUID) {
+        if (!networkExists(netUUID))
+            return true;
+        NeutronNetwork target = networkDB.get(netUUID);
+        if (target.getPortsOnNetwork().size() > 0)
+            return true;
+        return false;
+    }
+}
index 8f1e70f052832ebb68ef38045d1b80638b2fca66..fd030e178bd021cb8ec4ccfcb14c1877d89b172a 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronPortInterface implements INeutronPortCRUD {\r
-    private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);\r
-    private String containerName = null;\r
-\r
-    private IClusterContainerServices clusterContainerService = null;\r
-    private ConcurrentMap<String, NeutronPort> portDB;\r
-\r
-    // methods needed for creating caches\r
-\r
-    void setClusterContainerService(IClusterContainerServices s) {\r
-        logger.debug("Cluster Service set");\r
-        clusterContainerService = s;\r
-    }\r
-\r
-    void unsetClusterContainerService(IClusterContainerServices s) {\r
-        if (clusterContainerService == s) {\r
-            logger.debug("Cluster Service removed!");\r
-            clusterContainerService = null;\r
-        }\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void allocateCache() {\r
-        if (clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't create cache");\r
-            return;\r
-        }\r
-        logger.debug("Creating Cache for OpenDOVE");\r
-        try {\r
-            // neutron caches\r
-            clusterContainerService.createCache("neutronPorts",\r
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
-        } catch (CacheConfigException cce) {\r
-            logger.error("Cache couldn't be created for OpenDOVE -  check cache mode");\r
-        } catch (CacheExistException cce) {\r
-            logger.error("Cache for OpenDOVE already exists, destroy and recreate");\r
-        }\r
-        logger.debug("Cache successfully created for OpenDOVE");\r
-    }\r
-\r
-    @SuppressWarnings({ "unchecked", "deprecation" })\r
-    private void retrieveCache() {\r
-        if (clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
-            return;\r
-        }\r
-\r
-        logger.debug("Retrieving cache for Neutron Ports");\r
-        portDB = (ConcurrentMap<String, NeutronPort>) clusterContainerService\r
-        .getCache("neutronPorts");\r
-        if (portDB == null) {\r
-            logger.error("Cache couldn't be retrieved for Neutron Ports");\r
-        }\r
-        logger.debug("Cache was successfully retrieved for Neutron Ports");\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void destroyCache() {\r
-        if (clusterContainerService == null) {\r
-            logger.error("un-initialized clusterMger, can't destroy cache");\r
-            return;\r
-        }\r
-        logger.debug("Destroying Cache for HostTracker");\r
-        clusterContainerService.destroyCache("neutronPorts");\r
-    }\r
-\r
-    private void startUp() {\r
-        allocateCache();\r
-        retrieveCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when all the required\r
-     * dependencies are satisfied\r
-     *\r
-     */\r
-    void init(Component c) {\r
-        Dictionary<?, ?> props = c.getServiceProperties();\r
-        if (props != null) {\r
-            containerName = (String) props.get("containerName");\r
-            logger.debug("Running containerName: {}", containerName);\r
-        } else {\r
-            // In the Global instance case the containerName is empty\r
-            containerName = "";\r
-        }\r
-        startUp();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when at least one dependency\r
-     * become unsatisfied or when the component is shutting down because for\r
-     * example bundle is being stopped.\r
-     *\r
-     */\r
-    void destroy() {\r
-        destroyCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by dependency manager after "init ()" is called and after\r
-     * the services provided by the class are registered in the service registry\r
-     *\r
-     */\r
-    void start() {\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager before the services exported by\r
-     * the component are unregistered, this will be followed by a "destroy ()"\r
-     * calls\r
-     *\r
-     */\r
-    void stop() {\r
-    }\r
-\r
-    // this method uses reflection to update an object from it's delta.\r
-\r
-    private boolean overwrite(Object target, Object delta) {\r
-        Method[] methods = target.getClass().getMethods();\r
-\r
-        for(Method toMethod: methods){\r
-            if(toMethod.getDeclaringClass().equals(target.getClass())\r
-                    && toMethod.getName().startsWith("set")){\r
-\r
-                String toName = toMethod.getName();\r
-                String fromName = toName.replace("set", "get");\r
-\r
-                try {\r
-                    Method fromMethod = delta.getClass().getMethod(fromName);\r
-                    Object value = fromMethod.invoke(delta, (Object[])null);\r
-                    if(value != null){\r
-                        toMethod.invoke(target, value);\r
-                    }\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    // IfNBPortCRUD methods\r
-\r
-    @Override\r
-    public boolean portExists(String uuid) {\r
-        return portDB.containsKey(uuid);\r
-    }\r
-\r
-    @Override\r
-    public NeutronPort getPort(String uuid) {\r
-        if (!portExists(uuid)) {\r
-            return null;\r
-        }\r
-        return portDB.get(uuid);\r
-    }\r
-\r
-    @Override\r
-    public List<NeutronPort> getAllPorts() {\r
-        Set<NeutronPort> allPorts = new HashSet<NeutronPort>();\r
-        for (Entry<String, NeutronPort> entry : portDB.entrySet()) {\r
-            NeutronPort port = entry.getValue();\r
-            allPorts.add(port);\r
-        }\r
-        logger.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());\r
-        List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
-        ans.addAll(allPorts);\r
-        return ans;\r
-    }\r
-\r
-    @Override\r
-    public boolean addPort(NeutronPort input) {\r
-        if (portExists(input.getID())) {\r
-            return false;\r
-        }\r
-        portDB.putIfAbsent(input.getID(), input);\r
-        // if there are no fixed IPs, allocate one for each subnet in the network\r
-        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        if (input.getFixedIPs().size() == 0) {\r
-            List<Neutron_IPs> list = input.getFixedIPs();\r
-            Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();\r
-            while (subnetIterator.hasNext()) {\r
-                NeutronSubnet subnet = subnetIterator.next();\r
-                if (subnet.getNetworkUUID().equals(input.getNetworkUUID())) {\r
-                    list.add(new Neutron_IPs(subnet.getID()));\r
-                }\r
-            }\r
-        }\r
-        Iterator<Neutron_IPs> fixedIPIterator = input.getFixedIPs().iterator();\r
-        while (fixedIPIterator.hasNext()) {\r
-            Neutron_IPs ip = fixedIPIterator.next();\r
-            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
-            if (ip.getIpAddress() == null) {\r
-                ip.setIpAddress(subnet.getLowAddr());\r
-            }\r
-            if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {\r
-                subnet.allocateIP(ip.getIpAddress());\r
-            }\r
-            else {\r
-                subnet.setGatewayIPAllocated();\r
-            }\r
-            subnet.addPort(input);\r
-        }\r
-        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
-        NeutronNetwork network = networkIf.getNetwork(input.getNetworkUUID());\r
-        network.addPort(input);\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean removePort(String uuid) {\r
-        if (!portExists(uuid)) {\r
-            return false;\r
-        }\r
-        NeutronPort port = getPort(uuid);\r
-        portDB.remove(uuid);\r
-        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-\r
-        NeutronNetwork network = networkCRUD.getNetwork(port.getNetworkUUID());\r
-        network.removePort(port);\r
-        Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();\r
-        while (fixedIPIterator.hasNext()) {\r
-            Neutron_IPs ip = fixedIPIterator.next();\r
-            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
-            if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {\r
-                subnet.releaseIP(ip.getIpAddress());\r
-            }\r
-            else {\r
-                subnet.resetGatewayIPAllocated();\r
-            }\r
-            subnet.removePort(port);\r
-        }\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean updatePort(String uuid, NeutronPort delta) {\r
-        if (!portExists(uuid)) {\r
-            return false;\r
-        }\r
-        NeutronPort target = portDB.get(uuid);\r
-        // remove old Fixed_IPs\r
-        if (delta.getFixedIPs() != null) {\r
-            NeutronPort port = getPort(uuid);\r
-            INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-            for (Neutron_IPs ip: port.getFixedIPs()) {\r
-                NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
-                subnet.releaseIP(ip.getIpAddress());\r
-            }\r
-\r
-            // allocate new Fixed_IPs\r
-            for (Neutron_IPs ip: delta.getFixedIPs()) {\r
-                NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());\r
-                if (ip.getIpAddress() == null) {\r
-                    ip.setIpAddress(subnet.getLowAddr());\r
-                }\r
-                subnet.allocateIP(ip.getIpAddress());\r
-            }\r
-        }\r
-        return overwrite(target, delta);\r
-    }\r
-\r
-    @Override\r
-    public boolean macInUse(String macAddress) {\r
-        List<NeutronPort> ports = getAllPorts();\r
-        Iterator<NeutronPort> portIterator = ports.iterator();\r
-        while (portIterator.hasNext()) {\r
-            NeutronPort port = portIterator.next();\r
-            if (macAddress.equalsIgnoreCase(port.getMacAddress())) {\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    @Override\r
-    public NeutronPort getGatewayPort(String subnetUUID) {\r
-        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        NeutronSubnet subnet = systemCRUD.getSubnet(subnetUUID);\r
-        Iterator<NeutronPort> portIterator = getAllPorts().iterator();\r
-        while (portIterator.hasNext()) {\r
-            NeutronPort port = portIterator.next();\r
-            List<Neutron_IPs> fixedIPs = port.getFixedIPs();\r
-            if (fixedIPs.size() == 1) {\r
-                if (subnet.getGatewayIP().equals(fixedIPs.get(0).getIpAddress())) {\r
-                    return port;\r
-                }\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronPortInterface implements INeutronPortCRUD {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronPortInterface.class);
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private ConcurrentMap<String, NeutronPort> portDB;
+
+    // methods needed for creating caches
+
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            clusterContainerService = null;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private void allocateCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for OpenDOVE");
+        try {
+            // neutron caches
+            clusterContainerService.createCache("neutronPorts",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for OpenDOVE -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for OpenDOVE already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for OpenDOVE");
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron Ports");
+        portDB = (ConcurrentMap<String, NeutronPort>) clusterContainerService
+        .getCache("neutronPorts");
+        if (portDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Ports");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Ports");
+    }
+
+    @SuppressWarnings("deprecation")
+    private void destroyCache() {
+        if (clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for HostTracker");
+        clusterContainerService.destroyCache("neutronPorts");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    // IfNBPortCRUD methods
+
+    @Override
+    public boolean portExists(String uuid) {
+        return portDB.containsKey(uuid);
+    }
+
+    @Override
+    public NeutronPort getPort(String uuid) {
+        if (!portExists(uuid)) {
+            return null;
+        }
+        return portDB.get(uuid);
+    }
+
+    @Override
+    public List<NeutronPort> getAllPorts() {
+        Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
+        for (Entry<String, NeutronPort> entry : portDB.entrySet()) {
+            NeutronPort port = entry.getValue();
+            allPorts.add(port);
+        }
+        logger.debug("Exiting getAllPorts, Found {} OpenStackPorts", allPorts.size());
+        List<NeutronPort> ans = new ArrayList<NeutronPort>();
+        ans.addAll(allPorts);
+        return ans;
+    }
+
+    @Override
+    public boolean addPort(NeutronPort input) {
+        if (portExists(input.getID())) {
+            return false;
+        }
+        portDB.putIfAbsent(input.getID(), input);
+        // if there are no fixed IPs, allocate one for each subnet in the network
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        if (input.getFixedIPs().size() == 0) {
+            List<Neutron_IPs> list = input.getFixedIPs();
+            Iterator<NeutronSubnet> subnetIterator = systemCRUD.getAllSubnets().iterator();
+            while (subnetIterator.hasNext()) {
+                NeutronSubnet subnet = subnetIterator.next();
+                if (subnet.getNetworkUUID().equals(input.getNetworkUUID())) {
+                    list.add(new Neutron_IPs(subnet.getID()));
+                }
+            }
+        }
+        Iterator<Neutron_IPs> fixedIPIterator = input.getFixedIPs().iterator();
+        while (fixedIPIterator.hasNext()) {
+            Neutron_IPs ip = fixedIPIterator.next();
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+            if (ip.getIpAddress() == null) {
+                ip.setIpAddress(subnet.getLowAddr());
+            }
+            if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {
+                subnet.allocateIP(ip.getIpAddress());
+            }
+            else {
+                subnet.setGatewayIPAllocated();
+            }
+            subnet.addPort(input);
+        }
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+        NeutronNetwork network = networkIf.getNetwork(input.getNetworkUUID());
+        network.addPort(input);
+        return true;
+    }
+
+    @Override
+    public boolean removePort(String uuid) {
+        if (!portExists(uuid)) {
+            return false;
+        }
+        NeutronPort port = getPort(uuid);
+        portDB.remove(uuid);
+        INeutronNetworkCRUD networkCRUD = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+
+        NeutronNetwork network = networkCRUD.getNetwork(port.getNetworkUUID());
+        network.removePort(port);
+        Iterator<Neutron_IPs> fixedIPIterator = port.getFixedIPs().iterator();
+        while (fixedIPIterator.hasNext()) {
+            Neutron_IPs ip = fixedIPIterator.next();
+            NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+            if (!ip.getIpAddress().equals(subnet.getGatewayIP())) {
+                subnet.releaseIP(ip.getIpAddress());
+            }
+            else {
+                subnet.resetGatewayIPAllocated();
+            }
+            subnet.removePort(port);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePort(String uuid, NeutronPort delta) {
+        if (!portExists(uuid)) {
+            return false;
+        }
+        NeutronPort target = portDB.get(uuid);
+        // remove old Fixed_IPs
+        if (delta.getFixedIPs() != null) {
+            NeutronPort port = getPort(uuid);
+            INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+            for (Neutron_IPs ip: port.getFixedIPs()) {
+                NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+                subnet.releaseIP(ip.getIpAddress());
+            }
+
+            // allocate new Fixed_IPs
+            for (Neutron_IPs ip: delta.getFixedIPs()) {
+                NeutronSubnet subnet = systemCRUD.getSubnet(ip.getSubnetUUID());
+                if (ip.getIpAddress() == null) {
+                    ip.setIpAddress(subnet.getLowAddr());
+                }
+                subnet.allocateIP(ip.getIpAddress());
+            }
+        }
+        return overwrite(target, delta);
+    }
+
+    @Override
+    public boolean macInUse(String macAddress) {
+        List<NeutronPort> ports = getAllPorts();
+        Iterator<NeutronPort> portIterator = ports.iterator();
+        while (portIterator.hasNext()) {
+            NeutronPort port = portIterator.next();
+            if (macAddress.equalsIgnoreCase(port.getMacAddress())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public NeutronPort getGatewayPort(String subnetUUID) {
+        INeutronSubnetCRUD systemCRUD = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        NeutronSubnet subnet = systemCRUD.getSubnet(subnetUUID);
+        Iterator<NeutronPort> portIterator = getAllPorts().iterator();
+        while (portIterator.hasNext()) {
+            NeutronPort port = portIterator.next();
+            List<Neutron_IPs> fixedIPs = port.getFixedIPs();
+            if (fixedIPs.size() == 1) {
+                if (subnet.getGatewayIP().equals(fixedIPs.get(0).getIpAddress())) {
+                    return port;
+                }
+            }
+        }
+        return null;
+    }
+
+}
index 0a7afa562c2d5365cb52dabc6dfd34f975aad678..0e64dc5a098284640bb9d242a68e3649e100cf5e 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronRouterInterface implements INeutronRouterCRUD {\r
-    private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);\r
-    private String containerName = null;\r
-\r
-    private IClusterContainerServices clusterContainerService = null;\r
-    private ConcurrentMap<String, NeutronRouter> routerDB;\r
-    // methods needed for creating caches\r
-\r
-    void setClusterContainerService(IClusterContainerServices s) {\r
-        logger.debug("Cluster Service set");\r
-        this.clusterContainerService = s;\r
-    }\r
-\r
-    void unsetClusterContainerService(IClusterContainerServices s) {\r
-        if (this.clusterContainerService == s) {\r
-            logger.debug("Cluster Service removed!");\r
-            this.clusterContainerService = null;\r
-        }\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void allocateCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't create cache");\r
-            return;\r
-        }\r
-        logger.debug("Creating Cache for Neutron Routers");\r
-        try {\r
-            // neutron caches\r
-            this.clusterContainerService.createCache("neutronRouters",\r
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
-        } catch (CacheConfigException cce) {\r
-            logger.error("Cache couldn't be created for Neutron Routers -  check cache mode");\r
-        } catch (CacheExistException cce) {\r
-            logger.error("Cache for Neutron Routers already exists, destroy and recreate");\r
-        }\r
-        logger.debug("Cache successfully created for Neutron Routers");\r
-    }\r
-\r
-    @SuppressWarnings({ "unchecked", "deprecation" })\r
-    private void retrieveCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
-            return;\r
-        }\r
-\r
-        logger.debug("Retrieving cache for Neutron Routers");\r
-        routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService\r
-        .getCache("neutronRouters");\r
-        if (routerDB == null) {\r
-            logger.error("Cache couldn't be retrieved for Neutron Routers");\r
-        }\r
-        logger.debug("Cache was successfully retrieved for Neutron Routers");\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void destroyCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterMger, can't destroy cache");\r
-            return;\r
-        }\r
-        logger.debug("Destroying Cache for HostTracker");\r
-        this.clusterContainerService.destroyCache("neutronRouters");\r
-    }\r
-\r
-    private void startUp() {\r
-        allocateCache();\r
-        retrieveCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when all the required\r
-     * dependencies are satisfied\r
-     *\r
-     */\r
-    void init(Component c) {\r
-        Dictionary<?, ?> props = c.getServiceProperties();\r
-        if (props != null) {\r
-            this.containerName = (String) props.get("containerName");\r
-            logger.debug("Running containerName: {}", this.containerName);\r
-        } else {\r
-            // In the Global instance case the containerName is empty\r
-            this.containerName = "";\r
-        }\r
-        startUp();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when at least one dependency\r
-     * become unsatisfied or when the component is shutting down because for\r
-     * example bundle is being stopped.\r
-     *\r
-     */\r
-    void destroy() {\r
-        destroyCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by dependency manager after "init ()" is called and after\r
-     * the services provided by the class are registered in the service registry\r
-     *\r
-     */\r
-    void start() {\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager before the services exported by\r
-     * the component are unregistered, this will be followed by a "destroy ()"\r
-     * calls\r
-     *\r
-     */\r
-    void stop() {\r
-    }\r
-\r
-    // this method uses reflection to update an object from it's delta.\r
-\r
-    private boolean overwrite(Object target, Object delta) {\r
-        Method[] methods = target.getClass().getMethods();\r
-\r
-        for(Method toMethod: methods){\r
-            if(toMethod.getDeclaringClass().equals(target.getClass())\r
-                    && toMethod.getName().startsWith("set")){\r
-\r
-                String toName = toMethod.getName();\r
-                String fromName = toName.replace("set", "get");\r
-\r
-                try {\r
-                    Method fromMethod = delta.getClass().getMethod(fromName);\r
-                    Object value = fromMethod.invoke(delta, (Object[])null);\r
-                    if(value != null){\r
-                        toMethod.invoke(target, value);\r
-                    }\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-\r
-    // IfNBRouterCRUD Interface methods\r
-\r
-    public boolean routerExists(String uuid) {\r
-        return routerDB.containsKey(uuid);\r
-    }\r
-\r
-    public NeutronRouter getRouter(String uuid) {\r
-        if (!routerExists(uuid))\r
-            return null;\r
-        return routerDB.get(uuid);\r
-    }\r
-\r
-    public List<NeutronRouter> getAllRouters() {\r
-        Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();\r
-        for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {\r
-            NeutronRouter router = entry.getValue();\r
-            allRouters.add(router);\r
-        }\r
-        logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());\r
-        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
-        ans.addAll(allRouters);\r
-        return ans;\r
-    }\r
-\r
-    public boolean addRouter(NeutronRouter input) {\r
-        if (routerExists(input.getID()))\r
-            return false;\r
-        routerDB.putIfAbsent(input.getID(), input);\r
-        return true;\r
-    }\r
-\r
-    public boolean removeRouter(String uuid) {\r
-        if (!routerExists(uuid))\r
-            return false;\r
-        routerDB.remove(uuid);\r
-        return true;\r
-    }\r
-\r
-    public boolean updateRouter(String uuid, NeutronRouter delta) {\r
-        if (!routerExists(uuid))\r
-            return false;\r
-        NeutronRouter target = routerDB.get(uuid);\r
-        return overwrite(target, delta);\r
-    }\r
-\r
-    public boolean routerInUse(String routerUUID) {\r
-        if (!routerExists(routerUUID))\r
-            return true;\r
-        NeutronRouter target = routerDB.get(routerUUID);\r
-        return (target.getInterfaces().size() > 0);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronRouterInterface implements INeutronRouterCRUD {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronRouterInterface.class);
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private ConcurrentMap<String, NeutronRouter> routerDB;
+    // methods needed for creating caches
+
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        this.clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (this.clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            this.clusterContainerService = null;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron Routers");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronRouters",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron Routers -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron Routers already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for Neutron Routers");
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron Routers");
+        routerDB = (ConcurrentMap<String, NeutronRouter>) this.clusterContainerService
+        .getCache("neutronRouters");
+        if (routerDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Routers");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Routers");
+    }
+
+    @SuppressWarnings("deprecation")
+    private void destroyCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for HostTracker");
+        this.clusterContainerService.destroyCache("neutronRouters");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+
+    // IfNBRouterCRUD Interface methods
+
+    public boolean routerExists(String uuid) {
+        return routerDB.containsKey(uuid);
+    }
+
+    public NeutronRouter getRouter(String uuid) {
+        if (!routerExists(uuid))
+            return null;
+        return routerDB.get(uuid);
+    }
+
+    public List<NeutronRouter> getAllRouters() {
+        Set<NeutronRouter> allRouters = new HashSet<NeutronRouter>();
+        for (Entry<String, NeutronRouter> entry : routerDB.entrySet()) {
+            NeutronRouter router = entry.getValue();
+            allRouters.add(router);
+        }
+        logger.debug("Exiting getAllRouters, Found {} Routers", allRouters.size());
+        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+        ans.addAll(allRouters);
+        return ans;
+    }
+
+    public boolean addRouter(NeutronRouter input) {
+        if (routerExists(input.getID()))
+            return false;
+        routerDB.putIfAbsent(input.getID(), input);
+        return true;
+    }
+
+    public boolean removeRouter(String uuid) {
+        if (!routerExists(uuid))
+            return false;
+        routerDB.remove(uuid);
+        return true;
+    }
+
+    public boolean updateRouter(String uuid, NeutronRouter delta) {
+        if (!routerExists(uuid))
+            return false;
+        NeutronRouter target = routerDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    public boolean routerInUse(String routerUUID) {
+        if (!routerExists(routerUUID))
+            return true;
+        NeutronRouter target = routerDB.get(routerUUID);
+        return (target.getInterfaces().size() > 0);
+    }
+}
index 0fc333723a61874f17c7d2409a80a928adc36c98..62ef64c74c705fe8d0fb0f92c913d750157ece9c 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.implementation;\r
-\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Dictionary;\r
-import java.util.EnumSet;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.Map.Entry;\r
-import java.util.concurrent.ConcurrentMap;\r
-\r
-import org.apache.felix.dm.Component;\r
-import org.opendaylight.controller.clustering.services.CacheConfigException;\r
-import org.opendaylight.controller.clustering.services.CacheExistException;\r
-import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
-import org.opendaylight.controller.clustering.services.IClusterServices;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-public class NeutronSubnetInterface implements INeutronSubnetCRUD {\r
-    private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);\r
-    private String containerName = null;\r
-\r
-    private IClusterContainerServices clusterContainerService = null;\r
-    private ConcurrentMap<String, NeutronSubnet> subnetDB;\r
-\r
-    // methods needed for creating caches\r
-\r
-    void setClusterContainerService(IClusterContainerServices s) {\r
-        logger.debug("Cluster Service set");\r
-        this.clusterContainerService = s;\r
-    }\r
-\r
-    void unsetClusterContainerService(IClusterContainerServices s) {\r
-        if (this.clusterContainerService == s) {\r
-            logger.debug("Cluster Service removed!");\r
-            this.clusterContainerService = null;\r
-        }\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void allocateCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't create cache");\r
-            return;\r
-        }\r
-        logger.debug("Creating Cache for Neutron Subnets");\r
-        try {\r
-            // neutron caches\r
-            this.clusterContainerService.createCache("neutronSubnets",\r
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));\r
-        } catch (CacheConfigException cce) {\r
-            logger.error("Cache couldn't be created for Neutron Subnets -  check cache mode");\r
-        } catch (CacheExistException cce) {\r
-            logger.error("Cache for Neutron Subnets already exists, destroy and recreate");\r
-        }\r
-        logger.debug("Cache successfully created for Neutron Subnets");\r
-    }\r
-\r
-    @SuppressWarnings({ "unchecked", "deprecation" })\r
-    private void retrieveCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterContainerService, can't retrieve cache");\r
-            return;\r
-        }\r
-\r
-        logger.debug("Retrieving cache for Neutron Subnets");\r
-        subnetDB = (ConcurrentMap<String, NeutronSubnet>) this.clusterContainerService\r
-        .getCache("neutronSubnets");\r
-        if (subnetDB == null) {\r
-            logger.error("Cache couldn't be retrieved for Neutron Subnets");\r
-        }\r
-        logger.debug("Cache was successfully retrieved for Neutron Subnets");\r
-    }\r
-\r
-    @SuppressWarnings("deprecation")\r
-    private void destroyCache() {\r
-        if (this.clusterContainerService == null) {\r
-            logger.error("un-initialized clusterMger, can't destroy cache");\r
-            return;\r
-        }\r
-        logger.debug("Destroying Cache for HostTracker");\r
-        this.clusterContainerService.destroyCache("neutronSubnets");\r
-    }\r
-\r
-    private void startUp() {\r
-        allocateCache();\r
-        retrieveCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when all the required\r
-     * dependencies are satisfied\r
-     *\r
-     */\r
-    void init(Component c) {\r
-        Dictionary<?, ?> props = c.getServiceProperties();\r
-        if (props != null) {\r
-            this.containerName = (String) props.get("containerName");\r
-            logger.debug("Running containerName: {}", this.containerName);\r
-        } else {\r
-            // In the Global instance case the containerName is empty\r
-            this.containerName = "";\r
-        }\r
-        startUp();\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager when at least one dependency\r
-     * become unsatisfied or when the component is shutting down because for\r
-     * example bundle is being stopped.\r
-     *\r
-     */\r
-    void destroy() {\r
-        destroyCache();\r
-    }\r
-\r
-    /**\r
-     * Function called by dependency manager after "init ()" is called and after\r
-     * the services provided by the class are registered in the service registry\r
-     *\r
-     */\r
-    void start() {\r
-    }\r
-\r
-    /**\r
-     * Function called by the dependency manager before the services exported by\r
-     * the component are unregistered, this will be followed by a "destroy ()"\r
-     * calls\r
-     *\r
-     */\r
-    void stop() {\r
-    }\r
-\r
-    // this method uses reflection to update an object from it's delta.\r
-\r
-    private boolean overwrite(Object target, Object delta) {\r
-        Method[] methods = target.getClass().getMethods();\r
-\r
-        for(Method toMethod: methods){\r
-            if(toMethod.getDeclaringClass().equals(target.getClass())\r
-                    && toMethod.getName().startsWith("set")){\r
-\r
-                String toName = toMethod.getName();\r
-                String fromName = toName.replace("set", "get");\r
-\r
-                try {\r
-                    Method fromMethod = delta.getClass().getMethod(fromName);\r
-                    Object value = fromMethod.invoke(delta, (Object[])null);\r
-                    if(value != null){\r
-                        toMethod.invoke(target, value);\r
-                    }\r
-                } catch (Exception e) {\r
-                    e.printStackTrace();\r
-                    return false;\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-\r
-    // IfNBSubnetCRUD methods\r
-\r
-    public boolean subnetExists(String uuid) {\r
-        return subnetDB.containsKey(uuid);\r
-    }\r
-\r
-    public NeutronSubnet getSubnet(String uuid) {\r
-        if (!subnetExists(uuid))\r
-            return null;\r
-        return subnetDB.get(uuid);\r
-    }\r
-\r
-    public List<NeutronSubnet> getAllSubnets() {\r
-        Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();\r
-        for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {\r
-            NeutronSubnet subnet = entry.getValue();\r
-            allSubnets.add(subnet);\r
-        }\r
-        logger.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());\r
-        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
-        ans.addAll(allSubnets);\r
-        return ans;\r
-    }\r
-\r
-    public boolean addSubnet(NeutronSubnet input) {\r
-        String id = input.getID();\r
-        if (subnetExists(id))\r
-            return false;\r
-        subnetDB.putIfAbsent(id, input);\r
-        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
-        NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());\r
-        targetNet.addSubnet(id);\r
-        return true;\r
-    }\r
-\r
-    public boolean removeSubnet(String uuid) {\r
-        if (!subnetExists(uuid))\r
-            return false;\r
-        NeutronSubnet target = subnetDB.get(uuid);\r
-        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);\r
-\r
-        NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());\r
-        targetNet.removeSubnet(uuid);\r
-        subnetDB.remove(uuid);\r
-        return true;\r
-    }\r
-\r
-    public boolean updateSubnet(String uuid, NeutronSubnet delta) {\r
-        if (!subnetExists(uuid))\r
-            return false;\r
-        NeutronSubnet target = subnetDB.get(uuid);\r
-        return overwrite(target, delta);\r
-    }\r
-\r
-    public boolean subnetInUse(String subnetUUID) {\r
-        if (!subnetExists(subnetUUID))\r
-            return true;\r
-        NeutronSubnet target = subnetDB.get(subnetUUID);\r
-        return (target.getPortsInSubnet().size() > 0);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.implementation;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.felix.dm.Component;
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class NeutronSubnetInterface implements INeutronSubnetCRUD {
+    private static final Logger logger = LoggerFactory.getLogger(NeutronSubnetInterface.class);
+    private String containerName = null;
+
+    private IClusterContainerServices clusterContainerService = null;
+    private ConcurrentMap<String, NeutronSubnet> subnetDB;
+
+    // methods needed for creating caches
+
+    void setClusterContainerService(IClusterContainerServices s) {
+        logger.debug("Cluster Service set");
+        this.clusterContainerService = s;
+    }
+
+    void unsetClusterContainerService(IClusterContainerServices s) {
+        if (this.clusterContainerService == s) {
+            logger.debug("Cluster Service removed!");
+            this.clusterContainerService = null;
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    private void allocateCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't create cache");
+            return;
+        }
+        logger.debug("Creating Cache for Neutron Subnets");
+        try {
+            // neutron caches
+            this.clusterContainerService.createCache("neutronSubnets",
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            logger.error("Cache couldn't be created for Neutron Subnets -  check cache mode");
+        } catch (CacheExistException cce) {
+            logger.error("Cache for Neutron Subnets already exists, destroy and recreate");
+        }
+        logger.debug("Cache successfully created for Neutron Subnets");
+    }
+
+    @SuppressWarnings({ "unchecked", "deprecation" })
+    private void retrieveCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterContainerService, can't retrieve cache");
+            return;
+        }
+
+        logger.debug("Retrieving cache for Neutron Subnets");
+        subnetDB = (ConcurrentMap<String, NeutronSubnet>) this.clusterContainerService
+        .getCache("neutronSubnets");
+        if (subnetDB == null) {
+            logger.error("Cache couldn't be retrieved for Neutron Subnets");
+        }
+        logger.debug("Cache was successfully retrieved for Neutron Subnets");
+    }
+
+    @SuppressWarnings("deprecation")
+    private void destroyCache() {
+        if (this.clusterContainerService == null) {
+            logger.error("un-initialized clusterMger, can't destroy cache");
+            return;
+        }
+        logger.debug("Destroying Cache for HostTracker");
+        this.clusterContainerService.destroyCache("neutronSubnets");
+    }
+
+    private void startUp() {
+        allocateCache();
+        retrieveCache();
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    void init(Component c) {
+        Dictionary<?, ?> props = c.getServiceProperties();
+        if (props != null) {
+            this.containerName = (String) props.get("containerName");
+            logger.debug("Running containerName: {}", this.containerName);
+        } else {
+            // In the Global instance case the containerName is empty
+            this.containerName = "";
+        }
+        startUp();
+    }
+
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+        destroyCache();
+    }
+
+    /**
+     * Function called by dependency manager after "init ()" is called and after
+     * the services provided by the class are registered in the service registry
+     *
+     */
+    void start() {
+    }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+    void stop() {
+    }
+
+    // this method uses reflection to update an object from it's delta.
+
+    private boolean overwrite(Object target, Object delta) {
+        Method[] methods = target.getClass().getMethods();
+
+        for(Method toMethod: methods){
+            if(toMethod.getDeclaringClass().equals(target.getClass())
+                    && toMethod.getName().startsWith("set")){
+
+                String toName = toMethod.getName();
+                String fromName = toName.replace("set", "get");
+
+                try {
+                    Method fromMethod = delta.getClass().getMethod(fromName);
+                    Object value = fromMethod.invoke(delta, (Object[])null);
+                    if(value != null){
+                        toMethod.invoke(target, value);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+
+    // IfNBSubnetCRUD methods
+
+    public boolean subnetExists(String uuid) {
+        return subnetDB.containsKey(uuid);
+    }
+
+    public NeutronSubnet getSubnet(String uuid) {
+        if (!subnetExists(uuid))
+            return null;
+        return subnetDB.get(uuid);
+    }
+
+    public List<NeutronSubnet> getAllSubnets() {
+        Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
+        for (Entry<String, NeutronSubnet> entry : subnetDB.entrySet()) {
+            NeutronSubnet subnet = entry.getValue();
+            allSubnets.add(subnet);
+        }
+        logger.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
+        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+        ans.addAll(allSubnets);
+        return ans;
+    }
+
+    public boolean addSubnet(NeutronSubnet input) {
+        String id = input.getID();
+        if (subnetExists(id))
+            return false;
+        subnetDB.putIfAbsent(id, input);
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+        NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());
+        targetNet.addSubnet(id);
+        return true;
+    }
+
+    public boolean removeSubnet(String uuid) {
+        if (!subnetExists(uuid))
+            return false;
+        NeutronSubnet target = subnetDB.get(uuid);
+        INeutronNetworkCRUD networkIf = NeutronCRUDInterfaces.getINeutronNetworkCRUD(this);
+
+        NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());
+        targetNet.removeSubnet(uuid);
+        subnetDB.remove(uuid);
+        return true;
+    }
+
+    public boolean updateSubnet(String uuid, NeutronSubnet delta) {
+        if (!subnetExists(uuid))
+            return false;
+        NeutronSubnet target = subnetDB.get(uuid);
+        return overwrite(target, delta);
+    }
+
+    public boolean subnetInUse(String subnetUUID) {
+        if (!subnetExists(subnetUUID))
+            return true;
+        NeutronSubnet target = subnetDB.get(subnetUUID);
+        return (target.getPortsInSubnet().size() > 0);
+    }
+}
index 05d50be818a8d2a50481d1f7f6e01e3d7dc2c8cf..43175d3236455e1d3f9f4a5df23b3e3e290e9ac0 100644 (file)
@@ -1,83 +1,83 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronFloatingIPAware {\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified floatingIP can be created\r
-     *\r
-     * @param floatingIP\r
-     *            instance of proposed new Neutron FloatingIP object\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the create operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canCreateFloatingIP(NeutronFloatingIP floatingIP);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a floatingIP has been created\r
-     *\r
-     * @param floatingIP\r
-     *            instance of new Neutron FloatingIP object\r
-     * @return void\r
-     */\r
-    public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified\r
-     * delta\r
-     *\r
-     * @param delta\r
-     *            updates to the floatingIP object using patch semantics\r
-     * @param floatingIP\r
-     *            instance of the Neutron FloatingIP object to be updated\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the update operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a floatingIP has been updated\r
-     *\r
-     * @param floatingIP\r
-     *            instance of modified Neutron FloatingIP object\r
-     * @return void\r
-     */\r
-    public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified floatingIP can be deleted\r
-     *\r
-     * @param floatingIP\r
-     *            instance of the Neutron FloatingIP object to be deleted\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the delete operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDeleteFloatingIP(NeutronFloatingIP floatingIP);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a floatingIP has been deleted\r
-     *\r
-     * @param floatingIP\r
-     *            instance of deleted Neutron FloatingIP object\r
-     * @return void\r
-     */\r
-    public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron FloatingIPs needs to implement
+ *
+ */
+
+public interface INeutronFloatingIPAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be created
+     *
+     * @param floatingIP
+     *            instance of proposed new Neutron FloatingIP object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canCreateFloatingIP(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been created
+     *
+     * @param floatingIP
+     *            instance of new Neutron FloatingIP object
+     * @return void
+     */
+    public void neutronFloatingIPCreated(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the floatingIP object using patch semantics
+     * @param floatingIP
+     *            instance of the Neutron FloatingIP object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canUpdateFloatingIP(NeutronFloatingIP delta, NeutronFloatingIP original);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been updated
+     *
+     * @param floatingIP
+     *            instance of modified Neutron FloatingIP object
+     * @return void
+     */
+    public void neutronFloatingIPUpdated(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method to indicate if the specified floatingIP can be deleted
+     *
+     * @param floatingIP
+     *            instance of the Neutron FloatingIP object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDeleteFloatingIP(NeutronFloatingIP floatingIP);
+
+    /**
+     * Services provide this interface method for taking action after a floatingIP has been deleted
+     *
+     * @param floatingIP
+     *            instance of deleted Neutron FloatingIP object
+     * @return void
+     */
+    public void neutronFloatingIPDeleted(NeutronFloatingIP floatingIP);
+}
index 7443deec6e9f97f19906574cd702b157918d3fc6..e416ee7d2f31efb450fc4c6795a687c95eb25591 100644 (file)
@@ -1,83 +1,83 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB FloatingIP objects\r
- *\r
- */\r
-\r
-public interface INeutronFloatingIPCRUD {\r
-    /**\r
-     * Applications call this interface method to determine if a particular\r
-     * FloatingIP object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the FloatingIP object\r
-     * @return boolean\r
-     */\r
-\r
-    public boolean floatingIPExists(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return if a particular\r
-     * FloatingIP object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the FloatingIP object\r
-     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP.OpenStackFloatingIPs}\r
-     *          OpenStack FloatingIP class\r
-     */\r
-\r
-    public NeutronFloatingIP getFloatingIP(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return all FloatingIP objects\r
-     *\r
-     * @return a Set of OpenStackFloatingIPs objects\r
-     */\r
-\r
-    public List<NeutronFloatingIP> getAllFloatingIPs();\r
-\r
-    /**\r
-     * Applications call this interface method to add a FloatingIP object to the\r
-     * concurrent map\r
-     *\r
-     * @param input\r
-     *            OpenStackFloatingIP object\r
-     * @return boolean on whether the object was added or not\r
-     */\r
-\r
-    public boolean addFloatingIP(NeutronFloatingIP input);\r
-\r
-    /**\r
-     * Applications call this interface method to remove a FloatingIP object to the\r
-     * concurrent map\r
-     *\r
-     * @param uuid\r
-     *            identifier for the FloatingIP object\r
-     * @return boolean on whether the object was removed or not\r
-     */\r
-\r
-    public boolean removeFloatingIP(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to edit a FloatingIP object\r
-     *\r
-     * @param uuid\r
-     *            identifier of the FloatingIP object\r
-     * @param delta\r
-     *            OpenStackFloatingIP object containing changes to apply\r
-     * @return boolean on whether the object was updated or not\r
-     */\r
-\r
-    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB FloatingIP objects
+ *
+ */
+
+public interface INeutronFloatingIPCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * FloatingIP object exists
+     *
+     * @param uuid
+     *            UUID of the FloatingIP object
+     * @return boolean
+     */
+
+    public boolean floatingIPExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * FloatingIP object exists
+     *
+     * @param uuid
+     *            UUID of the FloatingIP object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP.OpenStackFloatingIPs}
+     *          OpenStack FloatingIP class
+     */
+
+    public NeutronFloatingIP getFloatingIP(String uuid);
+
+    /**
+     * Applications call this interface method to return all FloatingIP objects
+     *
+     * @return a Set of OpenStackFloatingIPs objects
+     */
+
+    public List<NeutronFloatingIP> getAllFloatingIPs();
+
+    /**
+     * Applications call this interface method to add a FloatingIP object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackFloatingIP object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addFloatingIP(NeutronFloatingIP input);
+
+    /**
+     * Applications call this interface method to remove a FloatingIP object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the FloatingIP object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeFloatingIP(String uuid);
+
+    /**
+     * Applications call this interface method to edit a FloatingIP object
+     *
+     * @param uuid
+     *            identifier of the FloatingIP object
+     * @param delta
+     *            OpenStackFloatingIP object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateFloatingIP(String uuid, NeutronFloatingIP delta);
+}
index dc6df25ab7dd3b4ed801acdc44f3916352389c30..88d3c1dc6e84726842361add116002fd035ebb24 100644 (file)
@@ -1,83 +1,83 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronNetworkAware {\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified network can be created\r
-     *\r
-     * @param network\r
-     *            instance of proposed new Neutron Network object\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the create operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canCreateNetwork(NeutronNetwork network);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a network has been created\r
-     *\r
-     * @param network\r
-     *            instance of new Neutron Network object\r
-     * @return void\r
-     */\r
-    public void neutronNetworkCreated(NeutronNetwork network);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified network can be changed using the specified\r
-     * delta\r
-     *\r
-     * @param delta\r
-     *            updates to the network object using patch semantics\r
-     * @param network\r
-     *            instance of the Neutron Network object to be updated\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the update operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a network has been updated\r
-     *\r
-     * @param network\r
-     *            instance of modified Neutron Network object\r
-     * @return void\r
-     */\r
-    public void neutronNetworkUpdated(NeutronNetwork network);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified network can be deleted\r
-     *\r
-     * @param network\r
-     *            instance of the Neutron Network object to be deleted\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the delete operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDeleteNetwork(NeutronNetwork network);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a network has been deleted\r
-     *\r
-     * @param network\r
-     *            instance of deleted Neutron Network object\r
-     * @return void\r
-     */\r
-    public void neutronNetworkDeleted(NeutronNetwork network);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Networks needs to implement
+ *
+ */
+
+public interface INeutronNetworkAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be created
+     *
+     * @param network
+     *            instance of proposed new Neutron Network object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canCreateNetwork(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method for taking action after a network has been created
+     *
+     * @param network
+     *            instance of new Neutron Network object
+     * @return void
+     */
+    public void neutronNetworkCreated(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the network object using patch semantics
+     * @param network
+     *            instance of the Neutron Network object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original);
+
+    /**
+     * Services provide this interface method for taking action after a network has been updated
+     *
+     * @param network
+     *            instance of modified Neutron Network object
+     * @return void
+     */
+    public void neutronNetworkUpdated(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method to indicate if the specified network can be deleted
+     *
+     * @param network
+     *            instance of the Neutron Network object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDeleteNetwork(NeutronNetwork network);
+
+    /**
+     * Services provide this interface method for taking action after a network has been deleted
+     *
+     * @param network
+     *            instance of deleted Neutron Network object
+     * @return void
+     */
+    public void neutronNetworkDeleted(NeutronNetwork network);
+}
index 248153105c581ede84d083240664b7206694b212..bf900a618f1057c5fbc8babc12635cbec7045d37 100644 (file)
@@ -1,95 +1,95 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB network objects\r
- *\r
- */\r
-\r
-public interface INeutronNetworkCRUD {\r
-    /**\r
-     * Applications call this interface method to determine if a particular\r
-     * Network object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Network object\r
-     * @return boolean\r
-     */\r
-\r
-    public boolean networkExists(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return if a particular\r
-     * Network object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Network object\r
-     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronNetwork.OpenStackNetworks}\r
-     *          OpenStack Network class\r
-     */\r
-\r
-    public NeutronNetwork getNetwork(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return all Network objects\r
-     *\r
-     * @return List of OpenStackNetworks objects\r
-     */\r
-\r
-    public List<NeutronNetwork> getAllNetworks();\r
-\r
-    /**\r
-     * Applications call this interface method to add a Network object to the\r
-     * concurrent map\r
-     *\r
-     * @param input\r
-     *            OpenStackNetwork object\r
-     * @return boolean on whether the object was added or not\r
-     */\r
-\r
-    public boolean addNetwork(NeutronNetwork input);\r
-\r
-    /**\r
-     * Applications call this interface method to remove a Network object to the\r
-     * concurrent map\r
-     *\r
-     * @param uuid\r
-     *            identifier for the network object\r
-     * @return boolean on whether the object was removed or not\r
-     */\r
-\r
-    public boolean removeNetwork(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to edit a Network object\r
-     *\r
-     * @param uuid\r
-     *            identifier of the network object\r
-     * @param delta\r
-     *            OpenStackNetwork object containing changes to apply\r
-     * @return boolean on whether the object was updated or not\r
-     */\r
-\r
-    public boolean updateNetwork(String uuid, NeutronNetwork delta);\r
-\r
-    /**\r
-     * Applications call this interface method to determine if a Network object\r
-     * is use\r
-     *\r
-     * @param netUUID\r
-     *            identifier of the network object\r
-     *\r
-     * @return boolean on whether the network is in use or not\r
-     */\r
-\r
-    public boolean networkInUse(String netUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB network objects
+ *
+ */
+
+public interface INeutronNetworkCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Network object exists
+     *
+     * @param uuid
+     *            UUID of the Network object
+     * @return boolean
+     */
+
+    public boolean networkExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Network object exists
+     *
+     * @param uuid
+     *            UUID of the Network object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronNetwork.OpenStackNetworks}
+     *          OpenStack Network class
+     */
+
+    public NeutronNetwork getNetwork(String uuid);
+
+    /**
+     * Applications call this interface method to return all Network objects
+     *
+     * @return List of OpenStackNetworks objects
+     */
+
+    public List<NeutronNetwork> getAllNetworks();
+
+    /**
+     * Applications call this interface method to add a Network object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackNetwork object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addNetwork(NeutronNetwork input);
+
+    /**
+     * Applications call this interface method to remove a Network object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the network object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeNetwork(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Network object
+     *
+     * @param uuid
+     *            identifier of the network object
+     * @param delta
+     *            OpenStackNetwork object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateNetwork(String uuid, NeutronNetwork delta);
+
+    /**
+     * Applications call this interface method to determine if a Network object
+     * is use
+     *
+     * @param netUUID
+     *            identifier of the network object
+     *
+     * @return boolean on whether the network is in use or not
+     */
+
+    public boolean networkInUse(String netUUID);
+}
index 36ed4ffb39ec12f82bb0cf38e1ab1bb7f813532e..3f40ba3879a84a2b8aa517f0baad66e2cf0c1672 100644 (file)
@@ -1,83 +1,83 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronPortAware {\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified port can be created\r
-     *\r
-     * @param port\r
-     *            instance of proposed new Neutron Port object\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the create operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canCreatePort(NeutronPort port);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a port has been created\r
-     *\r
-     * @param port\r
-     *            instance of new Neutron Port object\r
-     * @return void\r
-     */\r
-    public void neutronPortCreated(NeutronPort port);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified port can be changed using the specified\r
-     * delta\r
-     *\r
-     * @param delta\r
-     *            updates to the port object using patch semantics\r
-     * @param port\r
-     *            instance of the Neutron Port object to be updated\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the update operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canUpdatePort(NeutronPort delta, NeutronPort original);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a port has been updated\r
-     *\r
-     * @param port\r
-     *            instance of modified Neutron Port object\r
-     * @return void\r
-     */\r
-    public void neutronPortUpdated(NeutronPort port);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified port can be deleted\r
-     *\r
-     * @param port\r
-     *            instance of the Neutron Port object to be deleted\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the delete operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDeletePort(NeutronPort port);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a port has been deleted\r
-     *\r
-     * @param port\r
-     *            instance of deleted Port Network object\r
-     * @return void\r
-     */\r
-    public void neutronPortDeleted(NeutronPort port);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Ports needs to implement
+ *
+ */
+
+public interface INeutronPortAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be created
+     *
+     * @param port
+     *            instance of proposed new Neutron Port object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canCreatePort(NeutronPort port);
+
+    /**
+     * Services provide this interface method for taking action after a port has been created
+     *
+     * @param port
+     *            instance of new Neutron Port object
+     * @return void
+     */
+    public void neutronPortCreated(NeutronPort port);
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the port object using patch semantics
+     * @param port
+     *            instance of the Neutron Port object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canUpdatePort(NeutronPort delta, NeutronPort original);
+
+    /**
+     * Services provide this interface method for taking action after a port has been updated
+     *
+     * @param port
+     *            instance of modified Neutron Port object
+     * @return void
+     */
+    public void neutronPortUpdated(NeutronPort port);
+
+    /**
+     * Services provide this interface method to indicate if the specified port can be deleted
+     *
+     * @param port
+     *            instance of the Neutron Port object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDeletePort(NeutronPort port);
+
+    /**
+     * Services provide this interface method for taking action after a port has been deleted
+     *
+     * @param port
+     *            instance of deleted Port Network object
+     * @return void
+     */
+    public void neutronPortDeleted(NeutronPort port);
+}
index 681e9253772d605632eec56b462663e9cbed1198..ce30c6806eea294c57bc637e3fb532377c3b21b4 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Port objects\r
- *\r
- */\r
-\r
-public interface INeutronPortCRUD {\r
-    /**\r
-     * Applications call this interface method to determine if a particular\r
-     * Port object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Port object\r
-     * @return boolean\r
-     */\r
-\r
-    public boolean portExists(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return if a particular\r
-     * Port object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Port object\r
-     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronPort.OpenStackPorts}\r
-     *          OpenStack Port class\r
-     */\r
-\r
-    public NeutronPort getPort(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return all Port objects\r
-     *\r
-     * @return List of OpenStackPorts objects\r
-     */\r
-\r
-    public List<NeutronPort> getAllPorts();\r
-\r
-    /**\r
-     * Applications call this interface method to add a Port object to the\r
-     * concurrent map\r
-     *\r
-     * @param input\r
-     *            OpenStackPort object\r
-     * @return boolean on whether the object was added or not\r
-     */\r
-\r
-    public boolean addPort(NeutronPort input);\r
-\r
-    /**\r
-     * Applications call this interface method to remove a Port object to the\r
-     * concurrent map\r
-     *\r
-     * @param uuid\r
-     *            identifier for the Port object\r
-     * @return boolean on whether the object was removed or not\r
-     */\r
-\r
-    public boolean removePort(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to edit a Port object\r
-     *\r
-     * @param uuid\r
-     *            identifier of the Port object\r
-     * @param delta\r
-     *            OpenStackPort object containing changes to apply\r
-     * @return boolean on whether the object was updated or not\r
-     */\r
-\r
-    public boolean updatePort(String uuid, NeutronPort delta);\r
-\r
-    /**\r
-     * Applications call this interface method to see if a MAC address is in use\r
-     *\r
-     * @param macAddress\r
-     *            mac Address to be tested\r
-     * @return boolean on whether the macAddress is already associated with a\r
-     * port or not\r
-     */\r
-\r
-    public boolean macInUse(String macAddress);\r
-\r
-    /**\r
-     * Applications call this interface method to retrieve the port associated with\r
-     * the gateway address of a subnet\r
-     *\r
-     * @param subnetUUID\r
-     *            identifier of the subnet\r
-     * @return OpenStackPorts object if the port exists and null if it does not\r
-     */\r
-\r
-    public NeutronPort getGatewayPort(String subnetUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Port objects
+ *
+ */
+
+public interface INeutronPortCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Port object exists
+     *
+     * @param uuid
+     *            UUID of the Port object
+     * @return boolean
+     */
+
+    public boolean portExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Port object exists
+     *
+     * @param uuid
+     *            UUID of the Port object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronPort.OpenStackPorts}
+     *          OpenStack Port class
+     */
+
+    public NeutronPort getPort(String uuid);
+
+    /**
+     * Applications call this interface method to return all Port objects
+     *
+     * @return List of OpenStackPorts objects
+     */
+
+    public List<NeutronPort> getAllPorts();
+
+    /**
+     * Applications call this interface method to add a Port object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackPort object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addPort(NeutronPort input);
+
+    /**
+     * Applications call this interface method to remove a Port object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Port object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removePort(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Port object
+     *
+     * @param uuid
+     *            identifier of the Port object
+     * @param delta
+     *            OpenStackPort object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updatePort(String uuid, NeutronPort delta);
+
+    /**
+     * Applications call this interface method to see if a MAC address is in use
+     *
+     * @param macAddress
+     *            mac Address to be tested
+     * @return boolean on whether the macAddress is already associated with a
+     * port or not
+     */
+
+    public boolean macInUse(String macAddress);
+
+    /**
+     * Applications call this interface method to retrieve the port associated with
+     * the gateway address of a subnet
+     *
+     * @param subnetUUID
+     *            identifier of the subnet
+     * @return OpenStackPorts object if the port exists and null if it does not
+     */
+
+    public NeutronPort getGatewayPort(String subnetUUID);
+}
index 040bdd87c4cdfd0fddbe39dae95dd67a4e956f04..3c9e83d490c0e0d561077f42ad3903b1c11e93b9 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronRouterAware {\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified router can be created\r
-     *\r
-     * @param router\r
-     *            instance of proposed new Neutron Router object\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the create operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canCreateRouter(NeutronRouter router);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a router has been created\r
-     *\r
-     * @param router\r
-     *            instance of new Neutron Router object\r
-     * @return void\r
-     */\r
-    public void neutronRouterCreated(NeutronRouter router);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified router can be changed using the specified\r
-     * delta\r
-     *\r
-     * @param delta\r
-     *            updates to the router object using patch semantics\r
-     * @param router\r
-     *            instance of the Neutron Router object to be updated\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the update operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canUpdateRouter(NeutronRouter delta, NeutronRouter original);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a router has been updated\r
-     *\r
-     * @param router\r
-     *            instance of modified Neutron Router object\r
-     * @return void\r
-     */\r
-    public void neutronRouterUpdated(NeutronRouter router);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified router can be deleted\r
-     *\r
-     * @param router\r
-     *            instance of the Neutron Router object to be deleted\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the delete operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDeleteRouter(NeutronRouter router);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a router has been deleted\r
-     *\r
-     * @param router\r
-     *            instance of deleted Router Network object\r
-     * @return void\r
-     */\r
-    public void neutronRouterDeleted(NeutronRouter router);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified interface can be attached to the specified route\r
-     *\r
-     * @param router\r
-     *            instance of the base Neutron Router object\r
-     * @param routerInterface\r
-     *            instance of the NeutronRouter_Interface to be attached to the router\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the attach operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after an interface has been added to a router\r
-     *\r
-     * @param router\r
-     *            instance of the base Neutron Router object\r
-     * @param routerInterface\r
-     *            instance of the NeutronRouter_Interface being attached to the router\r
-     * @return void\r
-     */\r
-    public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified interface can be detached from the specified router\r
-     *\r
-     * @param router\r
-     *            instance of the base Neutron Router object\r
-     * @param routerInterface\r
-     *            instance of the NeutronRouter_Interface to be detached to the router\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the detach operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after an interface has been removed from a router\r
-     *\r
-     * @param router\r
-     *            instance of the base Neutron Router object\r
-     * @param routerInterface\r
-     *            instance of the NeutronRouter_Interface being detached from the router\r
-     * @return void\r
-     */\r
-    public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Routers needs to implement
+ *
+ */
+
+public interface INeutronRouterAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be created
+     *
+     * @param router
+     *            instance of proposed new Neutron Router object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canCreateRouter(NeutronRouter router);
+
+    /**
+     * Services provide this interface method for taking action after a router has been created
+     *
+     * @param router
+     *            instance of new Neutron Router object
+     * @return void
+     */
+    public void neutronRouterCreated(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the router object using patch semantics
+     * @param router
+     *            instance of the Neutron Router object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canUpdateRouter(NeutronRouter delta, NeutronRouter original);
+
+    /**
+     * Services provide this interface method for taking action after a router has been updated
+     *
+     * @param router
+     *            instance of modified Neutron Router object
+     * @return void
+     */
+    public void neutronRouterUpdated(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the specified router can be deleted
+     *
+     * @param router
+     *            instance of the Neutron Router object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDeleteRouter(NeutronRouter router);
+
+    /**
+     * Services provide this interface method for taking action after a router has been deleted
+     *
+     * @param router
+     *            instance of deleted Router Network object
+     * @return void
+     */
+    public void neutronRouterDeleted(NeutronRouter router);
+
+    /**
+     * Services provide this interface method to indicate if the specified interface can be attached to the specified route
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface to be attached to the router
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the attach operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canAttachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method for taking action after an interface has been added to a router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface being attached to the router
+     * @return void
+     */
+    public void neutronRouterInterfaceAttached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method to indicate if the specified interface can be detached from the specified router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface to be detached to the router
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the detach operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDetachInterface(NeutronRouter router, NeutronRouter_Interface routerInterface);
+
+    /**
+     * Services provide this interface method for taking action after an interface has been removed from a router
+     *
+     * @param router
+     *            instance of the base Neutron Router object
+     * @param routerInterface
+     *            instance of the NeutronRouter_Interface being detached from the router
+     * @return void
+     */
+    public void neutronRouterInterfaceDetached(NeutronRouter router, NeutronRouter_Interface routerInterface);
+}
index 19be16d68e3a1cfba9b88f532c5248b5dd624cfb..b1a943fce1946e287271da2984206c84b3942bab 100644 (file)
@@ -1,93 +1,93 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Router objects\r
- *\r
- */\r
-\r
-public interface INeutronRouterCRUD {\r
-    /**\r
-     * Applications call this interface method to determine if a particular\r
-     * Router object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Router object\r
-     * @return boolean\r
-     */\r
-\r
-    public boolean routerExists(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return if a particular\r
-     * Router object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Router object\r
-     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronRouter.OpenStackRouters}\r
-     *          OpenStack Router class\r
-     */\r
-\r
-    public NeutronRouter getRouter(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return all Router objects\r
-     *\r
-     * @return List of OpenStackRouters objects\r
-     */\r
-\r
-    public List<NeutronRouter> getAllRouters();\r
-\r
-    /**\r
-     * Applications call this interface method to add a Router object to the\r
-     * concurrent map\r
-     *\r
-     * @param input\r
-     *            OpenStackRouter object\r
-     * @return boolean on whether the object was added or not\r
-     */\r
-\r
-    public boolean addRouter(NeutronRouter input);\r
-\r
-    /**\r
-     * Applications call this interface method to remove a Router object to the\r
-     * concurrent map\r
-     *\r
-     * @param uuid\r
-     *            identifier for the Router object\r
-     * @return boolean on whether the object was removed or not\r
-     */\r
-\r
-    public boolean removeRouter(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to edit a Router object\r
-     *\r
-     * @param uuid\r
-     *            identifier of the Router object\r
-     * @param delta\r
-     *            OpenStackRouter object containing changes to apply\r
-     * @return boolean on whether the object was updated or not\r
-     */\r
-\r
-    public boolean updateRouter(String uuid, NeutronRouter delta);\r
-\r
-    /**\r
-     * Applications call this interface method to check if a router is in use\r
-     *\r
-     * @param uuid\r
-     *            identifier of the Router object\r
-     * @return boolean on whether the router is in use or not\r
-     */\r
-\r
-    public boolean routerInUse(String routerUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Router objects
+ *
+ */
+
+public interface INeutronRouterCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Router object exists
+     *
+     * @param uuid
+     *            UUID of the Router object
+     * @return boolean
+     */
+
+    public boolean routerExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Router object exists
+     *
+     * @param uuid
+     *            UUID of the Router object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronRouter.OpenStackRouters}
+     *          OpenStack Router class
+     */
+
+    public NeutronRouter getRouter(String uuid);
+
+    /**
+     * Applications call this interface method to return all Router objects
+     *
+     * @return List of OpenStackRouters objects
+     */
+
+    public List<NeutronRouter> getAllRouters();
+
+    /**
+     * Applications call this interface method to add a Router object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackRouter object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addRouter(NeutronRouter input);
+
+    /**
+     * Applications call this interface method to remove a Router object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Router object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeRouter(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Router object
+     *
+     * @param uuid
+     *            identifier of the Router object
+     * @param delta
+     *            OpenStackRouter object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateRouter(String uuid, NeutronRouter delta);
+
+    /**
+     * Applications call this interface method to check if a router is in use
+     *
+     * @param uuid
+     *            identifier of the Router object
+     * @return boolean on whether the router is in use or not
+     */
+
+    public boolean routerInUse(String routerUUID);
+}
index b7bafab04cf58fe6e7032377fe9faec17ad67d8c..fa0707698d6a88208693bfb9233fd523b512c6de 100644 (file)
@@ -1,84 +1,84 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-/**\r
- * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement\r
- *\r
- */\r
-\r
-public interface INeutronSubnetAware {\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified subnet can be created\r
-     *\r
-     * @param subnet\r
-     *            instance of proposed new Neutron Subnet object\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the create operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canCreateSubnet(NeutronSubnet subnet);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a subnet has been created\r
-     *\r
-     * @param subnet\r
-     *            instance of new Neutron Subnet object\r
-     * @return void\r
-     */\r
-    public void neutronSubnetCreated(NeutronSubnet subnet);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified subnet can be changed using the specified\r
-     * delta\r
-     *\r
-     * @param delta\r
-     *            updates to the subnet object using patch semantics\r
-     * @param subnet\r
-     *            instance of the Neutron Subnet object to be updated\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the update operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a subnet has been updated\r
-     *\r
-     * @param subnet\r
-     *            instance of modified Neutron Subnet object\r
-     * @return void\r
-     */\r
-    public void neutronSubnetUpdated(NeutronSubnet subnet);\r
-\r
-    /**\r
-     * Services provide this interface method to indicate if the specified subnet can be deleted\r
-     *\r
-     * @param subnet\r
-     *            instance of the Subnet Router object to be deleted\r
-     * @return integer\r
-     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299\r
-     *            results in the delete operation being interrupted and the returned status value reflected in the\r
-     *            HTTP response.\r
-     */\r
-    public int canDeleteSubnet(NeutronSubnet subnet);\r
-\r
-    /**\r
-     * Services provide this interface method for taking action after a subnet has been deleted\r
-     *\r
-     * @param subnet\r
-     *            instance of deleted Router Subnet object\r
-     * @return void\r
-     */\r
-    public void neutronSubnetDeleted(NeutronSubnet subnet);\r
-\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+/**
+ * This interface defines the methods a service that wishes to be aware of Neutron Subnets needs to implement
+ *
+ */
+
+public interface INeutronSubnetAware {
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be created
+     *
+     * @param subnet
+     *            instance of proposed new Neutron Subnet object
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the create operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canCreateSubnet(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been created
+     *
+     * @param subnet
+     *            instance of new Neutron Subnet object
+     * @return void
+     */
+    public void neutronSubnetCreated(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be changed using the specified
+     * delta
+     *
+     * @param delta
+     *            updates to the subnet object using patch semantics
+     * @param subnet
+     *            instance of the Neutron Subnet object to be updated
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the update operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been updated
+     *
+     * @param subnet
+     *            instance of modified Neutron Subnet object
+     * @return void
+     */
+    public void neutronSubnetUpdated(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method to indicate if the specified subnet can be deleted
+     *
+     * @param subnet
+     *            instance of the Subnet Router object to be deleted
+     * @return integer
+     *            the return value is understood to be a HTTP status code.  A return value outside of 200 through 299
+     *            results in the delete operation being interrupted and the returned status value reflected in the
+     *            HTTP response.
+     */
+    public int canDeleteSubnet(NeutronSubnet subnet);
+
+    /**
+     * Services provide this interface method for taking action after a subnet has been deleted
+     *
+     * @param subnet
+     *            instance of deleted Router Subnet object
+     * @return void
+     */
+    public void neutronSubnetDeleted(NeutronSubnet subnet);
+
+}
index 9c390467e5c49409e2ad3554848a8155ee174041..6f9a6ffb7b54850dce84b900ca08cadd57c00ce4 100644 (file)
@@ -1,95 +1,95 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.List;\r
-\r
-/**\r
- * This interface defines the methods for CRUD of NB Subnet objects\r
- *\r
- */\r
-\r
-public interface INeutronSubnetCRUD {\r
-    /**\r
-     * Applications call this interface method to determine if a particular\r
-     * Subnet object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Subnet object\r
-     * @return boolean\r
-     */\r
-\r
-    public boolean subnetExists(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return if a particular\r
-     * Subnet object exists\r
-     *\r
-     * @param uuid\r
-     *            UUID of the Subnet object\r
-     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSubnet.OpenStackSubnets}\r
-     *          OpenStack Subnet class\r
-     */\r
-\r
-    public NeutronSubnet getSubnet(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to return all Subnet objects\r
-     *\r
-     * @return List of OpenStackSubnets objects\r
-     */\r
-\r
-    public List<NeutronSubnet> getAllSubnets();\r
-\r
-    /**\r
-     * Applications call this interface method to add a Subnet object to the\r
-     * concurrent map\r
-     *\r
-     * @param input\r
-     *            OpenStackSubnet object\r
-     * @return boolean on whether the object was added or not\r
-     */\r
-\r
-    public boolean addSubnet(NeutronSubnet input);\r
-\r
-    /**\r
-     * Applications call this interface method to remove a Subnet object to the\r
-     * concurrent map\r
-     *\r
-     * @param uuid\r
-     *            identifier for the Subnet object\r
-     * @return boolean on whether the object was removed or not\r
-     */\r
-\r
-    public boolean removeSubnet(String uuid);\r
-\r
-    /**\r
-     * Applications call this interface method to edit a Subnet object\r
-     *\r
-     * @param uuid\r
-     *            identifier of the Subnet object\r
-     * @param delta\r
-     *            OpenStackSubnet object containing changes to apply\r
-     * @return boolean on whether the object was updated or not\r
-     */\r
-\r
-    public boolean updateSubnet(String uuid, NeutronSubnet delta);\r
-\r
-    /**\r
-     * Applications call this interface method to determine if a Subnet object\r
-     * is use\r
-     *\r
-     * @param subnetUUID\r
-     *            identifier of the subnet object\r
-     *\r
-     * @return boolean on whether the subnet is in use or not\r
-     */\r
-\r
-    public boolean subnetInUse(String subnetUUID);\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.List;
+
+/**
+ * This interface defines the methods for CRUD of NB Subnet objects
+ *
+ */
+
+public interface INeutronSubnetCRUD {
+    /**
+     * Applications call this interface method to determine if a particular
+     * Subnet object exists
+     *
+     * @param uuid
+     *            UUID of the Subnet object
+     * @return boolean
+     */
+
+    public boolean subnetExists(String uuid);
+
+    /**
+     * Applications call this interface method to return if a particular
+     * Subnet object exists
+     *
+     * @param uuid
+     *            UUID of the Subnet object
+     * @return {@link org.opendaylight.controller.networkconfig.neutron.NeutronSubnet.OpenStackSubnets}
+     *          OpenStack Subnet class
+     */
+
+    public NeutronSubnet getSubnet(String uuid);
+
+    /**
+     * Applications call this interface method to return all Subnet objects
+     *
+     * @return List of OpenStackSubnets objects
+     */
+
+    public List<NeutronSubnet> getAllSubnets();
+
+    /**
+     * Applications call this interface method to add a Subnet object to the
+     * concurrent map
+     *
+     * @param input
+     *            OpenStackSubnet object
+     * @return boolean on whether the object was added or not
+     */
+
+    public boolean addSubnet(NeutronSubnet input);
+
+    /**
+     * Applications call this interface method to remove a Subnet object to the
+     * concurrent map
+     *
+     * @param uuid
+     *            identifier for the Subnet object
+     * @return boolean on whether the object was removed or not
+     */
+
+    public boolean removeSubnet(String uuid);
+
+    /**
+     * Applications call this interface method to edit a Subnet object
+     *
+     * @param uuid
+     *            identifier of the Subnet object
+     * @param delta
+     *            OpenStackSubnet object containing changes to apply
+     * @return boolean on whether the object was updated or not
+     */
+
+    public boolean updateSubnet(String uuid, NeutronSubnet delta);
+
+    /**
+     * Applications call this interface method to determine if a Subnet object
+     * is use
+     *
+     * @param subnetUUID
+     *            identifier of the subnet object
+     *
+     * @return boolean on whether the subnet is in use or not
+     */
+
+    public boolean subnetInUse(String subnetUUID);
+}
index 0becb475b8301d0ad5f57ec1a6d3f084e99a3841..aebecfa93e18884d243cfb58227124a98de6d429 100644 (file)
@@ -1,39 +1,39 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-public class NeutronCRUDInterfaces {\r
-\r
-    public static INeutronNetworkCRUD getINeutronNetworkCRUD(Object o) {\r
-        INeutronNetworkCRUD answer = (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, o);\r
-        return answer;\r
-    }\r
-\r
-    public static INeutronSubnetCRUD getINeutronSubnetCRUD(Object o) {\r
-        INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, o);\r
-        return answer;\r
-    }\r
-\r
-    public static INeutronPortCRUD getINeutronPortCRUD(Object o) {\r
-        INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, o);\r
-        return answer;\r
-    }\r
-\r
-    public static INeutronRouterCRUD getINeutronRouterCRUD(Object o) {\r
-        INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getGlobalInstance(INeutronRouterCRUD.class, o);\r
-        return answer;\r
-    }\r
-\r
-    public static INeutronFloatingIPCRUD getINeutronFloatingIPCRUD(Object o) {\r
-        INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);\r
-        return answer;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+public class NeutronCRUDInterfaces {
+
+    public static INeutronNetworkCRUD getINeutronNetworkCRUD(Object o) {
+        INeutronNetworkCRUD answer = (INeutronNetworkCRUD) ServiceHelper.getGlobalInstance(INeutronNetworkCRUD.class, o);
+        return answer;
+    }
+
+    public static INeutronSubnetCRUD getINeutronSubnetCRUD(Object o) {
+        INeutronSubnetCRUD answer = (INeutronSubnetCRUD) ServiceHelper.getGlobalInstance(INeutronSubnetCRUD.class, o);
+        return answer;
+    }
+
+    public static INeutronPortCRUD getINeutronPortCRUD(Object o) {
+        INeutronPortCRUD answer = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, o);
+        return answer;
+    }
+
+    public static INeutronRouterCRUD getINeutronRouterCRUD(Object o) {
+        INeutronRouterCRUD answer = (INeutronRouterCRUD) ServiceHelper.getGlobalInstance(INeutronRouterCRUD.class, o);
+        return answer;
+    }
+
+    public static INeutronFloatingIPCRUD getINeutronFloatingIPCRUD(Object o) {
+        INeutronFloatingIPCRUD answer = (INeutronFloatingIPCRUD) ServiceHelper.getGlobalInstance(INeutronFloatingIPCRUD.class, o);
+        return answer;
+    }
+}
index 906b4d4e76baef1afe79e47ca8ed37fbbd8beecb..4d029dccf31c642a7fd8ca790570e8764bcbebb2 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronFloatingIP {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement (name="id")\r
-    String floatingIPUUID;\r
-\r
-    @XmlElement (name="floating_network_id")\r
-    String floatingNetworkUUID;\r
-\r
-    @XmlElement (name="port_id")\r
-    String portUUID;\r
-\r
-    @XmlElement (name="fixed_ip_address")\r
-    String fixedIPAddress;\r
-\r
-    @XmlElement (name="floating_ip_address")\r
-    String floatingIPAddress;\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantUUID;\r
-\r
-    public NeutronFloatingIP() {\r
-    }\r
-\r
-    public String getID() { return floatingIPUUID; }\r
-\r
-    public String getFloatingIPUUID() {\r
-        return floatingIPUUID;\r
-    }\r
-\r
-    public void setFloatingIPUUID(String floatingIPUUID) {\r
-        this.floatingIPUUID = floatingIPUUID;\r
-    }\r
-\r
-    public String getFloatingNetworkUUID() {\r
-        return floatingNetworkUUID;\r
-    }\r
-\r
-    public void setFloatingNetworkUUID(String floatingNetworkUUID) {\r
-        this.floatingNetworkUUID = floatingNetworkUUID;\r
-    }\r
-\r
-    public String getPortUUID() {\r
-        return portUUID;\r
-    }\r
-\r
-    public void setPortUUID(String portUUID) {\r
-        this.portUUID = portUUID;\r
-    }\r
-\r
-    public String getFixedIPAddress() {\r
-        return fixedIPAddress;\r
-    }\r
-\r
-    public void setFixedIPAddress(String fixedIPAddress) {\r
-        this.fixedIPAddress = fixedIPAddress;\r
-    }\r
-\r
-    public String getFloatingIPAddress() {\r
-        return floatingIPAddress;\r
-    }\r
-\r
-    public void setFloatingIPAddress(String floatingIPAddress) {\r
-        this.floatingIPAddress = floatingIPAddress;\r
-    }\r
-\r
-    public String getTenantUUID() {\r
-        return tenantUUID;\r
-    }\r
-\r
-    public void setTenantUUID(String tenantUUID) {\r
-        this.tenantUUID = tenantUUID;\r
-    }\r
-\r
-    /**\r
-     * This method copies selected fields from the object and returns them\r
-     * as a new object, suitable for marshaling.\r
-     *\r
-     * @param fields\r
-     *            List of attributes to be extracted\r
-     * @return an OpenStackFloatingIPs object with only the selected fields\r
-     * populated\r
-     */\r
-\r
-    public NeutronFloatingIP extractFields(List<String> fields) {\r
-        NeutronFloatingIP ans = new NeutronFloatingIP();\r
-        Iterator<String> i = fields.iterator();\r
-        while (i.hasNext()) {\r
-            String s = i.next();\r
-            if (s.equals("id"))\r
-                ans.setFloatingIPUUID(this.getFloatingIPUUID());\r
-            if (s.equals("floating_network_id"))\r
-                ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());\r
-            if (s.equals("port_id"))\r
-                ans.setPortUUID(this.getPortUUID());\r
-            if (s.equals("fixed_ip_address"))\r
-                ans.setFixedIPAddress(this.getFixedIPAddress());\r
-            if (s.equals("floating_ip_address"))\r
-                ans.setFloatingIPAddress(this.getFloatingIPAddress());\r
-            if (s.equals("tenant_id"))\r
-                ans.setTenantUUID(this.getTenantUUID());\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    public void initDefaults() {\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronFloatingIP {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name="id")
+    String floatingIPUUID;
+
+    @XmlElement (name="floating_network_id")
+    String floatingNetworkUUID;
+
+    @XmlElement (name="port_id")
+    String portUUID;
+
+    @XmlElement (name="fixed_ip_address")
+    String fixedIPAddress;
+
+    @XmlElement (name="floating_ip_address")
+    String floatingIPAddress;
+
+    @XmlElement (name="tenant_id")
+    String tenantUUID;
+
+    public NeutronFloatingIP() {
+    }
+
+    public String getID() { return floatingIPUUID; }
+
+    public String getFloatingIPUUID() {
+        return floatingIPUUID;
+    }
+
+    public void setFloatingIPUUID(String floatingIPUUID) {
+        this.floatingIPUUID = floatingIPUUID;
+    }
+
+    public String getFloatingNetworkUUID() {
+        return floatingNetworkUUID;
+    }
+
+    public void setFloatingNetworkUUID(String floatingNetworkUUID) {
+        this.floatingNetworkUUID = floatingNetworkUUID;
+    }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public String getFixedIPAddress() {
+        return fixedIPAddress;
+    }
+
+    public void setFixedIPAddress(String fixedIPAddress) {
+        this.fixedIPAddress = fixedIPAddress;
+    }
+
+    public String getFloatingIPAddress() {
+        return floatingIPAddress;
+    }
+
+    public void setFloatingIPAddress(String floatingIPAddress) {
+        this.floatingIPAddress = floatingIPAddress;
+    }
+
+    public String getTenantUUID() {
+        return tenantUUID;
+    }
+
+    public void setTenantUUID(String tenantUUID) {
+        this.tenantUUID = tenantUUID;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackFloatingIPs object with only the selected fields
+     * populated
+     */
+
+    public NeutronFloatingIP extractFields(List<String> fields) {
+        NeutronFloatingIP ans = new NeutronFloatingIP();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setFloatingIPUUID(this.getFloatingIPUUID());
+            }
+            if (s.equals("floating_network_id")) {
+                ans.setFloatingNetworkUUID(this.getFloatingNetworkUUID());
+            }
+            if (s.equals("port_id")) {
+                ans.setPortUUID(this.getPortUUID());
+            }
+            if (s.equals("fixed_ip_address")) {
+                ans.setFixedIPAddress(this.getFixedIPAddress());
+            }
+            if (s.equals("floating_ip_address")) {
+                ans.setFloatingIPAddress(this.getFloatingIPAddress());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantUUID(this.getTenantUUID());
+            }
+        }
+        return ans;
+    }
+
+    public void initDefaults() {
+    }
+}
index eccbbcc3464a24a272d1e4371ee59b273884a5e9..f7f7982947467d11d13615c28f01638b32b8493c 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement(name = "network")\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronNetwork {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement (name="id")\r
-    String networkUUID;              // network UUID\r
-\r
-    @XmlElement (name="name")\r
-    String networkName;              // name\r
-\r
-    @XmlElement (defaultValue="true", name="admin_state_up")\r
-    Boolean adminStateUp;             // admin state up (true/false)\r
-\r
-    @XmlElement (defaultValue="false", name="shared")\r
-    Boolean shared;                   // shared network or not\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantID;                 // tenant for this network\r
-\r
-    @XmlElement (defaultValue="false", namespace="router", name="external")\r
-    Boolean routerExternal;           // network external or not\r
-\r
-    @XmlElement (defaultValue="flat", namespace="provider", name="network_type")\r
-    String providerNetworkType;      // provider network type (flat or vlan)\r
-\r
-    @XmlElement (namespace="provider", name="physical_network")\r
-    String providerPhysicalNetwork;  // provider physical network (name)\r
-\r
-    @XmlElement (namespace="provider", name="segmentation_id")\r
-    String providerSegmentationID;   // provide segmentation ID (vlan ID)\r
-\r
-    @XmlElement (name="status")\r
-    String status;                   // status (read-only)\r
-\r
-    @XmlElement (name="subnets")\r
-    List<String> subnets;            // subnets (read-only)\r
-\r
-    /* This attribute lists the ports associated with an instance\r
-     * which is needed for determining if that instance can be deleted\r
-     */\r
-\r
-    List<NeutronPort> myPorts;\r
-\r
-    public NeutronNetwork() {\r
-        myPorts = new ArrayList<NeutronPort>();\r
-    }\r
-\r
-    public void initDefaults() {\r
-        subnets = new ArrayList<String>();\r
-        if (this.status == null)\r
-            this.status = "ACTIVE";\r
-        if (this.adminStateUp == null)\r
-            this.adminStateUp = true;\r
-        if (this.shared == null)\r
-            this.shared = false;\r
-        if (this.routerExternal == null)\r
-            this.routerExternal = false;\r
-        if (this.providerNetworkType == null)\r
-            this.providerNetworkType = "flat";\r
-    }\r
-\r
-    public String getID() { return networkUUID; }\r
-\r
-    public String getNetworkUUID() {\r
-        return networkUUID;\r
-    }\r
-\r
-    public void setNetworkUUID(String networkUUID) {\r
-        this.networkUUID = networkUUID;\r
-    }\r
-\r
-    public String getNetworkName() {\r
-        return networkName;\r
-    }\r
-\r
-    public void setNetworkName(String networkName) {\r
-        this.networkName = networkName;\r
-    }\r
-\r
-    public boolean isAdminStateUp() {\r
-        return adminStateUp;\r
-    }\r
-\r
-    public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
-    public void setAdminStateUp(boolean newValue) {\r
-        this.adminStateUp = newValue;\r
-    }\r
-\r
-    public boolean isShared() { return shared; }\r
-\r
-    public Boolean getShared() { return shared; }\r
-\r
-    public void setShared(boolean newValue) {\r
-        this.shared = newValue;\r
-    }\r
-\r
-    public String getTenantID() {\r
-        return tenantID;\r
-    }\r
-\r
-    public void setTenantID(String tenantID) {\r
-        this.tenantID = tenantID;\r
-    }\r
-\r
-    public boolean isRouterExternal() { return routerExternal; }\r
-\r
-    public Boolean getRouterExternal() { return routerExternal; }\r
-\r
-    public void setRouterExternal(boolean newValue) {\r
-        this.routerExternal = newValue;\r
-    }\r
-\r
-    public String getProviderNetworkType() {\r
-        return providerNetworkType;\r
-    }\r
-\r
-    public void setProviderNetworkType(String providerNetworkType) {\r
-        this.providerNetworkType = providerNetworkType;\r
-    }\r
-\r
-    public String getProviderPhysicalNetwork() {\r
-        return providerPhysicalNetwork;\r
-    }\r
-\r
-    public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {\r
-        this.providerPhysicalNetwork = providerPhysicalNetwork;\r
-    }\r
-\r
-    public String getProviderSegmentationID() {\r
-        return providerSegmentationID;\r
-    }\r
-\r
-    public void setProviderSegmentationID(String providerSegmentationID) {\r
-        this.providerSegmentationID = providerSegmentationID;\r
-    }\r
-\r
-    public String getStatus() {\r
-        return status;\r
-    }\r
-\r
-    public void setStatus(String status) {\r
-        this.status = status;\r
-    }\r
-\r
-    public List<String> getSubnets() {\r
-        return subnets;\r
-    }\r
-\r
-    public void setSubnets(List<String> subnets) {\r
-        this.subnets = subnets;\r
-    }\r
-\r
-    public void addSubnet(String uuid) {\r
-        this.subnets.add(uuid);\r
-    }\r
-\r
-    public void removeSubnet(String uuid) {\r
-        this.subnets.remove(uuid);\r
-    }\r
-\r
-    public List<NeutronPort> getPortsOnNetwork() {\r
-        return myPorts;\r
-    }\r
-\r
-    public void addPort(NeutronPort port) {\r
-        myPorts.add(port);\r
-    }\r
-\r
-    public void removePort(NeutronPort port) {\r
-        myPorts.remove(port);\r
-    }\r
-\r
-    /**\r
-     * This method copies selected fields from the object and returns them\r
-     * as a new object, suitable for marshaling.\r
-     *\r
-     * @param fields\r
-     *            List of attributes to be extracted\r
-     * @return an OpenStackNetworks object with only the selected fields\r
-     * populated\r
-     */\r
-\r
-    public NeutronNetwork extractFields(List<String> fields) {\r
-        NeutronNetwork ans = new NeutronNetwork();\r
-        Iterator<String> i = fields.iterator();\r
-        while (i.hasNext()) {\r
-            String s = i.next();\r
-            if (s.equals("id"))\r
-                ans.setNetworkUUID(this.getNetworkUUID());\r
-            if (s.equals("name"))\r
-                ans.setNetworkName(this.getNetworkName());\r
-            if (s.equals("admin_state_up"))\r
-                ans.setAdminStateUp(this.adminStateUp);\r
-            if (s.equals("status"))\r
-                ans.setStatus(this.getStatus());\r
-            if (s.equals("subnets")) {\r
-                List<String> subnetList = new ArrayList<String>();\r
-                subnetList.addAll(this.getSubnets());\r
-                ans.setSubnets(subnetList);\r
-            }\r
-            if (s.equals("shared"))\r
-                ans.setShared(this.shared);\r
-            if (s.equals("tenant_id"))\r
-                ans.setTenantID(this.getTenantID());\r
-        }\r
-        return ans;\r
-    }\r
-\r
-}\r
-\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "network")
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronNetwork {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name="id")
+    String networkUUID;              // network UUID
+
+    @XmlElement (name="name")
+    String networkName;              // name
+
+    @XmlElement (defaultValue="true", name="admin_state_up")
+    Boolean adminStateUp;             // admin state up (true/false)
+
+    @XmlElement (defaultValue="false", name="shared")
+    Boolean shared;                   // shared network or not
+
+    @XmlElement (name="tenant_id")
+    String tenantID;                 // tenant for this network
+
+    @XmlElement (defaultValue="false", namespace="router", name="external")
+    Boolean routerExternal;           // network external or not
+
+    @XmlElement (defaultValue="flat", namespace="provider", name="network_type")
+    String providerNetworkType;      // provider network type (flat or vlan)
+
+    @XmlElement (namespace="provider", name="physical_network")
+    String providerPhysicalNetwork;  // provider physical network (name)
+
+    @XmlElement (namespace="provider", name="segmentation_id")
+    String providerSegmentationID;   // provide segmentation ID (vlan ID)
+
+    @XmlElement (name="status")
+    String status;                   // status (read-only)
+
+    @XmlElement (name="subnets")
+    List<String> subnets;            // subnets (read-only)
+
+    /* This attribute lists the ports associated with an instance
+     * which is needed for determining if that instance can be deleted
+     */
+
+    List<NeutronPort> myPorts;
+
+    public NeutronNetwork() {
+        myPorts = new ArrayList<NeutronPort>();
+    }
+
+    public void initDefaults() {
+        subnets = new ArrayList<String>();
+        if (status == null) {
+            status = "ACTIVE";
+        }
+        if (adminStateUp == null) {
+            adminStateUp = true;
+        }
+        if (shared == null) {
+            shared = false;
+        }
+        if (routerExternal == null) {
+            routerExternal = false;
+        }
+        if (providerNetworkType == null) {
+            providerNetworkType = "flat";
+        }
+    }
+
+    public String getID() { return networkUUID; }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getNetworkName() {
+        return networkName;
+    }
+
+    public void setNetworkName(String networkName) {
+        this.networkName = networkName;
+    }
+
+    public boolean isAdminStateUp() {
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(boolean newValue) {
+        adminStateUp = newValue;
+    }
+
+    public boolean isShared() { return shared; }
+
+    public Boolean getShared() { return shared; }
+
+    public void setShared(boolean newValue) {
+        shared = newValue;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public boolean isRouterExternal() { return routerExternal; }
+
+    public Boolean getRouterExternal() { return routerExternal; }
+
+    public void setRouterExternal(boolean newValue) {
+        routerExternal = newValue;
+    }
+
+    public String getProviderNetworkType() {
+        return providerNetworkType;
+    }
+
+    public void setProviderNetworkType(String providerNetworkType) {
+        this.providerNetworkType = providerNetworkType;
+    }
+
+    public String getProviderPhysicalNetwork() {
+        return providerPhysicalNetwork;
+    }
+
+    public void setProviderPhysicalNetwork(String providerPhysicalNetwork) {
+        this.providerPhysicalNetwork = providerPhysicalNetwork;
+    }
+
+    public String getProviderSegmentationID() {
+        return providerSegmentationID;
+    }
+
+    public void setProviderSegmentationID(String providerSegmentationID) {
+        this.providerSegmentationID = providerSegmentationID;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public List<String> getSubnets() {
+        return subnets;
+    }
+
+    public void setSubnets(List<String> subnets) {
+        this.subnets = subnets;
+    }
+
+    public void addSubnet(String uuid) {
+        subnets.add(uuid);
+    }
+
+    public void removeSubnet(String uuid) {
+        subnets.remove(uuid);
+    }
+
+    public List<NeutronPort> getPortsOnNetwork() {
+        return myPorts;
+    }
+
+    public void addPort(NeutronPort port) {
+        myPorts.add(port);
+    }
+
+    public void removePort(NeutronPort port) {
+        myPorts.remove(port);
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackNetworks object with only the selected fields
+     * populated
+     */
+
+    public NeutronNetwork extractFields(List<String> fields) {
+        NeutronNetwork ans = new NeutronNetwork();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setNetworkUUID(this.getNetworkUUID());
+            }
+            if (s.equals("name")) {
+                ans.setNetworkName(this.getNetworkName());
+            }
+            if (s.equals("admin_state_up")) {
+                ans.setAdminStateUp(adminStateUp);
+            }
+            if (s.equals("status")) {
+                ans.setStatus(this.getStatus());
+            }
+            if (s.equals("subnets")) {
+                List<String> subnetList = new ArrayList<String>();
+                subnetList.addAll(this.getSubnets());
+                ans.setSubnets(subnetList);
+            }
+            if (s.equals("shared")) {
+                ans.setShared(shared);
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+        }
+        return ans;
+    }
+
+}
+
index 7f7f712bed65c55ad8ceae7c11538435c29f7fb7..b585554bf873734da16cc9f6b4871174b4f3645d 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronPort {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement (name="id")\r
-    String portUUID;\r
-\r
-    @XmlElement (name="network_id")\r
-    String networkUUID;\r
-\r
-    @XmlElement (name="name")\r
-    String name;\r
-\r
-    @XmlElement (defaultValue="true", name="admin_state_up")\r
-    Boolean adminStateUp;\r
-\r
-    @XmlElement (name="status")\r
-    String status;\r
-\r
-    @XmlElement (name="mac_address")\r
-    String macAddress;\r
-\r
-    @XmlElement (name="fixed_ips")\r
-    List<Neutron_IPs> fixedIPs;\r
-\r
-    @XmlElement (name="device_id")\r
-    String deviceID;\r
-\r
-    @XmlElement (name="device_owner")\r
-    String deviceOwner;\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantID;\r
-\r
-    // TODO: add security groups\r
-    //        @XmlElement (name="security_groups")\r
-    //        List<String> securityGroups;\r
-\r
-    /* this attribute stores the floating IP address assigned to\r
-     * each fixed IP address\r
-     */\r
-\r
-    HashMap<String, NeutronFloatingIP> floatingIPMap;\r
-\r
-    public NeutronPort() {\r
-        floatingIPMap = new HashMap<String, NeutronFloatingIP>();\r
-    }\r
-\r
-    public String getID() { return portUUID; }\r
-\r
-    public String getPortUUID() {\r
-        return portUUID;\r
-    }\r
-\r
-    public void setPortUUID(String portUUID) {\r
-        this.portUUID = portUUID;\r
-    }\r
-\r
-    public String getNetworkUUID() {\r
-        return networkUUID;\r
-    }\r
-\r
-    public void setNetworkUUID(String networkUUID) {\r
-        this.networkUUID = networkUUID;\r
-    }\r
-\r
-    public String getName() {\r
-        return name;\r
-    }\r
-\r
-    public void setName(String name) {\r
-        this.name = name;\r
-    }\r
-\r
-    public boolean isAdminStateUp() {\r
-        if (adminStateUp == null)\r
-            return true;\r
-        return adminStateUp;\r
-    }\r
-\r
-    public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
-    public void setAdminStateUp(Boolean newValue) {\r
-            this.adminStateUp = newValue;\r
-    }\r
-\r
-    public String getStatus() {\r
-        return status;\r
-    }\r
-\r
-    public void setStatus(String status) {\r
-        this.status = status;\r
-    }\r
-\r
-    public String getMacAddress() {\r
-        return macAddress;\r
-    }\r
-\r
-    public void setMacAddress(String macAddress) {\r
-        this.macAddress = macAddress;\r
-    }\r
-\r
-    public List<Neutron_IPs> getFixedIPs() {\r
-        return fixedIPs;\r
-    }\r
-\r
-    public void setFixedIPs(List<Neutron_IPs> fixedIPs) {\r
-        this.fixedIPs = fixedIPs;\r
-    }\r
-\r
-    public String getDeviceID() {\r
-        return deviceID;\r
-    }\r
-\r
-    public void setDeviceID(String deviceID) {\r
-        this.deviceID = deviceID;\r
-    }\r
-\r
-    public String getDeviceOwner() {\r
-        return deviceOwner;\r
-    }\r
-\r
-    public void setDeviceOwner(String deviceOwner) {\r
-        this.deviceOwner = deviceOwner;\r
-    }\r
-\r
-    public String getTenantID() {\r
-        return tenantID;\r
-    }\r
-\r
-    public void setTenantID(String tenantID) {\r
-        this.tenantID = tenantID;\r
-    }\r
-\r
-    public NeutronFloatingIP getFloatingIP(String key) {\r
-        if (!floatingIPMap.containsKey(key))\r
-            return null;\r
-        return floatingIPMap.get(key);\r
-    }\r
-\r
-    public void removeFloatingIP(String key) {\r
-        floatingIPMap.remove(key);\r
-    }\r
-\r
-    public void addFloatingIP(String key, NeutronFloatingIP floatingIP) {\r
-        if (!floatingIPMap.containsKey(key))\r
-            floatingIPMap.put(key, floatingIP);\r
-    }\r
-\r
-    /**\r
-     * This method copies selected fields from the object and returns them\r
-     * as a new object, suitable for marshaling.\r
-     *\r
-     * @param fields\r
-     *            List of attributes to be extracted\r
-     * @return an OpenStackPorts object with only the selected fields\r
-     * populated\r
-     */\r
-\r
-    public NeutronPort extractFields(List<String> fields) {\r
-        NeutronPort ans = new NeutronPort();\r
-        Iterator<String> i = fields.iterator();\r
-        while (i.hasNext()) {\r
-            String s = i.next();\r
-            if (s.equals("id"))\r
-                ans.setPortUUID(this.getPortUUID());\r
-            if (s.equals("network_id"))\r
-                ans.setNetworkUUID(this.getNetworkUUID());\r
-            if (s.equals("name"))\r
-                ans.setName(this.getName());\r
-            if (s.equals("admin_state_up"))\r
-                ans.setAdminStateUp(this.getAdminStateUp());\r
-            if (s.equals("status"))\r
-                ans.setStatus(this.getStatus());\r
-            if (s.equals("mac_address"))\r
-                ans.setMacAddress(this.getMacAddress());\r
-            if (s.equals("fixed_ips")) {\r
-                List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();\r
-                fixedIPs.addAll(this.getFixedIPs());\r
-                ans.setFixedIPs(fixedIPs);\r
-            }\r
-            if (s.equals("device_id")) {\r
-                ans.setDeviceID(this.getDeviceID());\r
-            }\r
-            if (s.equals("device_owner")) {\r
-                ans.setDeviceOwner(this.getDeviceOwner());\r
-            }\r
-            if (s.equals("tenant_id"))\r
-                ans.setTenantID(this.getTenantID());\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    public void initDefaults() {\r
-        adminStateUp = true;\r
-        if (status == null)\r
-            status = "ACTIVE";\r
-        if (fixedIPs == null)\r
-            fixedIPs = new ArrayList<Neutron_IPs>();\r
-    }\r
-\r
-    /**\r
-     * This method checks to see if the port has a floating IPv4 address\r
-     * associated with the supplied fixed IPv4 address\r
-     *\r
-     * @param fixedIP\r
-     *            fixed IPv4 address in dotted decimal format\r
-     * @return a boolean indicating if there is a floating IPv4 address bound\r
-     * to the fixed IPv4 address\r
-     */\r
-\r
-    public boolean isBoundToFloatingIP(String fixedIP) {\r
-        return floatingIPMap.containsKey(fixedIP);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronPort {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name="id")
+    String portUUID;
+
+    @XmlElement (name="network_id")
+    String networkUUID;
+
+    @XmlElement (name="name")
+    String name;
+
+    @XmlElement (defaultValue="true", name="admin_state_up")
+    Boolean adminStateUp;
+
+    @XmlElement (name="status")
+    String status;
+
+    @XmlElement (name="mac_address")
+    String macAddress;
+
+    @XmlElement (name="fixed_ips")
+    List<Neutron_IPs> fixedIPs;
+
+    @XmlElement (name="device_id")
+    String deviceID;
+
+    @XmlElement (name="device_owner")
+    String deviceOwner;
+
+    @XmlElement (name="tenant_id")
+    String tenantID;
+
+    // TODO: add security groups
+    //        @XmlElement (name="security_groups")
+    //        List<String> securityGroups;
+
+    /* this attribute stores the floating IP address assigned to
+     * each fixed IP address
+     */
+
+    HashMap<String, NeutronFloatingIP> floatingIPMap;
+
+    public NeutronPort() {
+        floatingIPMap = new HashMap<String, NeutronFloatingIP>();
+    }
+
+    public String getID() { return portUUID; }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isAdminStateUp() {
+        if (adminStateUp == null) {
+            return true;
+        }
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(Boolean newValue) {
+            adminStateUp = newValue;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getMacAddress() {
+        return macAddress;
+    }
+
+    public void setMacAddress(String macAddress) {
+        this.macAddress = macAddress;
+    }
+
+    public List<Neutron_IPs> getFixedIPs() {
+        return fixedIPs;
+    }
+
+    public void setFixedIPs(List<Neutron_IPs> fixedIPs) {
+        this.fixedIPs = fixedIPs;
+    }
+
+    public String getDeviceID() {
+        return deviceID;
+    }
+
+    public void setDeviceID(String deviceID) {
+        this.deviceID = deviceID;
+    }
+
+    public String getDeviceOwner() {
+        return deviceOwner;
+    }
+
+    public void setDeviceOwner(String deviceOwner) {
+        this.deviceOwner = deviceOwner;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public NeutronFloatingIP getFloatingIP(String key) {
+        if (!floatingIPMap.containsKey(key)) {
+            return null;
+        }
+        return floatingIPMap.get(key);
+    }
+
+    public void removeFloatingIP(String key) {
+        floatingIPMap.remove(key);
+    }
+
+    public void addFloatingIP(String key, NeutronFloatingIP floatingIP) {
+        if (!floatingIPMap.containsKey(key)) {
+            floatingIPMap.put(key, floatingIP);
+        }
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackPorts object with only the selected fields
+     * populated
+     */
+
+    public NeutronPort extractFields(List<String> fields) {
+        NeutronPort ans = new NeutronPort();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setPortUUID(this.getPortUUID());
+            }
+            if (s.equals("network_id")) {
+                ans.setNetworkUUID(this.getNetworkUUID());
+            }
+            if (s.equals("name")) {
+                ans.setName(this.getName());
+            }
+            if (s.equals("admin_state_up")) {
+                ans.setAdminStateUp(this.getAdminStateUp());
+            }
+            if (s.equals("status")) {
+                ans.setStatus(this.getStatus());
+            }
+            if (s.equals("mac_address")) {
+                ans.setMacAddress(this.getMacAddress());
+            }
+            if (s.equals("fixed_ips")) {
+                List<Neutron_IPs> fixedIPs = new ArrayList<Neutron_IPs>();
+                fixedIPs.addAll(this.getFixedIPs());
+                ans.setFixedIPs(fixedIPs);
+            }
+            if (s.equals("device_id")) {
+                ans.setDeviceID(this.getDeviceID());
+            }
+            if (s.equals("device_owner")) {
+                ans.setDeviceOwner(this.getDeviceOwner());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+        }
+        return ans;
+    }
+
+    public void initDefaults() {
+        adminStateUp = true;
+        if (status == null) {
+            status = "ACTIVE";
+        }
+        if (fixedIPs == null) {
+            fixedIPs = new ArrayList<Neutron_IPs>();
+        }
+    }
+
+    /**
+     * This method checks to see if the port has a floating IPv4 address
+     * associated with the supplied fixed IPv4 address
+     *
+     * @param fixedIP
+     *            fixed IPv4 address in dotted decimal format
+     * @return a boolean indicating if there is a floating IPv4 address bound
+     * to the fixed IPv4 address
+     */
+
+    public boolean isBoundToFloatingIP(String fixedIP) {
+        return floatingIPMap.containsKey(fixedIP);
+    }
+}
index 8329ffc58fdaf057d73aceeab4af2bfb5e81faee..1ef48bd95bfe2f4a378f497371f38db11b307e91 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouter {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-    @XmlElement (name="id")\r
-    String routerUUID;\r
-\r
-    @XmlElement (name="name")\r
-    String name;\r
-\r
-    @XmlElement (defaultValue="true", name="admin_state_up")\r
-    Boolean adminStateUp;\r
-\r
-    @XmlElement (name="status")\r
-    String status;\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantID;\r
-\r
-    @XmlElement (name="external_gateway_info")\r
-    NeutronRouter_NetworkReference externalGatewayInfo;\r
-\r
-    /* Holds a map of OpenStackRouterInterfaces by subnet UUID\r
-     * used for internal mapping to DOVE\r
-     */\r
-    HashMap<String, NeutronRouter_Interface> interfaces;\r
-\r
-    public NeutronRouter() {\r
-        interfaces = new HashMap<String, NeutronRouter_Interface>();\r
-    }\r
-\r
-    public String getID() { return routerUUID; }\r
-\r
-    public String getRouterUUID() {\r
-        return routerUUID;\r
-    }\r
-\r
-    public void setRouterUUID(String routerUUID) {\r
-        this.routerUUID = routerUUID;\r
-    }\r
-\r
-    public String getName() {\r
-        return name;\r
-    }\r
-\r
-    public void setName(String name) {\r
-        this.name = name;\r
-    }\r
-\r
-    public boolean isAdminStateUp() {\r
-        if (adminStateUp == null)\r
-            return true;\r
-        return adminStateUp;\r
-    }\r
-\r
-    public Boolean getAdminStateUp() { return adminStateUp; }\r
-\r
-    public void setAdminStateUp(Boolean newValue) {\r
-        this.adminStateUp = newValue;\r
-    }\r
-\r
-    public String getStatus() {\r
-        return status;\r
-    }\r
-\r
-    public void setStatus(String status) {\r
-        this.status = status;\r
-    }\r
-\r
-    public String getTenantID() {\r
-        return tenantID;\r
-    }\r
-\r
-    public void setTenantID(String tenantID) {\r
-        this.tenantID = tenantID;\r
-    }\r
-\r
-    public NeutronRouter_NetworkReference getExternalGatewayInfo() {\r
-        return externalGatewayInfo;\r
-    }\r
-\r
-    public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {\r
-        this.externalGatewayInfo = externalGatewayInfo;\r
-    }\r
-\r
-    /**\r
-     * This method copies selected fields from the object and returns them\r
-     * as a new object, suitable for marshaling.\r
-     *\r
-     * @param fields\r
-     *            List of attributes to be extracted\r
-     * @return an OpenStackRouters object with only the selected fields\r
-     * populated\r
-     */\r
-\r
-    public NeutronRouter extractFields(List<String> fields) {\r
-        NeutronRouter ans = new NeutronRouter();\r
-        Iterator<String> i = fields.iterator();\r
-        while (i.hasNext()) {\r
-            String s = i.next();\r
-            if (s.equals("id"))\r
-                ans.setRouterUUID(this.getRouterUUID());\r
-            if (s.equals("name"))\r
-                ans.setName(this.getName());\r
-            if (s.equals("admin_state_up"))\r
-                ans.setAdminStateUp(this.getAdminStateUp());\r
-            if (s.equals("status"))\r
-                ans.setStatus(this.getStatus());\r
-            if (s.equals("tenant_id"))\r
-                ans.setTenantID(this.getTenantID());\r
-            if (s.equals("external_gateway_info")) {\r
-                ans.setExternalGatewayInfo(this.getExternalGatewayInfo());\r
-            }\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    public HashMap<String, NeutronRouter_Interface> getInterfaces() {\r
-        return interfaces;\r
-    }\r
-\r
-    public void addInterface(String s, NeutronRouter_Interface i) {\r
-        interfaces.put(s, i);\r
-    }\r
-\r
-    public void removeInterface(String s) {\r
-        interfaces.remove(s);\r
-    }\r
-\r
-    public void initDefaults() {\r
-        adminStateUp = true;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+    @XmlElement (name="id")
+    String routerUUID;
+
+    @XmlElement (name="name")
+    String name;
+
+    @XmlElement (defaultValue="true", name="admin_state_up")
+    Boolean adminStateUp;
+
+    @XmlElement (name="status")
+    String status;
+
+    @XmlElement (name="tenant_id")
+    String tenantID;
+
+    @XmlElement (name="external_gateway_info")
+    NeutronRouter_NetworkReference externalGatewayInfo;
+
+    /* Holds a map of OpenStackRouterInterfaces by subnet UUID
+     * used for internal mapping to DOVE
+     */
+    HashMap<String, NeutronRouter_Interface> interfaces;
+
+    public NeutronRouter() {
+        interfaces = new HashMap<String, NeutronRouter_Interface>();
+    }
+
+    public String getID() { return routerUUID; }
+
+    public String getRouterUUID() {
+        return routerUUID;
+    }
+
+    public void setRouterUUID(String routerUUID) {
+        this.routerUUID = routerUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isAdminStateUp() {
+        if (adminStateUp == null) {
+            return true;
+        }
+        return adminStateUp;
+    }
+
+    public Boolean getAdminStateUp() { return adminStateUp; }
+
+    public void setAdminStateUp(Boolean newValue) {
+        adminStateUp = newValue;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    public NeutronRouter_NetworkReference getExternalGatewayInfo() {
+        return externalGatewayInfo;
+    }
+
+    public void setExternalGatewayInfo(NeutronRouter_NetworkReference externalGatewayInfo) {
+        this.externalGatewayInfo = externalGatewayInfo;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackRouters object with only the selected fields
+     * populated
+     */
+
+    public NeutronRouter extractFields(List<String> fields) {
+        NeutronRouter ans = new NeutronRouter();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setRouterUUID(this.getRouterUUID());
+            }
+            if (s.equals("name")) {
+                ans.setName(this.getName());
+            }
+            if (s.equals("admin_state_up")) {
+                ans.setAdminStateUp(this.getAdminStateUp());
+            }
+            if (s.equals("status")) {
+                ans.setStatus(this.getStatus());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+            if (s.equals("external_gateway_info")) {
+                ans.setExternalGatewayInfo(this.getExternalGatewayInfo());
+            }
+        }
+        return ans;
+    }
+
+    public HashMap<String, NeutronRouter_Interface> getInterfaces() {
+        return interfaces;
+    }
+
+    public void addInterface(String s, NeutronRouter_Interface i) {
+        interfaces.put(s, i);
+    }
+
+    public void removeInterface(String s) {
+        interfaces.remove(s);
+    }
+
+    public void initDefaults() {
+        adminStateUp = true;
+    }
+}
index 307789c8cf2433311dd5f435b34527baa01c2900..5b5e0ce9cc61de995360bb0172b14b7f13475676 100644 (file)
@@ -1,65 +1,65 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronRouter_Interface {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement (name="subnet_id")\r
-    String subnetUUID;\r
-\r
-    @XmlElement (name="port_id")\r
-    String portUUID;\r
-\r
-    @XmlElement (name="id")\r
-    String id;\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantID;\r
-\r
-    public NeutronRouter_Interface() {\r
-    }\r
-\r
-    public NeutronRouter_Interface(String subnetUUID, String portUUID) {\r
-        this.subnetUUID = subnetUUID;\r
-        this.portUUID = portUUID;\r
-    }\r
-\r
-    public String getSubnetUUID() {\r
-        return subnetUUID;\r
-    }\r
-\r
-    public void setSubnetUUID(String subnetUUID) {\r
-        this.subnetUUID = subnetUUID;\r
-    }\r
-\r
-    public String getPortUUID() {\r
-        return portUUID;\r
-    }\r
-\r
-    public void setPortUUID(String portUUID) {\r
-        this.portUUID = portUUID;\r
-    }\r
-\r
-    public void setID(String id) {\r
-        this.id = id;\r
-    }\r
-\r
-    public void setTenantID(String tenantID) {\r
-        this.tenantID = tenantID;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronRouter_Interface {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name="subnet_id")
+    String subnetUUID;
+
+    @XmlElement (name="port_id")
+    String portUUID;
+
+    @XmlElement (name="id")
+    String id;
+
+    @XmlElement (name="tenant_id")
+    String tenantID;
+
+    public NeutronRouter_Interface() {
+    }
+
+    public NeutronRouter_Interface(String subnetUUID, String portUUID) {
+        this.subnetUUID = subnetUUID;
+        this.portUUID = portUUID;
+    }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+
+    public String getPortUUID() {
+        return portUUID;
+    }
+
+    public void setPortUUID(String portUUID) {
+        this.portUUID = portUUID;
+    }
+
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+}
index 012215c719342360f9cc2175f0b20b77b85852e4..07f165dc7e16b661c0f9c9e052af89c63c43cf2a 100644 (file)
@@ -1,36 +1,36 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouter_NetworkReference {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="network_id")\r
-    String networkID;\r
-\r
-    public NeutronRouter_NetworkReference() {\r
-    }\r
-\r
-    public String getNetworkID() {\r
-        return networkID;\r
-    }\r
-\r
-    public void setNetworkID(String networkID) {\r
-        this.networkID = networkID;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouter_NetworkReference {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="network_id")
+    String networkID;
+
+    public NeutronRouter_NetworkReference() {
+    }
+
+    public String getNetworkID() {
+        return networkID;
+    }
+
+    public void setNetworkID(String networkID) {
+        this.networkID = networkID;
+    }
+}
index 8b1a8d6af4bb50c13e8b2166bac245fe7d41f0ce..e53c3d4b1a9ddee674c231bdf400f0beed22a162 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.apache.commons.net.util.SubnetUtils;\r
-import org.apache.commons.net.util.SubnetUtils.SubnetInfo;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronSubnet {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement (name="id")\r
-    String subnetUUID;\r
-\r
-    @XmlElement (name="network_id")\r
-    String networkUUID;\r
-\r
-    @XmlElement (name="name")\r
-    String name;\r
-\r
-    @XmlElement (defaultValue="4", name="ip_version")\r
-    Integer ipVersion;\r
-\r
-    @XmlElement (name="cidr")\r
-    String cidr;\r
-\r
-    @XmlElement (name="gateway_ip")\r
-    String gatewayIP;\r
-\r
-    @XmlElement (name="dns_nameservers")\r
-    List<String> dnsNameservers;\r
-\r
-    @XmlElement (name="allocation_pools")\r
-    List<NeutronSubnet_IPAllocationPool> allocationPools;\r
-\r
-    @XmlElement (name="host_routes")\r
-    List<NeutronSubnet_HostRoute> hostRoutes;\r
-\r
-    @XmlElement (defaultValue="true", name="enable_dhcp")\r
-    Boolean enableDHCP;\r
-\r
-    @XmlElement (name="tenant_id")\r
-    String tenantID;\r
-\r
-    /* stores the OpenStackPorts associated with an instance\r
-     * used to determine if that instance can be deleted.\r
-     */\r
-    List<NeutronPort> myPorts;\r
-\r
-    boolean gatewayIPAssigned;\r
-\r
-    public NeutronSubnet() {\r
-        myPorts = new ArrayList<NeutronPort>();\r
-    }\r
-\r
-    public String getID() { return subnetUUID; }\r
-\r
-    public String getSubnetUUID() {\r
-        return subnetUUID;\r
-    }\r
-\r
-    public void setSubnetUUID(String subnetUUID) {\r
-        this.subnetUUID = subnetUUID;\r
-    }\r
-\r
-    public String getNetworkUUID() {\r
-        return networkUUID;\r
-    }\r
-\r
-    public void setNetworkUUID(String networkUUID) {\r
-        this.networkUUID = networkUUID;\r
-    }\r
-\r
-    public String getName() {\r
-        return name;\r
-    }\r
-\r
-    public void setName(String name) {\r
-        this.name = name;\r
-    }\r
-\r
-    public Integer getIpVersion() {\r
-        return ipVersion;\r
-    }\r
-\r
-    public void setIpVersion(Integer ipVersion) {\r
-        this.ipVersion = ipVersion;\r
-    }\r
-\r
-    public String getCidr() {\r
-        return cidr;\r
-    }\r
-\r
-    public void setCidr(String cidr) {\r
-        this.cidr = cidr;\r
-    }\r
-\r
-    public String getGatewayIP() {\r
-        return gatewayIP;\r
-    }\r
-\r
-    public void setGatewayIP(String gatewayIP) {\r
-        this.gatewayIP = gatewayIP;\r
-    }\r
-\r
-    public List<String> getDnsNameservers() {\r
-        return dnsNameservers;\r
-    }\r
-\r
-    public void setDnsNameservers(List<String> dnsNameservers) {\r
-        this.dnsNameservers = dnsNameservers;\r
-    }\r
-\r
-    public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {\r
-        return allocationPools;\r
-    }\r
-\r
-    public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {\r
-        this.allocationPools = allocationPools;\r
-    }\r
-\r
-    public List<NeutronSubnet_HostRoute> getHostRoutes() {\r
-        return hostRoutes;\r
-    }\r
-\r
-    public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {\r
-        this.hostRoutes = hostRoutes;\r
-    }\r
-\r
-    public boolean isEnableDHCP() {\r
-        if (enableDHCP == null) {\r
-            return true;\r
-        }\r
-        return enableDHCP;\r
-    }\r
-\r
-    public Boolean getEnableDHCP() { return enableDHCP; }\r
-\r
-    public void setEnableDHCP(Boolean newValue) {\r
-            enableDHCP = newValue;\r
-    }\r
-\r
-    public String getTenantID() {\r
-        return tenantID;\r
-    }\r
-\r
-    public void setTenantID(String tenantID) {\r
-        this.tenantID = tenantID;\r
-    }\r
-\r
-    /**\r
-     * This method copies selected fields from the object and returns them\r
-     * as a new object, suitable for marshaling.\r
-     *\r
-     * @param fields\r
-     *            List of attributes to be extracted\r
-     * @return an OpenStackSubnets object with only the selected fields\r
-     * populated\r
-     */\r
-\r
-    public NeutronSubnet extractFields(List<String> fields) {\r
-        NeutronSubnet ans = new NeutronSubnet();\r
-        Iterator<String> i = fields.iterator();\r
-        while (i.hasNext()) {\r
-            String s = i.next();\r
-            if (s.equals("id")) {\r
-                ans.setSubnetUUID(this.getSubnetUUID());\r
-            }\r
-            if (s.equals("network_id")) {\r
-                ans.setNetworkUUID(this.getNetworkUUID());\r
-            }\r
-            if (s.equals("name")) {\r
-                ans.setName(this.getName());\r
-            }\r
-            if (s.equals("ip_version")) {\r
-                ans.setIpVersion(this.getIpVersion());\r
-            }\r
-            if (s.equals("cidr")) {\r
-                ans.setCidr(this.getCidr());\r
-            }\r
-            if (s.equals("gateway_ip")) {\r
-                ans.setGatewayIP(this.getGatewayIP());\r
-            }\r
-            if (s.equals("dns_nameservers")) {\r
-                List<String> nsList = new ArrayList<String>();\r
-                nsList.addAll(this.getDnsNameservers());\r
-                ans.setDnsNameservers(nsList);\r
-            }\r
-            if (s.equals("allocation_pools")) {\r
-                List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
-                aPools.addAll(this.getAllocationPools());\r
-                ans.setAllocationPools(aPools);\r
-            }\r
-            if (s.equals("host_routes")) {\r
-                List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
-                hRoutes.addAll(this.getHostRoutes());\r
-                ans.setHostRoutes(hRoutes);\r
-            }\r
-            if (s.equals("enable_dhcp")) {\r
-                ans.setEnableDHCP(this.getEnableDHCP());\r
-            }\r
-            if (s.equals("tenant_id")) {\r
-                ans.setTenantID(this.getTenantID());\r
-            }\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    /* test to see if the cidr address used to define this subnet\r
-     * is a valid network address (an necessary condition when creating\r
-     * a new subnet)\r
-     */\r
-    public boolean isValidCIDR() {\r
-        try {\r
-            SubnetUtils util = new SubnetUtils(cidr);\r
-            SubnetInfo info = util.getInfo();\r
-            if (!info.getNetworkAddress().equals(info.getAddress())) {\r
-                return false;\r
-            }\r
-        } catch (Exception e) {\r
-            return false;\r
-        }\r
-        return true;\r
-    }\r
-\r
-    /* test to see if the gateway IP specified overlaps with specified\r
-     * allocation pools (an error condition when creating a new subnet\r
-     * or assigning a gateway IP)\r
-     */\r
-    public boolean gatewayIP_Pool_overlap() {\r
-        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronSubnet_IPAllocationPool pool = i.next();\r
-            if (pool.contains(gatewayIP)) {\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    public boolean initDefaults() {\r
-        if (enableDHCP == null) {\r
-            enableDHCP = true;\r
-        }\r
-        if (ipVersion == null) {\r
-            ipVersion = 4;\r
-        }\r
-        gatewayIPAssigned = false;\r
-        dnsNameservers = new ArrayList<String>();\r
-        allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
-        hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();\r
-        try {\r
-            SubnetUtils util = new SubnetUtils(cidr);\r
-            SubnetInfo info = util.getInfo();\r
-            if (gatewayIP == null) {\r
-                gatewayIP = info.getLowAddress();\r
-            }\r
-            if (allocationPools.size() < 1) {\r
-                NeutronSubnet_IPAllocationPool source =\r
-                    new NeutronSubnet_IPAllocationPool(info.getLowAddress(),\r
-                            info.getHighAddress());\r
-                allocationPools = source.splitPool(gatewayIP);\r
-            }\r
-        } catch (Exception e) {\r
-            return false;\r
-        }\r
-        return true;\r
-    }\r
-\r
-    public List<NeutronPort> getPortsInSubnet() {\r
-        return myPorts;\r
-    }\r
-\r
-    public void addPort(NeutronPort port) {\r
-        myPorts.add(port);\r
-    }\r
-\r
-    public void removePort(NeutronPort port) {\r
-        myPorts.remove(port);\r
-    }\r
-\r
-    /* this method tests to see if the supplied IPv4 address\r
-     * is valid for this subnet or not\r
-     */\r
-    public boolean isValidIP(String ipAddress) {\r
-        try {\r
-            SubnetUtils util = new SubnetUtils(cidr);\r
-            SubnetInfo info = util.getInfo();\r
-            return info.isInRange(ipAddress);\r
-        } catch (Exception e) {\r
-            return false;\r
-        }\r
-    }\r
-\r
-    /* test to see if the supplied IPv4 address is part of one of the\r
-     * available allocation pools or not\r
-     */\r
-    public boolean isIPInUse(String ipAddress) {\r
-        if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {\r
-            return false;\r
-        }\r
-        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronSubnet_IPAllocationPool pool = i.next();\r
-            if (pool.contains(ipAddress)) {\r
-                return false;\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    /* method to get the lowest available address of the subnet.\r
-     * go through all the allocation pools and keep the lowest of their\r
-     * low addresses.\r
-     */\r
-    public String getLowAddr() {\r
-        String ans = null;\r
-        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronSubnet_IPAllocationPool pool = i.next();\r
-            if (ans == null) {\r
-                ans = pool.getPoolStart();\r
-            }\r
-            else\r
-                if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <\r
-                        NeutronSubnet_IPAllocationPool.convert(ans)) {\r
-                    ans = pool.getPoolStart();\r
-                }\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    /*\r
-     * allocate the parameter address.  Because this uses an iterator to\r
-     * check the instance's list of allocation pools and we want to modify\r
-     * pools while the iterator is being used, it is necessary to\r
-     * build a new list of allocation pools and replace the list when\r
-     * finished (otherwise a split will cause undefined iterator behavior.\r
-     */\r
-    public void allocateIP(String ipAddress) {\r
-        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
-        List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>();    // we have to modify a separate list\r
-        while (i.hasNext()) {\r
-            NeutronSubnet_IPAllocationPool pool = i.next();\r
-            /* if the pool contains a single address element and we are allocating it\r
-             * then we don't need to copy the pool over.  Otherwise, we need to possibly\r
-             * split the pool and add both pieces to the new list\r
-             */\r
-            if (!(pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&\r
-                    pool.getPoolStart().equalsIgnoreCase(ipAddress))) {\r
-                if (pool.contains(ipAddress)) {\r
-                    List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);\r
-                    newList.addAll(pools);\r
-                } else {\r
-                    newList.add(pool);\r
-                }\r
-            }\r
-        }\r
-        allocationPools = newList;\r
-    }\r
-\r
-    /*\r
-     * release an IP address back to the subnet.  Although an iterator\r
-     * is used, the list is not modified until the iterator is complete, so\r
-     * an extra list is not necessary.\r
-     */\r
-    public void releaseIP(String ipAddress) {\r
-        NeutronSubnet_IPAllocationPool lPool = null;\r
-        NeutronSubnet_IPAllocationPool hPool = null;\r
-        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();\r
-        long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
-        //look for lPool where ipAddr - 1 is high address\r
-        //look for hPool where ipAddr + 1 is low address\r
-        while (i.hasNext()) {\r
-            NeutronSubnet_IPAllocationPool pool = i.next();\r
-            long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());\r
-            long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());\r
-            if (sIP+1 == lIP) {\r
-                hPool = pool;\r
-            }\r
-            if (sIP-1 == hIP) {\r
-                lPool = pool;\r
-            }\r
-        }\r
-        //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high\r
-        if (lPool == null && hPool == null) {\r
-            allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));\r
-        }\r
-        //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr\r
-        if (lPool == null && hPool != null) {\r
-            hPool.setPoolStart(ipAddress);\r
-        }\r
-        //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr\r
-        if (lPool != null && hPool == null) {\r
-            lPool.setPoolEnd(ipAddress);\r
-        }\r
-        //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool\r
-        //        where low address = lPool.low address and high address = hPool.high Address\r
-        if (lPool != null && hPool != null) {\r
-            allocationPools.remove(lPool);\r
-            allocationPools.remove(hPool);\r
-            allocationPools.add(new NeutronSubnet_IPAllocationPool(\r
-                    lPool.getPoolStart(), hPool.getPoolEnd()));\r
-        }\r
-    }\r
-\r
-    public void setGatewayIPAllocated() {\r
-        gatewayIPAssigned = true;\r
-    }\r
-\r
-    public void resetGatewayIPAllocated() {\r
-        gatewayIPAssigned = false;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.net.util.SubnetUtils;
+import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnet {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement (name="id")
+    String subnetUUID;
+
+    @XmlElement (name="network_id")
+    String networkUUID;
+
+    @XmlElement (name="name")
+    String name;
+
+    @XmlElement (defaultValue="4", name="ip_version")
+    Integer ipVersion;
+
+    @XmlElement (name="cidr")
+    String cidr;
+
+    @XmlElement (name="gateway_ip")
+    String gatewayIP;
+
+    @XmlElement (name="dns_nameservers")
+    List<String> dnsNameservers;
+
+    @XmlElement (name="allocation_pools")
+    List<NeutronSubnet_IPAllocationPool> allocationPools;
+
+    @XmlElement (name="host_routes")
+    List<NeutronSubnet_HostRoute> hostRoutes;
+
+    @XmlElement (defaultValue="true", name="enable_dhcp")
+    Boolean enableDHCP;
+
+    @XmlElement (name="tenant_id")
+    String tenantID;
+
+    /* stores the OpenStackPorts associated with an instance
+     * used to determine if that instance can be deleted.
+     */
+    List<NeutronPort> myPorts;
+
+    boolean gatewayIPAssigned;
+
+    public NeutronSubnet() {
+        myPorts = new ArrayList<NeutronPort>();
+    }
+
+    public String getID() { return subnetUUID; }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+
+    public String getNetworkUUID() {
+        return networkUUID;
+    }
+
+    public void setNetworkUUID(String networkUUID) {
+        this.networkUUID = networkUUID;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getIpVersion() {
+        return ipVersion;
+    }
+
+    public void setIpVersion(Integer ipVersion) {
+        this.ipVersion = ipVersion;
+    }
+
+    public String getCidr() {
+        return cidr;
+    }
+
+    public void setCidr(String cidr) {
+        this.cidr = cidr;
+    }
+
+    public String getGatewayIP() {
+        return gatewayIP;
+    }
+
+    public void setGatewayIP(String gatewayIP) {
+        this.gatewayIP = gatewayIP;
+    }
+
+    public List<String> getDnsNameservers() {
+        return dnsNameservers;
+    }
+
+    public void setDnsNameservers(List<String> dnsNameservers) {
+        this.dnsNameservers = dnsNameservers;
+    }
+
+    public List<NeutronSubnet_IPAllocationPool> getAllocationPools() {
+        return allocationPools;
+    }
+
+    public void setAllocationPools(List<NeutronSubnet_IPAllocationPool> allocationPools) {
+        this.allocationPools = allocationPools;
+    }
+
+    public List<NeutronSubnet_HostRoute> getHostRoutes() {
+        return hostRoutes;
+    }
+
+    public void setHostRoutes(List<NeutronSubnet_HostRoute> hostRoutes) {
+        this.hostRoutes = hostRoutes;
+    }
+
+    public boolean isEnableDHCP() {
+        if (enableDHCP == null) {
+            return true;
+        }
+        return enableDHCP;
+    }
+
+    public Boolean getEnableDHCP() { return enableDHCP; }
+
+    public void setEnableDHCP(Boolean newValue) {
+            enableDHCP = newValue;
+    }
+
+    public String getTenantID() {
+        return tenantID;
+    }
+
+    public void setTenantID(String tenantID) {
+        this.tenantID = tenantID;
+    }
+
+    /**
+     * This method copies selected fields from the object and returns them
+     * as a new object, suitable for marshaling.
+     *
+     * @param fields
+     *            List of attributes to be extracted
+     * @return an OpenStackSubnets object with only the selected fields
+     * populated
+     */
+
+    public NeutronSubnet extractFields(List<String> fields) {
+        NeutronSubnet ans = new NeutronSubnet();
+        Iterator<String> i = fields.iterator();
+        while (i.hasNext()) {
+            String s = i.next();
+            if (s.equals("id")) {
+                ans.setSubnetUUID(this.getSubnetUUID());
+            }
+            if (s.equals("network_id")) {
+                ans.setNetworkUUID(this.getNetworkUUID());
+            }
+            if (s.equals("name")) {
+                ans.setName(this.getName());
+            }
+            if (s.equals("ip_version")) {
+                ans.setIpVersion(this.getIpVersion());
+            }
+            if (s.equals("cidr")) {
+                ans.setCidr(this.getCidr());
+            }
+            if (s.equals("gateway_ip")) {
+                ans.setGatewayIP(this.getGatewayIP());
+            }
+            if (s.equals("dns_nameservers")) {
+                List<String> nsList = new ArrayList<String>();
+                nsList.addAll(this.getDnsNameservers());
+                ans.setDnsNameservers(nsList);
+            }
+            if (s.equals("allocation_pools")) {
+                List<NeutronSubnet_IPAllocationPool> aPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
+                aPools.addAll(this.getAllocationPools());
+                ans.setAllocationPools(aPools);
+            }
+            if (s.equals("host_routes")) {
+                List<NeutronSubnet_HostRoute> hRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+                hRoutes.addAll(this.getHostRoutes());
+                ans.setHostRoutes(hRoutes);
+            }
+            if (s.equals("enable_dhcp")) {
+                ans.setEnableDHCP(this.getEnableDHCP());
+            }
+            if (s.equals("tenant_id")) {
+                ans.setTenantID(this.getTenantID());
+            }
+        }
+        return ans;
+    }
+
+    /* test to see if the cidr address used to define this subnet
+     * is a valid network address (an necessary condition when creating
+     * a new subnet)
+     */
+    public boolean isValidCIDR() {
+        try {
+            SubnetUtils util = new SubnetUtils(cidr);
+            SubnetInfo info = util.getInfo();
+            if (!info.getNetworkAddress().equals(info.getAddress())) {
+                return false;
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    /* test to see if the gateway IP specified overlaps with specified
+     * allocation pools (an error condition when creating a new subnet
+     * or assigning a gateway IP)
+     */
+    public boolean gatewayIP_Pool_overlap() {
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+        while (i.hasNext()) {
+            NeutronSubnet_IPAllocationPool pool = i.next();
+            if (pool.contains(gatewayIP)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean initDefaults() {
+        if (enableDHCP == null) {
+            enableDHCP = true;
+        }
+        if (ipVersion == null) {
+            ipVersion = 4;
+        }
+        gatewayIPAssigned = false;
+        dnsNameservers = new ArrayList<String>();
+        allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
+        hostRoutes = new ArrayList<NeutronSubnet_HostRoute>();
+        try {
+            SubnetUtils util = new SubnetUtils(cidr);
+            SubnetInfo info = util.getInfo();
+            if (gatewayIP == null) {
+                gatewayIP = info.getLowAddress();
+            }
+            if (allocationPools.size() < 1) {
+                NeutronSubnet_IPAllocationPool source =
+                    new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
+                            info.getHighAddress());
+                allocationPools = source.splitPool(gatewayIP);
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    public List<NeutronPort> getPortsInSubnet() {
+        return myPorts;
+    }
+
+    public void addPort(NeutronPort port) {
+        myPorts.add(port);
+    }
+
+    public void removePort(NeutronPort port) {
+        myPorts.remove(port);
+    }
+
+    /* this method tests to see if the supplied IPv4 address
+     * is valid for this subnet or not
+     */
+    public boolean isValidIP(String ipAddress) {
+        try {
+            SubnetUtils util = new SubnetUtils(cidr);
+            SubnetInfo info = util.getInfo();
+            return info.isInRange(ipAddress);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /* test to see if the supplied IPv4 address is part of one of the
+     * available allocation pools or not
+     */
+    public boolean isIPInUse(String ipAddress) {
+        if (ipAddress.equals(gatewayIP) && !gatewayIPAssigned ) {
+            return false;
+        }
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+        while (i.hasNext()) {
+            NeutronSubnet_IPAllocationPool pool = i.next();
+            if (pool.contains(ipAddress)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* method to get the lowest available address of the subnet.
+     * go through all the allocation pools and keep the lowest of their
+     * low addresses.
+     */
+    public String getLowAddr() {
+        String ans = null;
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+        while (i.hasNext()) {
+            NeutronSubnet_IPAllocationPool pool = i.next();
+            if (ans == null) {
+                ans = pool.getPoolStart();
+            }
+            else
+                if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <
+                        NeutronSubnet_IPAllocationPool.convert(ans)) {
+                    ans = pool.getPoolStart();
+                }
+        }
+        return ans;
+    }
+
+    /*
+     * allocate the parameter address.  Because this uses an iterator to
+     * check the instance's list of allocation pools and we want to modify
+     * pools while the iterator is being used, it is necessary to
+     * build a new list of allocation pools and replace the list when
+     * finished (otherwise a split will cause undefined iterator behavior.
+     */
+    public void allocateIP(String ipAddress) {
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+        List<NeutronSubnet_IPAllocationPool> newList = new ArrayList<NeutronSubnet_IPAllocationPool>();    // we have to modify a separate list
+        while (i.hasNext()) {
+            NeutronSubnet_IPAllocationPool pool = i.next();
+            /* if the pool contains a single address element and we are allocating it
+             * then we don't need to copy the pool over.  Otherwise, we need to possibly
+             * split the pool and add both pieces to the new list
+             */
+            if (!(pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&
+                    pool.getPoolStart().equalsIgnoreCase(ipAddress))) {
+                if (pool.contains(ipAddress)) {
+                    List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);
+                    newList.addAll(pools);
+                } else {
+                    newList.add(pool);
+                }
+            }
+        }
+        allocationPools = newList;
+    }
+
+    /*
+     * release an IP address back to the subnet.  Although an iterator
+     * is used, the list is not modified until the iterator is complete, so
+     * an extra list is not necessary.
+     */
+    public void releaseIP(String ipAddress) {
+        NeutronSubnet_IPAllocationPool lPool = null;
+        NeutronSubnet_IPAllocationPool hPool = null;
+        Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
+        long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
+        //look for lPool where ipAddr - 1 is high address
+        //look for hPool where ipAddr + 1 is low address
+        while (i.hasNext()) {
+            NeutronSubnet_IPAllocationPool pool = i.next();
+            long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());
+            long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());
+            if (sIP+1 == lIP) {
+                hPool = pool;
+            }
+            if (sIP-1 == hIP) {
+                lPool = pool;
+            }
+        }
+        //if (lPool == NULL and hPool == NULL) create new pool where low = ip = high
+        if (lPool == null && hPool == null) {
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(ipAddress,ipAddress));
+        }
+        //if (lPool == NULL and hPool != NULL) change low address of hPool to ipAddr
+        if (lPool == null && hPool != null) {
+            hPool.setPoolStart(ipAddress);
+        }
+        //if (lPool != NULL and hPool == NULL) change high address of lPool to ipAddr
+        if (lPool != null && hPool == null) {
+            lPool.setPoolEnd(ipAddress);
+        }
+        //if (lPool != NULL and hPool != NULL) remove lPool and hPool and create new pool
+        //        where low address = lPool.low address and high address = hPool.high Address
+        if (lPool != null && hPool != null) {
+            allocationPools.remove(lPool);
+            allocationPools.remove(hPool);
+            allocationPools.add(new NeutronSubnet_IPAllocationPool(
+                    lPool.getPoolStart(), hPool.getPoolEnd()));
+        }
+    }
+
+    public void setGatewayIPAllocated() {
+        gatewayIPAssigned = true;
+    }
+
+    public void resetGatewayIPAllocated() {
+        gatewayIPAssigned = false;
+    }
+}
index c1084297ba0528526ba0b3f4b2b07fde529626fd..75238c1ad97956de49a0d77ab1b0f2ac76d255d8 100644 (file)
@@ -1,29 +1,29 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronSubnet_HostRoute {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="destination")\r
-    String destination;\r
-\r
-    @XmlElement(name="nexthop")\r
-    String nextHop;\r
-\r
-    public NeutronSubnet_HostRoute() { }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnet_HostRoute {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="destination")
+    String destination;
+
+    @XmlElement(name="nexthop")
+    String nextHop;
+
+    public NeutronSubnet_HostRoute() { }
+}
index b4bbd11704c5f36f97bfa6ca89541022b93988f0..7829ba2199aac43b5e7ac99c2fa730d656436562 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronSubnet_IPAllocationPool {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="start")\r
-    String poolStart;\r
-\r
-    @XmlElement(name="end")\r
-    String poolEnd;\r
-\r
-    public NeutronSubnet_IPAllocationPool() { }\r
-\r
-    public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {\r
-        poolStart = lowAddress;\r
-        poolEnd = highAddress;\r
-    }\r
-\r
-    public String getPoolStart() {\r
-        return poolStart;\r
-    }\r
-\r
-    public void setPoolStart(String poolStart) {\r
-        this.poolStart = poolStart;\r
-    }\r
-\r
-    public String getPoolEnd() {\r
-        return poolEnd;\r
-    }\r
-\r
-    public void setPoolEnd(String poolEnd) {\r
-        this.poolEnd = poolEnd;\r
-    }\r
-\r
-    /**\r
-     * This method determines if this allocation pool contains the\r
-     * input IPv4 address\r
-     *\r
-     * @param inputString\r
-     *            IPv4 address in dotted decimal format\r
-     * @returns a boolean on whether the pool contains the address or not\r
-     */\r
-\r
-    public boolean contains(String inputString) {\r
-        long inputIP = convert(inputString);\r
-        long startIP = convert(poolStart);\r
-        long endIP = convert(poolEnd);\r
-        return (inputIP >= startIP && inputIP <= endIP);\r
-    }\r
-\r
-    /**\r
-     * This static method converts the supplied IPv4 address to a long\r
-     * integer for comparison\r
-     *\r
-     * @param inputString\r
-     *            IPv4 address in dotted decimal format\r
-     * @returns high-endian representation of the IPv4 address as a long\r
-     */\r
-\r
-    static long convert(String inputString) {\r
-        long ans = 0;\r
-        String[] parts = inputString.split("\\.");\r
-        for (String part: parts) {\r
-            ans <<= 8;\r
-            ans |= Integer.parseInt(part);\r
-        }\r
-        return ans;\r
-    }\r
-\r
-    /**\r
-     * This static method converts the supplied high-ending long back\r
-     * into a dotted decimal representation of an IPv4 address\r
-     *\r
-     * @param l\r
-     *            high-endian representation of the IPv4 address as a long\r
-     * @returns IPv4 address in dotted decimal format\r
-     */\r
-    static String longtoIP(long l) {\r
-        int i;\r
-        String[] parts = new String[4];\r
-        for (i=0; i<4; i++) {\r
-            parts[3-i] = String.valueOf(l & 255);\r
-            l >>= 8;\r
-        }\r
-        return join(parts,".");\r
-    }\r
-\r
-    /*\r
-     * helper routine used by longtoIP\r
-     */\r
-    public static String join(String r[],String d)\r
-    {\r
-        if (r.length == 0) return "";\r
-        StringBuilder sb = new StringBuilder();\r
-        int i;\r
-        for(i=0;i<r.length-1;i++) {\r
-            sb.append(r[i]+d);\r
-        }\r
-        return sb.toString()+r[i];\r
-    }\r
-\r
-    /*\r
-     * This method splits the current instance by removing the supplied\r
-     * parameter.\r
-     *\r
-     * If the parameter is either the low or high address,\r
-     * then that member is adjusted and a list containing just this instance\r
-     * is returned.\r
-     *\r
-     * If the parameter is in the middle of the pool, then\r
-     * create two new instances, one ranging from low to parameter-1\r
-     * the other ranging from parameter+1 to high\r
-     */\r
-    public List<NeutronSubnet_IPAllocationPool> splitPool(String ipAddress) {\r
-        List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();\r
-        long gIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);\r
-        long sIP = NeutronSubnet_IPAllocationPool.convert(poolStart);\r
-        long eIP = NeutronSubnet_IPAllocationPool.convert(poolEnd);\r
-        long i;\r
-        NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();\r
-        boolean poolStarted = false;\r
-        for (i=sIP; i<=eIP; i++) {\r
-            if (i == sIP) {\r
-                if (i != gIP) {\r
-                    p.setPoolStart(poolStart);\r
-                    poolStarted = true;\r
-                }\r
-            }\r
-            if (i == eIP) {\r
-                if (i != gIP) {\r
-                    p.setPoolEnd(poolEnd);\r
-                } else {\r
-                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
-                }\r
-                ans.add(p);\r
-            }\r
-            if (i != sIP && i != eIP) {\r
-                if (i != gIP) {\r
-                    if (!poolStarted) {\r
-                        p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));\r
-                        poolStarted = true;\r
-                    }\r
-                } else {\r
-                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));\r
-                    poolStarted = false;\r
-                    ans.add(p);\r
-                    p = new NeutronSubnet_IPAllocationPool();\r
-                }\r
-            }\r
-        }\r
-        return ans;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronSubnet_IPAllocationPool {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="start")
+    String poolStart;
+
+    @XmlElement(name="end")
+    String poolEnd;
+
+    public NeutronSubnet_IPAllocationPool() { }
+
+    public NeutronSubnet_IPAllocationPool(String lowAddress, String highAddress) {
+        poolStart = lowAddress;
+        poolEnd = highAddress;
+    }
+
+    public String getPoolStart() {
+        return poolStart;
+    }
+
+    public void setPoolStart(String poolStart) {
+        this.poolStart = poolStart;
+    }
+
+    public String getPoolEnd() {
+        return poolEnd;
+    }
+
+    public void setPoolEnd(String poolEnd) {
+        this.poolEnd = poolEnd;
+    }
+
+    /**
+     * This method determines if this allocation pool contains the
+     * input IPv4 address
+     *
+     * @param inputString
+     *            IPv4 address in dotted decimal format
+     * @returns a boolean on whether the pool contains the address or not
+     */
+
+    public boolean contains(String inputString) {
+        long inputIP = convert(inputString);
+        long startIP = convert(poolStart);
+        long endIP = convert(poolEnd);
+        return (inputIP >= startIP && inputIP <= endIP);
+    }
+
+    /**
+     * This static method converts the supplied IPv4 address to a long
+     * integer for comparison
+     *
+     * @param inputString
+     *            IPv4 address in dotted decimal format
+     * @returns high-endian representation of the IPv4 address as a long
+     */
+
+    static long convert(String inputString) {
+        long ans = 0;
+        String[] parts = inputString.split("\\.");
+        for (String part: parts) {
+            ans <<= 8;
+            ans |= Integer.parseInt(part);
+        }
+        return ans;
+    }
+
+    /**
+     * This static method converts the supplied high-ending long back
+     * into a dotted decimal representation of an IPv4 address
+     *
+     * @param l
+     *            high-endian representation of the IPv4 address as a long
+     * @returns IPv4 address in dotted decimal format
+     */
+    static String longtoIP(long l) {
+        int i;
+        String[] parts = new String[4];
+        for (i=0; i<4; i++) {
+            parts[3-i] = String.valueOf(l & 255);
+            l >>= 8;
+        }
+        return join(parts,".");
+    }
+
+    /*
+     * helper routine used by longtoIP
+     */
+    public static String join(String r[],String d)
+    {
+        if (r.length == 0) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder();
+        int i;
+        for(i=0;i<r.length-1;i++) {
+            sb.append(r[i]+d);
+        }
+        return sb.toString()+r[i];
+    }
+
+    /*
+     * This method splits the current instance by removing the supplied
+     * parameter.
+     *
+     * If the parameter is either the low or high address,
+     * then that member is adjusted and a list containing just this instance
+     * is returned.
+     *
+     * If the parameter is in the middle of the pool, then
+     * create two new instances, one ranging from low to parameter-1
+     * the other ranging from parameter+1 to high
+     */
+    public List<NeutronSubnet_IPAllocationPool> splitPool(String ipAddress) {
+        List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();
+        long gIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
+        long sIP = NeutronSubnet_IPAllocationPool.convert(poolStart);
+        long eIP = NeutronSubnet_IPAllocationPool.convert(poolEnd);
+        long i;
+        NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();
+        boolean poolStarted = false;
+        for (i=sIP; i<=eIP; i++) {
+            if (i == sIP) {
+                if (i != gIP) {
+                    p.setPoolStart(poolStart);
+                    poolStarted = true;
+                }
+            }
+            if (i == eIP) {
+                if (i != gIP) {
+                    p.setPoolEnd(poolEnd);
+                } else {
+                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+                }
+                ans.add(p);
+            }
+            if (i != sIP && i != eIP) {
+                if (i != gIP) {
+                    if (!poolStarted) {
+                        p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));
+                        poolStarted = true;
+                    }
+                } else {
+                    p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+                    poolStarted = false;
+                    ans.add(p);
+                    p = new NeutronSubnet_IPAllocationPool();
+                }
+            }
+        }
+        return ans;
+    }
+}
index 73094793996aa393055bb8c3a7cf0aaf23c4a8c6..6fe7c529942f1cf524320b923282d3b0b60315cc 100644 (file)
@@ -1,49 +1,49 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class Neutron_IPs {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="ip_address")\r
-    String ipAddress;\r
-\r
-    @XmlElement(name="subnet_id")\r
-    String subnetUUID;\r
-\r
-    public Neutron_IPs() { }\r
-\r
-    public Neutron_IPs(String uuid) {\r
-        this.subnetUUID = uuid;\r
-    }\r
-\r
-    public String getIpAddress() {\r
-        return ipAddress;\r
-    }\r
-\r
-    public void setIpAddress(String ipAddress) {\r
-        this.ipAddress = ipAddress;\r
-    }\r
-\r
-    public String getSubnetUUID() {\r
-        return subnetUUID;\r
-    }\r
-\r
-    public void setSubnetUUID(String subnetUUID) {\r
-        this.subnetUUID = subnetUUID;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class Neutron_IPs {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="ip_address")
+    String ipAddress;
+
+    @XmlElement(name="subnet_id")
+    String subnetUUID;
+
+    public Neutron_IPs() { }
+
+    public Neutron_IPs(String uuid) {
+        subnetUUID = uuid;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public String getSubnetUUID() {
+        return subnetUUID;
+    }
+
+    public void setSubnetUUID(String subnetUUID) {
+        this.subnetUUID = subnetUUID;
+    }
+}
index 7bec2722bf96fd1e9b3b645203aa67c8a6b4f36c..602de9a1c6f28f8e195ed0aa00c78bd82f3da434 100644 (file)
@@ -310,7 +310,7 @@ public class NorthboundIT {
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
         JSONArray subnetConfigs = json.getJSONArray("subnetConfig");
-        Assert.assertEquals(subnetConfigs.length(), 0);
+        Assert.assertEquals(subnetConfigs.length(), 1); // should only get the default subnet
 
         // Test GET subnet1 expecting 404
         result = getJsonResult(baseURL + "default/subnet/" + name1);
index ca1389c724d90c36f8a23476daae064f24a998d5..efb86e0542e9b9fcec607b55bdc8fb9742cbf8bb 100644 (file)
@@ -1,52 +1,52 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronFloatingIPRequest {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="floatingip")\r
-    NeutronFloatingIP singletonFloatingIP;\r
-\r
-    @XmlElement(name="floatingips")\r
-    List<NeutronFloatingIP> bulkRequest;\r
-\r
-    NeutronFloatingIPRequest() {\r
-    }\r
-\r
-    NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {\r
-        bulkRequest = bulk;\r
-        singletonFloatingIP = null;\r
-    }\r
-\r
-    NeutronFloatingIPRequest(NeutronFloatingIP singleton) {\r
-        bulkRequest = null;\r
-        singletonFloatingIP = singleton;\r
-    }\r
-\r
-    public NeutronFloatingIP getSingleton() {\r
-        return singletonFloatingIP;\r
-    }\r
-\r
-    public boolean isSingleton() {\r
-        return (singletonFloatingIP != null);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronFloatingIPRequest {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="floatingip")
+    NeutronFloatingIP singletonFloatingIP;
+
+    @XmlElement(name="floatingips")
+    List<NeutronFloatingIP> bulkRequest;
+
+    NeutronFloatingIPRequest() {
+    }
+
+    NeutronFloatingIPRequest(List<NeutronFloatingIP> bulk) {
+        bulkRequest = bulk;
+        singletonFloatingIP = null;
+    }
+
+    NeutronFloatingIPRequest(NeutronFloatingIP singleton) {
+        bulkRequest = null;
+        singletonFloatingIP = singleton;
+    }
+
+    public NeutronFloatingIP getSingleton() {
+        return singletonFloatingIP;
+    }
+
+    public boolean isSingleton() {
+        return (singletonFloatingIP != null);
+    }
+}
index 2b0ad45629967ac7061d8961ff54c16155a17543..680b028f9adf6f4de276188745cbeb6ceb4092b9 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/floatingips")\r
-public class NeutronFloatingIPsNorthbound {\r
-\r
-    private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {\r
-        return o.extractFields(fields);\r
-    }\r
-\r
-    /**\r
-     * Returns a list of all FloatingIPs */\r
-\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response listFloatingIPs(\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields,\r
-            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
-            @QueryParam("id") String queryID,\r
-            @QueryParam("floating_network_id") String queryFloatingNetworkId,\r
-            @QueryParam("port_id") String queryPortId,\r
-            @QueryParam("fixed_ip_address") String queryFixedIPAddress,\r
-            @QueryParam("floating_ip_address") String queryFloatingIPAddress,\r
-            @QueryParam("tenant_id") String queryTenantID,\r
-            // pagination\r
-            @QueryParam("limit") String limit,\r
-            @QueryParam("marker") String marker,\r
-            @QueryParam("page_reverse") String pageReverse\r
-            // sorting not supported\r
-            ) {\r
-        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
-        if (floatingIPInterface == null) {\r
-            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();\r
-        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();\r
-        Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronFloatingIP oSS = i.next();\r
-            //match filters: TODO provider extension and router extension\r
-            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
-                    (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&\r
-                    (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&\r
-                    (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&\r
-                    (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&\r
-                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {\r
-                if (fields.size() > 0)\r
-                    ans.add(extractFields(oSS,fields));\r
-                else\r
-                    ans.add(oSS);\r
-            }\r
-        }\r
-        //TODO: apply pagination to results\r
-        return Response.status(200).entity(\r
-                new NeutronFloatingIPRequest(ans)).build();\r
-    }\r
-\r
-    /**\r
-     * Returns a specific FloatingIP */\r
-\r
-    @Path("{floatingipUUID}")\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response showFloatingIP(\r
-            @PathParam("floatingipUUID") String floatingipUUID,\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields ) {\r
-        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
-        if (floatingIPInterface == null) {\r
-            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
-            return Response.status(404).build();\r
-        if (fields.size() > 0) {\r
-            NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);\r
-            return Response.status(200).entity(\r
-                    new NeutronFloatingIPRequest(extractFields(ans, fields))).build();\r
-        } else\r
-            return Response.status(200).entity(\r
-                    new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();\r
-\r
-    }\r
-\r
-    /**\r
-     * Creates new FloatingIPs */\r
-\r
-    @POST\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    @StatusCodes({\r
-        @ResponseCode(code = 201, condition = "Created"),\r
-        @ResponseCode(code = 400, condition = "Bad Request"),\r
-        @ResponseCode(code = 401, condition = "Unauthorized"),\r
-        @ResponseCode(code = 409, condition = "Conflict"),\r
-        @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response createFloatingIPs(final NeutronFloatingIPRequest input) {\r
-        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
-        if (floatingIPInterface == null) {\r
-            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (input.isSingleton()) {\r
-            NeutronFloatingIP singleton = input.getSingleton();\r
-            // check existence of id in cache and return badrequest if exists\r
-            if (floatingIPInterface.floatingIPExists(singleton.getID()))\r
-                return Response.status(400).build();\r
-            // check if the external network is specified, exists, and is an external network\r
-            String externalNetworkUUID = singleton.getFloatingNetworkUUID();\r
-            if (externalNetworkUUID == null)\r
-                return Response.status(400).build();\r
-            if (!networkInterface.networkExists(externalNetworkUUID))\r
-                return Response.status(400).build();\r
-            NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);\r
-            if (!externNetwork.isRouterExternal())\r
-                return Response.status(400).build();\r
-            // if floating IP is specified, make sure it can come from the network\r
-            String floatingIP = singleton.getFloatingIPAddress();\r
-            if (floatingIP != null) {\r
-                if (externNetwork.getSubnets().size() > 1)\r
-                    return Response.status(400).build();\r
-                NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
-                if (!externSubnet.isValidIP(floatingIP))\r
-                    return Response.status(400).build();\r
-                if (externSubnet.isIPInUse(floatingIP))\r
-                    return Response.status(409).build();\r
-            }\r
-            // if port_id is specified, then check that the port exists and has at least one IP\r
-            String port_id = singleton.getPortUUID();\r
-            if (port_id != null) {\r
-                String fixedIP = null;        // used for the fixedIP calculation\r
-                if (!portInterface.portExists(port_id))\r
-                    return Response.status(404).build();\r
-                NeutronPort port = portInterface.getPort(port_id);\r
-                if (port.getFixedIPs().size() < 1)\r
-                    return Response.status(400).build();\r
-                // if there is more than one fixed IP then check for fixed_ip_address\r
-                // and that it is in the list of port addresses\r
-                if (port.getFixedIPs().size() > 1) {\r
-                    fixedIP = singleton.getFixedIPAddress();\r
-                    if (fixedIP == null)\r
-                        return Response.status(400).build();\r
-                    Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
-                    boolean validFixedIP = false;\r
-                    while (i.hasNext() && !validFixedIP) {\r
-                        Neutron_IPs ip = i.next();\r
-                        if (ip.getIpAddress().equals(fixedIP))\r
-                            validFixedIP = true;\r
-                    }\r
-                    if (!validFixedIP)\r
-                        return Response.status(400).build();\r
-                } else {\r
-                    fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
-                    if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
-                        return Response.status(400).build();\r
-                }\r
-                //lastly check that this fixed IP address isn't already used\r
-                if (port.isBoundToFloatingIP(fixedIP))\r
-                    return Response.status(409).build();\r
-                singleton.setFixedIPAddress(fixedIP);\r
-            }\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                    int status = service.canCreateFloatingIP(singleton);\r
-                    if (status < 200 || status > 299)\r
-                        return Response.status(status).build();\r
-                }\r
-            }\r
-            floatingIPInterface.addFloatingIP(singleton);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                    service.neutronFloatingIPCreated(singleton);\r
-                }\r
-            }\r
-        } else {\r
-            return Response.status(400).build();\r
-        }\r
-        return Response.status(201).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Updates a FloatingIP */\r
-\r
-    @Path("{floatingipUUID}")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response updateFloatingIP(\r
-            @PathParam("floatingipUUID") String floatingipUUID,\r
-            NeutronFloatingIPRequest input\r
-            ) {\r
-        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
-        if (floatingIPInterface == null) {\r
-            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
-            return Response.status(404).build();\r
-\r
-        NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);\r
-        if (!input.isSingleton())\r
-            return Response.status(400).build();\r
-        NeutronFloatingIP singleton = input.getSingleton();\r
-        if (singleton.getID() != null)\r
-            return Response.status(400).build();\r
-\r
-        NeutronNetwork externNetwork = networkInterface.getNetwork(\r
-                sourceFloatingIP.getFloatingNetworkUUID());\r
-\r
-        // if floating IP is specified, make sure it can come from the network\r
-        String floatingIP = singleton.getFloatingIPAddress();\r
-        if (floatingIP != null) {\r
-            if (externNetwork.getSubnets().size() > 1)\r
-                return Response.status(400).build();\r
-            NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));\r
-            if (!externSubnet.isValidIP(floatingIP))\r
-                return Response.status(400).build();\r
-            if (externSubnet.isIPInUse(floatingIP))\r
-                return Response.status(409).build();\r
-        }\r
-\r
-        // if port_id is specified, then check that the port exists and has at least one IP\r
-        String port_id = singleton.getPortUUID();\r
-        if (port_id != null) {\r
-            String fixedIP = null;        // used for the fixedIP calculation\r
-            if (!portInterface.portExists(port_id))\r
-                return Response.status(404).build();\r
-            NeutronPort port = portInterface.getPort(port_id);\r
-            if (port.getFixedIPs().size() < 1)\r
-                return Response.status(400).build();\r
-            // if there is more than one fixed IP then check for fixed_ip_address\r
-            // and that it is in the list of port addresses\r
-            if (port.getFixedIPs().size() > 1) {\r
-                fixedIP = singleton.getFixedIPAddress();\r
-                if (fixedIP == null)\r
-                    return Response.status(400).build();\r
-                Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();\r
-                boolean validFixedIP = false;\r
-                while (i.hasNext() && !validFixedIP) {\r
-                    Neutron_IPs ip = i.next();\r
-                    if (ip.getIpAddress().equals(fixedIP))\r
-                        validFixedIP = true;\r
-                }\r
-                if (!validFixedIP)\r
-                    return Response.status(400).build();\r
-            } else {\r
-                fixedIP = port.getFixedIPs().get(0).getIpAddress();\r
-                if (singleton.getFixedIPAddress() != null &&\r
-                        !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))\r
-                    return Response.status(400).build();\r
-            }\r
-            //lastly check that this fixed IP address isn't already used\r
-            if (port.isBoundToFloatingIP(fixedIP))\r
-                return Response.status(409).build();\r
-            singleton.setFixedIPAddress(fixedIP);\r
-        }\r
-        NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                int status = service.canUpdateFloatingIP(singleton, target);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);\r
-        target = floatingIPInterface.getFloatingIP(floatingipUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                service.neutronFloatingIPUpdated(target);\r
-            }\r
-        }\r
-        return Response.status(200).entity(\r
-                new NeutronFloatingIPRequest(target)).build();\r
-\r
-    }\r
-\r
-    /**\r
-     * Deletes a FloatingIP */\r
-\r
-    @Path("{floatingipUUID}")\r
-    @DELETE\r
-    @StatusCodes({\r
-            @ResponseCode(code = 204, condition = "No Content"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response deleteFloatingIP(\r
-            @PathParam("floatingipUUID") String floatingipUUID) {\r
-        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);\r
-        if (floatingIPInterface == null) {\r
-            throw new ServiceUnavailableException("Floating IP CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!floatingIPInterface.floatingIPExists(floatingipUUID))\r
-            return Response.status(404).build();\r
-        // TODO: need to undo port association if it exists\r
-        NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                int status = service.canDeleteFloatingIP(singleton);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        floatingIPInterface.removeFloatingIP(floatingipUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;\r
-                service.neutronFloatingIPDeleted(singleton);\r
-            }\r
-        }\r
-        return Response.status(204).build();\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronFloatingIPCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronFloatingIP;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/floatingips")
+public class NeutronFloatingIPsNorthbound {
+
+    private NeutronFloatingIP extractFields(NeutronFloatingIP o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all FloatingIPs */
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response listFloatingIPs(
+            // return fields
+            @QueryParam("fields") List<String> fields,
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them
+            @QueryParam("id") String queryID,
+            @QueryParam("floating_network_id") String queryFloatingNetworkId,
+            @QueryParam("port_id") String queryPortId,
+            @QueryParam("fixed_ip_address") String queryFixedIPAddress,
+            @QueryParam("floating_ip_address") String queryFloatingIPAddress,
+            @QueryParam("tenant_id") String queryTenantID,
+            // pagination
+            @QueryParam("limit") String limit,
+            @QueryParam("marker") String marker,
+            @QueryParam("page_reverse") String pageReverse
+            // sorting not supported
+            ) {
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+        if (floatingIPInterface == null) {
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronFloatingIP> allFloatingIPs = floatingIPInterface.getAllFloatingIPs();
+        List<NeutronFloatingIP> ans = new ArrayList<NeutronFloatingIP>();
+        Iterator<NeutronFloatingIP> i = allFloatingIPs.iterator();
+        while (i.hasNext()) {
+            NeutronFloatingIP oSS = i.next();
+            //match filters: TODO provider extension and router extension
+            if ((queryID == null || queryID.equals(oSS.getID())) &&
+                    (queryFloatingNetworkId == null || queryFloatingNetworkId.equals(oSS.getFloatingNetworkUUID())) &&
+                    (queryPortId == null || queryPortId.equals(oSS.getPortUUID())) &&
+                    (queryFixedIPAddress == null || queryFixedIPAddress.equals(oSS.getFixedIPAddress())) &&
+                    (queryFloatingIPAddress == null || queryFloatingIPAddress.equals(oSS.getFloatingIPAddress())) &&
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantUUID()))) {
+                if (fields.size() > 0)
+                    ans.add(extractFields(oSS,fields));
+                else
+                    ans.add(oSS);
+            }
+        }
+        //TODO: apply pagination to results
+        return Response.status(200).entity(
+                new NeutronFloatingIPRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific FloatingIP */
+
+    @Path("{floatingipUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response showFloatingIP(
+            @PathParam("floatingipUUID") String floatingipUUID,
+            // return fields
+            @QueryParam("fields") List<String> fields ) {
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+        if (floatingIPInterface == null) {
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+            return Response.status(404).build();
+        if (fields.size() > 0) {
+            NeutronFloatingIP ans = floatingIPInterface.getFloatingIP(floatingipUUID);
+            return Response.status(200).entity(
+                    new NeutronFloatingIPRequest(extractFields(ans, fields))).build();
+        } else
+            return Response.status(200).entity(
+                    new NeutronFloatingIPRequest(floatingIPInterface.getFloatingIP(floatingipUUID))).build();
+
+    }
+
+    /**
+     * Creates new FloatingIPs */
+
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+        @ResponseCode(code = 201, condition = "Created"),
+        @ResponseCode(code = 400, condition = "Bad Request"),
+        @ResponseCode(code = 401, condition = "Unauthorized"),
+        @ResponseCode(code = 409, condition = "Conflict"),
+        @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response createFloatingIPs(final NeutronFloatingIPRequest input) {
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+        if (floatingIPInterface == null) {
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (input.isSingleton()) {
+            NeutronFloatingIP singleton = input.getSingleton();
+            // check existence of id in cache and return badrequest if exists
+            if (floatingIPInterface.floatingIPExists(singleton.getID()))
+                return Response.status(400).build();
+            // check if the external network is specified, exists, and is an external network
+            String externalNetworkUUID = singleton.getFloatingNetworkUUID();
+            if (externalNetworkUUID == null)
+                return Response.status(400).build();
+            if (!networkInterface.networkExists(externalNetworkUUID))
+                return Response.status(400).build();
+            NeutronNetwork externNetwork = networkInterface.getNetwork(externalNetworkUUID);
+            if (!externNetwork.isRouterExternal())
+                return Response.status(400).build();
+            // if floating IP is specified, make sure it can come from the network
+            String floatingIP = singleton.getFloatingIPAddress();
+            if (floatingIP != null) {
+                if (externNetwork.getSubnets().size() > 1)
+                    return Response.status(400).build();
+                NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+                if (!externSubnet.isValidIP(floatingIP))
+                    return Response.status(400).build();
+                if (externSubnet.isIPInUse(floatingIP))
+                    return Response.status(409).build();
+            }
+            // if port_id is specified, then check that the port exists and has at least one IP
+            String port_id = singleton.getPortUUID();
+            if (port_id != null) {
+                String fixedIP = null;        // used for the fixedIP calculation
+                if (!portInterface.portExists(port_id))
+                    return Response.status(404).build();
+                NeutronPort port = portInterface.getPort(port_id);
+                if (port.getFixedIPs().size() < 1)
+                    return Response.status(400).build();
+                // if there is more than one fixed IP then check for fixed_ip_address
+                // and that it is in the list of port addresses
+                if (port.getFixedIPs().size() > 1) {
+                    fixedIP = singleton.getFixedIPAddress();
+                    if (fixedIP == null)
+                        return Response.status(400).build();
+                    Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+                    boolean validFixedIP = false;
+                    while (i.hasNext() && !validFixedIP) {
+                        Neutron_IPs ip = i.next();
+                        if (ip.getIpAddress().equals(fixedIP))
+                            validFixedIP = true;
+                    }
+                    if (!validFixedIP)
+                        return Response.status(400).build();
+                } else {
+                    fixedIP = port.getFixedIPs().get(0).getIpAddress();
+                    if (singleton.getFixedIPAddress() != null && !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+                        return Response.status(400).build();
+                }
+                //lastly check that this fixed IP address isn't already used
+                if (port.isBoundToFloatingIP(fixedIP))
+                    return Response.status(409).build();
+                singleton.setFixedIPAddress(fixedIP);
+            }
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                    int status = service.canCreateFloatingIP(singleton);
+                    if (status < 200 || status > 299)
+                        return Response.status(status).build();
+                }
+            }
+            floatingIPInterface.addFloatingIP(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                    service.neutronFloatingIPCreated(singleton);
+                }
+            }
+        } else {
+            return Response.status(400).build();
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a FloatingIP */
+
+    @Path("{floatingipUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response updateFloatingIP(
+            @PathParam("floatingipUUID") String floatingipUUID,
+            NeutronFloatingIPRequest input
+            ) {
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+        if (floatingIPInterface == null) {
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD( this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+            return Response.status(404).build();
+
+        NeutronFloatingIP sourceFloatingIP = floatingIPInterface.getFloatingIP(floatingipUUID);
+        if (!input.isSingleton())
+            return Response.status(400).build();
+        NeutronFloatingIP singleton = input.getSingleton();
+        if (singleton.getID() != null)
+            return Response.status(400).build();
+
+        NeutronNetwork externNetwork = networkInterface.getNetwork(
+                sourceFloatingIP.getFloatingNetworkUUID());
+
+        // if floating IP is specified, make sure it can come from the network
+        String floatingIP = singleton.getFloatingIPAddress();
+        if (floatingIP != null) {
+            if (externNetwork.getSubnets().size() > 1)
+                return Response.status(400).build();
+            NeutronSubnet externSubnet = subnetInterface.getSubnet(externNetwork.getSubnets().get(0));
+            if (!externSubnet.isValidIP(floatingIP))
+                return Response.status(400).build();
+            if (externSubnet.isIPInUse(floatingIP))
+                return Response.status(409).build();
+        }
+
+        // if port_id is specified, then check that the port exists and has at least one IP
+        String port_id = singleton.getPortUUID();
+        if (port_id != null) {
+            String fixedIP = null;        // used for the fixedIP calculation
+            if (!portInterface.portExists(port_id))
+                return Response.status(404).build();
+            NeutronPort port = portInterface.getPort(port_id);
+            if (port.getFixedIPs().size() < 1)
+                return Response.status(400).build();
+            // if there is more than one fixed IP then check for fixed_ip_address
+            // and that it is in the list of port addresses
+            if (port.getFixedIPs().size() > 1) {
+                fixedIP = singleton.getFixedIPAddress();
+                if (fixedIP == null)
+                    return Response.status(400).build();
+                Iterator<Neutron_IPs> i = port.getFixedIPs().iterator();
+                boolean validFixedIP = false;
+                while (i.hasNext() && !validFixedIP) {
+                    Neutron_IPs ip = i.next();
+                    if (ip.getIpAddress().equals(fixedIP))
+                        validFixedIP = true;
+                }
+                if (!validFixedIP)
+                    return Response.status(400).build();
+            } else {
+                fixedIP = port.getFixedIPs().get(0).getIpAddress();
+                if (singleton.getFixedIPAddress() != null &&
+                        !fixedIP.equalsIgnoreCase(singleton.getFixedIPAddress()))
+                    return Response.status(400).build();
+            }
+            //lastly check that this fixed IP address isn't already used
+            if (port.isBoundToFloatingIP(fixedIP))
+                return Response.status(409).build();
+            singleton.setFixedIPAddress(fixedIP);
+        }
+        NeutronFloatingIP target = floatingIPInterface.getFloatingIP(floatingipUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                int status = service.canUpdateFloatingIP(singleton, target);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        floatingIPInterface.updateFloatingIP(floatingipUUID, singleton);
+        target = floatingIPInterface.getFloatingIP(floatingipUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                service.neutronFloatingIPUpdated(target);
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronFloatingIPRequest(target)).build();
+
+    }
+
+    /**
+     * Deletes a FloatingIP */
+
+    @Path("{floatingipUUID}")
+    @DELETE
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "No Content"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response deleteFloatingIP(
+            @PathParam("floatingipUUID") String floatingipUUID) {
+        INeutronFloatingIPCRUD floatingIPInterface = NeutronCRUDInterfaces.getINeutronFloatingIPCRUD(this);
+        if (floatingIPInterface == null) {
+            throw new ServiceUnavailableException("Floating IP CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!floatingIPInterface.floatingIPExists(floatingipUUID))
+            return Response.status(404).build();
+        // TODO: need to undo port association if it exists
+        NeutronFloatingIP singleton = floatingIPInterface.getFloatingIP(floatingipUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronFloatingIPAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                int status = service.canDeleteFloatingIP(singleton);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        floatingIPInterface.removeFloatingIP(floatingipUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronFloatingIPAware service = (INeutronFloatingIPAware) instance;
+                service.neutronFloatingIPDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
index 9d449380a5743548bdfb39a240655ada7fd8a59b..cebd3c267dd1a1ad2d3b345f2f97d498046631b0 100644 (file)
@@ -1,55 +1,55 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronNetworkRequest {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="network")\r
-    NeutronNetwork singletonNetwork;\r
-\r
-    @XmlElement(name="networks")\r
-    List<NeutronNetwork> bulkRequest;\r
-\r
-    NeutronNetworkRequest() {\r
-    }\r
-\r
-    NeutronNetworkRequest(List<NeutronNetwork> bulk) {\r
-        bulkRequest = bulk;\r
-        singletonNetwork = null;\r
-    }\r
-\r
-    NeutronNetworkRequest(NeutronNetwork net) {\r
-        singletonNetwork = net;\r
-    }\r
-\r
-    public NeutronNetwork getSingleton() {\r
-        return singletonNetwork;\r
-    }\r
-\r
-    public boolean isSingleton() {\r
-        return (singletonNetwork != null);\r
-    }\r
-\r
-    public List<NeutronNetwork> getBulk() {\r
-        return bulkRequest;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronNetworkRequest {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="network")
+    NeutronNetwork singletonNetwork;
+
+    @XmlElement(name="networks")
+    List<NeutronNetwork> bulkRequest;
+
+    NeutronNetworkRequest() {
+    }
+
+    NeutronNetworkRequest(List<NeutronNetwork> bulk) {
+        bulkRequest = bulk;
+        singletonNetwork = null;
+    }
+
+    NeutronNetworkRequest(NeutronNetwork net) {
+        singletonNetwork = net;
+    }
+
+    public NeutronNetwork getSingleton() {
+        return singletonNetwork;
+    }
+
+    public boolean isSingleton() {
+        return (singletonNetwork != null);
+    }
+
+    public List<NeutronNetwork> getBulk() {
+        return bulkRequest;
+    }
+}
index 383009b9d519366d9ffd3efe17783ad0be7624ad..e8690aa889aee1d449601a3156757d298de9dd72 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.codehaus.enunciate.jaxrs.TypeHint;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs for Network.<br>\r
- * This class provides REST APIs for managing open DOVE internals related to Networks\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/networks")\r
-public class NeutronNetworksNorthbound {\r
-\r
-    private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {\r
-        return o.extractFields(fields);\r
-    }\r
-\r
-    /**\r
-     * Returns a list of all Networks */\r
-\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackNetworks.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized") })\r
-    public Response listNetworks(\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields,\r
-            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
-            @QueryParam("id") String queryID,\r
-            @QueryParam("name") String queryName,\r
-            @QueryParam("admin_state_up") String queryAdminStateUp,\r
-            @QueryParam("status") String queryStatus,\r
-            @QueryParam("shared") String queryShared,\r
-            @QueryParam("tenant_id") String queryTenantID,\r
-            @QueryParam("router_external") String queryRouterExternal,\r
-            @QueryParam("provider_network_type") String queryProviderNetworkType,\r
-            @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,\r
-            @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,\r
-            // pagination\r
-            @QueryParam("limit") String limit,\r
-            @QueryParam("marker") String marker,\r
-            @QueryParam("page_reverse") String pageReverse\r
-            // sorting not supported\r
-        ) {\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();\r
-        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();\r
-        Iterator<NeutronNetwork> i = allNetworks.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronNetwork oSN = i.next();\r
-            //match filters: TODO provider extension\r
-            Boolean bAdminStateUp = null;\r
-            Boolean bShared = null;\r
-            Boolean bRouterExternal = null;\r
-            if (queryAdminStateUp != null)\r
-                bAdminStateUp = Boolean.valueOf(queryAdminStateUp);\r
-            if (queryShared != null)\r
-                bShared = Boolean.valueOf(queryShared);\r
-            if (queryRouterExternal != null)\r
-                bRouterExternal = Boolean.valueOf(queryRouterExternal);\r
-            if ((queryID == null || queryID.equals(oSN.getID())) &&\r
-                    (queryName == null || queryName.equals(oSN.getNetworkName())) &&\r
-                    (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&\r
-                    (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&\r
-                    (bShared == null || bShared.booleanValue() == oSN.isShared()) &&\r
-                    (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&\r
-                    (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {\r
-                if (fields.size() > 0)\r
-                    ans.add(extractFields(oSN,fields));\r
-                else\r
-                    ans.add(oSN);\r
-            }\r
-        }\r
-        //TODO: apply pagination to results\r
-        return Response.status(200).entity(\r
-                new NeutronNetworkRequest(ans)).build();\r
-    }\r
-\r
-    /**\r
-     * Returns a specific Network */\r
-\r
-    @Path("{netUUID}")\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackNetworks.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found") })\r
-    public Response showNetwork(\r
-            @PathParam("netUUID") String netUUID,\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields\r
-            ) {\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!networkInterface.networkExists(netUUID))\r
-            return Response.status(404).build();\r
-        if (fields.size() > 0) {\r
-            NeutronNetwork ans = networkInterface.getNetwork(netUUID);\r
-            return Response.status(200).entity(\r
-                    new NeutronNetworkRequest(extractFields(ans, fields))).build();\r
-        } else\r
-            return Response.status(200).entity(\r
-                    new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
-    }\r
-\r
-    /**\r
-     * Creates new Networks */\r
-    @POST\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    @TypeHint(NeutronNetwork.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 201, condition = "Created"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized") })\r
-    public Response createNetworks(final NeutronNetworkRequest input) {\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (input.isSingleton()) {\r
-            NeutronNetwork singleton = input.getSingleton();\r
-\r
-            /*\r
-             * network ID can't already exist\r
-             */\r
-            if (networkInterface.networkExists(singleton.getID()))\r
-                return Response.status(400).build();\r
-\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                    int status = service.canCreateNetwork(singleton);\r
-                    if (status < 200 || status > 299)\r
-                        return Response.status(status).build();\r
-                }\r
-            }\r
-\r
-            // add network to cache\r
-            networkInterface.addNetwork(singleton);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                    service.neutronNetworkCreated(singleton);\r
-                }\r
-            }\r
-\r
-        } else {\r
-            List<NeutronNetwork> bulk = input.getBulk();\r
-            Iterator<NeutronNetwork> i = bulk.iterator();\r
-            HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
-            while (i.hasNext()) {\r
-                NeutronNetwork test = i.next();\r
-\r
-                /*\r
-                 * network ID can't already exist, nor can there be an entry for this UUID\r
-                 * already in this bulk request\r
-                 */\r
-                if (networkInterface.networkExists(test.getID()))\r
-                    return Response.status(400).build();\r
-                if (testMap.containsKey(test.getID()))\r
-                    return Response.status(400).build();\r
-                if (instances != null) {\r
-                    for (Object instance: instances) {\r
-                        INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                        int status = service.canCreateNetwork(test);\r
-                        if (status < 200 || status > 299)\r
-                            return Response.status(status).build();\r
-                    }\r
-                }\r
-                testMap.put(test.getID(),test);\r
-            }\r
-\r
-            // now that everything passed, add items to the cache\r
-            i = bulk.iterator();\r
-            while (i.hasNext()) {\r
-                NeutronNetwork test = i.next();\r
-                test.initDefaults();\r
-                networkInterface.addNetwork(test);\r
-                if (instances != null) {\r
-                    for (Object instance: instances) {\r
-                        INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                        service.neutronNetworkCreated(test);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return Response.status(201).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Updates a Network */\r
-    @Path("{netUUID}")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackNetworks.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"), })\r
-    public Response updateNetwork(\r
-            @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input\r
-            ) {\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * network has to exist and only a single delta is supported\r
-         */\r
-        if (!networkInterface.networkExists(netUUID))\r
-            return Response.status(404).build();\r
-        if (!input.isSingleton())\r
-            return Response.status(400).build();\r
-        NeutronNetwork delta = input.getSingleton();\r
-\r
-        /*\r
-         * transitions forbidden by Neutron\r
-         */\r
-        if (delta.getID() != null || delta.getTenantID() != null ||\r
-                delta.getStatus() != null)\r
-            return Response.status(400).build();\r
-\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                NeutronNetwork original = networkInterface.getNetwork(netUUID);\r
-                int status = service.canUpdateNetwork(delta, original);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-\r
-        // update network object and return the modified object\r
-        networkInterface.updateNetwork(netUUID, delta);\r
-        NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                service.neutronNetworkUpdated(updatedSingleton);\r
-            }\r
-        }\r
-        return Response.status(200).entity(\r
-                new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();\r
-    }\r
-\r
-    /**\r
-     * Deletes a Network */\r
-\r
-    @Path("{netUUID}")\r
-    @DELETE\r
-    @StatusCodes({\r
-            @ResponseCode(code = 204, condition = "No Content"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Network In Use") })\r
-    public Response deleteNetwork(\r
-            @PathParam("netUUID") String netUUID) {\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * network has to exist and not be in use before it can be removed\r
-         */\r
-        if (!networkInterface.networkExists(netUUID))\r
-            return Response.status(404).build();\r
-        if (networkInterface.networkInUse(netUUID))\r
-            return Response.status(409).build();\r
-\r
-        NeutronNetwork singleton = networkInterface.getNetwork(netUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                int status = service.canDeleteNetwork(singleton);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        networkInterface.removeNetwork(netUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronNetworkAware service = (INeutronNetworkAware) instance;\r
-                service.neutronNetworkDeleted(singleton);\r
-            }\r
-        }\r
-        return Response.status(204).build();\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.codehaus.enunciate.jaxrs.TypeHint;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs for Network.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Networks
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/networks")
+public class NeutronNetworksNorthbound {
+
+    private NeutronNetwork extractFields(NeutronNetwork o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all Networks */
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackNetworks.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized") })
+    public Response listNetworks(
+            // return fields
+            @QueryParam("fields") List<String> fields,
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them
+            @QueryParam("id") String queryID,
+            @QueryParam("name") String queryName,
+            @QueryParam("admin_state_up") String queryAdminStateUp,
+            @QueryParam("status") String queryStatus,
+            @QueryParam("shared") String queryShared,
+            @QueryParam("tenant_id") String queryTenantID,
+            @QueryParam("router_external") String queryRouterExternal,
+            @QueryParam("provider_network_type") String queryProviderNetworkType,
+            @QueryParam("provider_physical_network") String queryProviderPhysicalNetwork,
+            @QueryParam("provider_segmentation_id") String queryProviderSegmentationID,
+            // pagination
+            @QueryParam("limit") String limit,
+            @QueryParam("marker") String marker,
+            @QueryParam("page_reverse") String pageReverse
+            // sorting not supported
+        ) {
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronNetwork> allNetworks = networkInterface.getAllNetworks();
+        List<NeutronNetwork> ans = new ArrayList<NeutronNetwork>();
+        Iterator<NeutronNetwork> i = allNetworks.iterator();
+        while (i.hasNext()) {
+            NeutronNetwork oSN = i.next();
+            //match filters: TODO provider extension
+            Boolean bAdminStateUp = null;
+            Boolean bShared = null;
+            Boolean bRouterExternal = null;
+            if (queryAdminStateUp != null)
+                bAdminStateUp = Boolean.valueOf(queryAdminStateUp);
+            if (queryShared != null)
+                bShared = Boolean.valueOf(queryShared);
+            if (queryRouterExternal != null)
+                bRouterExternal = Boolean.valueOf(queryRouterExternal);
+            if ((queryID == null || queryID.equals(oSN.getID())) &&
+                    (queryName == null || queryName.equals(oSN.getNetworkName())) &&
+                    (bAdminStateUp == null || bAdminStateUp.booleanValue() == oSN.isAdminStateUp()) &&
+                    (queryStatus == null || queryStatus.equals(oSN.getStatus())) &&
+                    (bShared == null || bShared.booleanValue() == oSN.isShared()) &&
+                    (bRouterExternal == null || bRouterExternal.booleanValue() == oSN.isRouterExternal()) &&
+                    (queryTenantID == null || queryTenantID.equals(oSN.getTenantID()))) {
+                if (fields.size() > 0)
+                    ans.add(extractFields(oSN,fields));
+                else
+                    ans.add(oSN);
+            }
+        }
+        //TODO: apply pagination to results
+        return Response.status(200).entity(
+                new NeutronNetworkRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Network */
+
+    @Path("{netUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackNetworks.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found") })
+    public Response showNetwork(
+            @PathParam("netUUID") String netUUID,
+            // return fields
+            @QueryParam("fields") List<String> fields
+            ) {
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!networkInterface.networkExists(netUUID))
+            return Response.status(404).build();
+        if (fields.size() > 0) {
+            NeutronNetwork ans = networkInterface.getNetwork(netUUID);
+            return Response.status(200).entity(
+                    new NeutronNetworkRequest(extractFields(ans, fields))).build();
+        } else
+            return Response.status(200).entity(
+                    new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+    }
+
+    /**
+     * Creates new Networks */
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @TypeHint(NeutronNetwork.class)
+    @StatusCodes({
+            @ResponseCode(code = 201, condition = "Created"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized") })
+    public Response createNetworks(final NeutronNetworkRequest input) {
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (input.isSingleton()) {
+            NeutronNetwork singleton = input.getSingleton();
+
+            /*
+             * network ID can't already exist
+             */
+            if (networkInterface.networkExists(singleton.getID()))
+                return Response.status(400).build();
+
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                    int status = service.canCreateNetwork(singleton);
+                    if (status < 200 || status > 299)
+                        return Response.status(status).build();
+                }
+            }
+
+            // add network to cache
+            networkInterface.addNetwork(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                    service.neutronNetworkCreated(singleton);
+                }
+            }
+
+        } else {
+            List<NeutronNetwork> bulk = input.getBulk();
+            Iterator<NeutronNetwork> i = bulk.iterator();
+            HashMap<String, NeutronNetwork> testMap = new HashMap<String, NeutronNetwork>();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+            while (i.hasNext()) {
+                NeutronNetwork test = i.next();
+
+                /*
+                 * network ID can't already exist, nor can there be an entry for this UUID
+                 * already in this bulk request
+                 */
+                if (networkInterface.networkExists(test.getID()))
+                    return Response.status(400).build();
+                if (testMap.containsKey(test.getID()))
+                    return Response.status(400).build();
+                if (instances != null) {
+                    for (Object instance: instances) {
+                        INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                        int status = service.canCreateNetwork(test);
+                        if (status < 200 || status > 299)
+                            return Response.status(status).build();
+                    }
+                }
+                testMap.put(test.getID(),test);
+            }
+
+            // now that everything passed, add items to the cache
+            i = bulk.iterator();
+            while (i.hasNext()) {
+                NeutronNetwork test = i.next();
+                test.initDefaults();
+                networkInterface.addNetwork(test);
+                if (instances != null) {
+                    for (Object instance: instances) {
+                        INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                        service.neutronNetworkCreated(test);
+                    }
+                }
+            }
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Network */
+    @Path("{netUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackNetworks.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"), })
+    public Response updateNetwork(
+            @PathParam("netUUID") String netUUID, final NeutronNetworkRequest input
+            ) {
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * network has to exist and only a single delta is supported
+         */
+        if (!networkInterface.networkExists(netUUID))
+            return Response.status(404).build();
+        if (!input.isSingleton())
+            return Response.status(400).build();
+        NeutronNetwork delta = input.getSingleton();
+
+        /*
+         * transitions forbidden by Neutron
+         */
+        if (delta.getID() != null || delta.getTenantID() != null ||
+                delta.getStatus() != null)
+            return Response.status(400).build();
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                NeutronNetwork original = networkInterface.getNetwork(netUUID);
+                int status = service.canUpdateNetwork(delta, original);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+
+        // update network object and return the modified object
+        networkInterface.updateNetwork(netUUID, delta);
+        NeutronNetwork updatedSingleton = networkInterface.getNetwork(netUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                service.neutronNetworkUpdated(updatedSingleton);
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronNetworkRequest(networkInterface.getNetwork(netUUID))).build();
+    }
+
+    /**
+     * Deletes a Network */
+
+    @Path("{netUUID}")
+    @DELETE
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "No Content"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Network In Use") })
+    public Response deleteNetwork(
+            @PathParam("netUUID") String netUUID) {
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * network has to exist and not be in use before it can be removed
+         */
+        if (!networkInterface.networkExists(netUUID))
+            return Response.status(404).build();
+        if (networkInterface.networkInUse(netUUID))
+            return Response.status(409).build();
+
+        NeutronNetwork singleton = networkInterface.getNetwork(netUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronNetworkAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                int status = service.canDeleteNetwork(singleton);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        networkInterface.removeNetwork(netUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronNetworkAware service = (INeutronNetworkAware) instance;
+                service.neutronNetworkDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
index 7e2a06be59f668b1109e7ce6e37d7d8dbe9b8e0b..76c39e4294dd05a0ada503edd05d1243c9b436f5 100644 (file)
@@ -1,58 +1,58 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import javax.ws.rs.core.Application;\r
-import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;\r
-\r
-\r
-/**\r
- * This class is an instance of javax.ws.rs.core.Application and is used to return the classes\r
- * that will be instantiated for JAXRS processing. This is necessary\r
- * because package scanning in jersey doesn't yet work in OSGi environment.\r
- *\r
- */\r
-public class NeutronNorthboundRSApplication extends Application {\r
-    @Override\r
-    public Set<Class<?>> getClasses() {\r
-        Set<Class<?>> classes = new HashSet<Class<?>>();\r
-// northbound URIs\r
-        classes.add(NeutronNetworksNorthbound.class);\r
-        classes.add(NeutronSubnetsNorthbound.class);\r
-        classes.add(NeutronPortsNorthbound.class);\r
-        classes.add(NeutronRoutersNorthbound.class);\r
-        classes.add(NeutronFloatingIPsNorthbound.class);\r
-        return classes;\r
-    }\r
-\r
-    @Override\r
-    public Set<Object> getSingletons() {\r
-        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();\r
-\r
-        moxyJsonProvider.setAttributePrefix("@");\r
-        moxyJsonProvider.setFormattedOutput(true);\r
-        moxyJsonProvider.setIncludeRoot(false);\r
-        moxyJsonProvider.setMarshalEmptyCollections(true);\r
-        moxyJsonProvider.setValueWrapper("$");\r
-\r
-        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);\r
-        namespacePrefixMapper.put("router", "router");        // FIXME: fill in with XSD\r
-        namespacePrefixMapper.put("provider", "provider");    // FIXME: fill in with XSD\r
-        moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);\r
-        moxyJsonProvider.setNamespaceSeparator(':');\r
-\r
-        HashSet<Object> set = new HashSet<Object>(1);\r
-        set.add(moxyJsonProvider);\r
-        return set;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.ws.rs.core.Application;
+import org.eclipse.persistence.jaxb.rs.MOXyJsonProvider;
+
+
+/**
+ * This class is an instance of javax.ws.rs.core.Application and is used to return the classes
+ * that will be instantiated for JAXRS processing. This is necessary
+ * because package scanning in jersey doesn't yet work in OSGi environment.
+ *
+ */
+public class NeutronNorthboundRSApplication extends Application {
+    @Override
+    public Set<Class<?>> getClasses() {
+        Set<Class<?>> classes = new HashSet<Class<?>>();
+// northbound URIs
+        classes.add(NeutronNetworksNorthbound.class);
+        classes.add(NeutronSubnetsNorthbound.class);
+        classes.add(NeutronPortsNorthbound.class);
+        classes.add(NeutronRoutersNorthbound.class);
+        classes.add(NeutronFloatingIPsNorthbound.class);
+        return classes;
+    }
+
+    @Override
+    public Set<Object> getSingletons() {
+        MOXyJsonProvider moxyJsonProvider = new MOXyJsonProvider();
+
+        moxyJsonProvider.setAttributePrefix("@");
+        moxyJsonProvider.setFormattedOutput(true);
+        moxyJsonProvider.setIncludeRoot(false);
+        moxyJsonProvider.setMarshalEmptyCollections(true);
+        moxyJsonProvider.setValueWrapper("$");
+
+        Map<String, String> namespacePrefixMapper = new HashMap<String, String>(1);
+        namespacePrefixMapper.put("router", "router");        // FIXME: fill in with XSD
+        namespacePrefixMapper.put("provider", "provider");    // FIXME: fill in with XSD
+        moxyJsonProvider.setNamespacePrefixMapper(namespacePrefixMapper);
+        moxyJsonProvider.setNamespaceSeparator(':');
+
+        HashSet<Object> set = new HashSet<Object>(1);
+        set.add(moxyJsonProvider);
+        return set;
+    }
+}
index f6765fb221fbeb9e6c52ad476675cf96bfaf14c2..9b3399d9a8bfe72266843b0d4d8c34d6b163ef52 100644 (file)
@@ -1,55 +1,55 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-public class NeutronPortRequest {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="port")\r
-    NeutronPort singletonPort;\r
-\r
-    @XmlElement(name="ports")\r
-    List<NeutronPort> bulkRequest;\r
-\r
-    NeutronPortRequest() {\r
-    }\r
-\r
-    NeutronPortRequest(List<NeutronPort> bulk) {\r
-        bulkRequest = bulk;\r
-        singletonPort = null;\r
-    }\r
-\r
-    NeutronPortRequest(NeutronPort port) {\r
-        singletonPort = port;\r
-    }\r
-\r
-    public NeutronPort getSingleton() {\r
-        return singletonPort;\r
-    }\r
-\r
-    public boolean isSingleton() {\r
-        return (singletonPort != null);\r
-    }\r
-\r
-    public List<NeutronPort> getBulk() {\r
-        return bulkRequest;\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NeutronPortRequest {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="port")
+    NeutronPort singletonPort;
+
+    @XmlElement(name="ports")
+    List<NeutronPort> bulkRequest;
+
+    NeutronPortRequest() {
+    }
+
+    NeutronPortRequest(List<NeutronPort> bulk) {
+        bulkRequest = bulk;
+        singletonPort = null;
+    }
+
+    NeutronPortRequest(NeutronPort port) {
+        singletonPort = port;
+    }
+
+    public NeutronPort getSingleton() {
+        return singletonPort;
+    }
+
+    public boolean isSingleton() {
+        return (singletonPort != null);
+    }
+
+    public List<NeutronPort> getBulk() {
+        return bulkRequest;
+    }
+}
index f48a70d9d728a512401bc5cbc4efc793548e1e12..08e5dfbb364d6cf7c82b2c677cff3359f533a13b 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/ports")\r
-public class NeutronPortsNorthbound {\r
-\r
-    private NeutronPort extractFields(NeutronPort o, List<String> fields) {\r
-        return o.extractFields(fields);\r
-    }\r
-\r
-    /**\r
-     * Returns a list of all Ports */\r
-\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackPorts.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response listPorts(\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields,\r
-            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
-            @QueryParam("id") String queryID,\r
-            @QueryParam("network_id") String queryNetworkID,\r
-            @QueryParam("name") String queryName,\r
-            @QueryParam("admin_state_up") String queryAdminStateUp,\r
-            @QueryParam("status") String queryStatus,\r
-            @QueryParam("mac_address") String queryMACAddress,\r
-            @QueryParam("device_id") String queryDeviceID,\r
-            @QueryParam("device_owner") String queryDeviceOwner,\r
-            @QueryParam("tenant_id") String queryTenantID,\r
-            // pagination\r
-            @QueryParam("limit") String limit,\r
-            @QueryParam("marker") String marker,\r
-            @QueryParam("page_reverse") String pageReverse\r
-            // sorting not supported\r
-            ) {\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        List<NeutronPort> allPorts = portInterface.getAllPorts();\r
-        List<NeutronPort> ans = new ArrayList<NeutronPort>();\r
-        Iterator<NeutronPort> i = allPorts.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronPort oSS = i.next();\r
-            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
-                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
-                    (queryName == null || queryName.equals(oSS.getName())) &&\r
-                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
-                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
-                    (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&\r
-                    (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&\r
-                    (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&\r
-                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
-                if (fields.size() > 0)\r
-                    ans.add(extractFields(oSS,fields));\r
-                else\r
-                    ans.add(oSS);\r
-            }\r
-        }\r
-        //TODO: apply pagination to results\r
-        return Response.status(200).entity(\r
-                new NeutronPortRequest(ans)).build();\r
-    }\r
-\r
-    /**\r
-     * Returns a specific Port */\r
-\r
-    @Path("{portUUID}")\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackPorts.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response showPort(\r
-            @PathParam("portUUID") String portUUID,\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields ) {\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!portInterface.portExists(portUUID))\r
-            return Response.status(404).build();\r
-        if (fields.size() > 0) {\r
-            NeutronPort ans = portInterface.getPort(portUUID);\r
-            return Response.status(200).entity(\r
-                    new NeutronPortRequest(extractFields(ans, fields))).build();\r
-        } else\r
-            return Response.status(200).entity(\r
-                    new NeutronPortRequest(portInterface.getPort(portUUID))).build();\r
-    }\r
-\r
-    /**\r
-     * Creates new Ports */\r
-\r
-    @POST\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackPorts.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 201, condition = "Created"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented"),\r
-            @ResponseCode(code = 503, condition = "MAC generation failure") })\r
-    public Response createPorts(final NeutronPortRequest input) {\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (input.isSingleton()) {\r
-            NeutronPort singleton = input.getSingleton();\r
-\r
-            /*\r
-             * the port must be part of an existing network, must not already exist,\r
-             * have a valid MAC and the MAC not be in use\r
-             */\r
-            if (singleton.getNetworkUUID() == null)\r
-                return Response.status(400).build();\r
-            if (portInterface.portExists(singleton.getID()))\r
-                return Response.status(400).build();\r
-            if (!networkInterface.networkExists(singleton.getNetworkUUID()))\r
-                return Response.status(404).build();\r
-            if (singleton.getMacAddress() == null ||\r
-                    !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
-                return Response.status(400).build();\r
-            if (portInterface.macInUse(singleton.getMacAddress()))\r
-                return Response.status(409).build();\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronPortAware service = (INeutronPortAware) instance;\r
-                    int status = service.canCreatePort(singleton);\r
-                    if (status < 200 || status > 299)\r
-                        return Response.status(status).build();\r
-                }\r
-            }\r
-            /*\r
-             * if fixed IPs are specified, each one has to have an existing subnet ID\r
-             * that is in the same scoping network as the port.  In addition, if an IP\r
-             * address is specified it has to be a valid address for the subnet and not\r
-             * already in use\r
-             */\r
-            List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
-            if (fixedIPs != null && fixedIPs.size() > 0) {\r
-                Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
-                while (fixedIPIterator.hasNext()) {\r
-                    Neutron_IPs ip = fixedIPIterator.next();\r
-                    if (ip.getSubnetUUID() == null)\r
-                        return Response.status(400).build();\r
-                    if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
-                        return Response.status(400).build();\r
-                    NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
-                    if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
-                        return Response.status(400).build();\r
-                    if (ip.getIpAddress() != null) {\r
-                        if (!subnet.isValidIP(ip.getIpAddress()))\r
-                            return Response.status(400).build();\r
-                        if (subnet.isIPInUse(ip.getIpAddress()))\r
-                            return Response.status(409).build();\r
-                    }\r
-                }\r
-            }\r
-\r
-            // add the port to the cache\r
-            portInterface.addPort(singleton);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronPortAware service = (INeutronPortAware) instance;\r
-                    service.neutronPortCreated(singleton);\r
-                }\r
-            }\r
-        } else {\r
-            List<NeutronPort> bulk = input.getBulk();\r
-            Iterator<NeutronPort> i = bulk.iterator();\r
-            HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
-            while (i.hasNext()) {\r
-                NeutronPort test = i.next();\r
-\r
-                /*\r
-                 * the port must be part of an existing network, must not already exist,\r
-                 * have a valid MAC and the MAC not be in use.  Further the bulk request\r
-                 * can't already contain a new port with the same UUID\r
-                 */\r
-                if (portInterface.portExists(test.getID()))\r
-                    return Response.status(400).build();\r
-                if (testMap.containsKey(test.getID()))\r
-                    return Response.status(400).build();\r
-                for (NeutronPort check : testMap.values()) {\r
-                    if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))\r
-                        return Response.status(409).build();\r
-                    for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {\r
-                        for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {\r
-                            if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))\r
-                                return Response.status(409).build();\r
-                        }\r
-                    }\r
-                }\r
-                testMap.put(test.getID(), test);\r
-                if (!networkInterface.networkExists(test.getNetworkUUID()))\r
-                    return Response.status(404).build();\r
-                if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))\r
-                    return Response.status(400).build();\r
-                if (portInterface.macInUse(test.getMacAddress()))\r
-                    return Response.status(409).build();\r
-                if (instances != null) {\r
-                    for (Object instance : instances) {\r
-                        INeutronPortAware service = (INeutronPortAware) instance;\r
-                        int status = service.canCreatePort(test);\r
-                        if (status < 200 || status > 299)\r
-                            return Response.status(status).build();\r
-                    }\r
-                }\r
-                /*\r
-                 * if fixed IPs are specified, each one has to have an existing subnet ID\r
-                 * that is in the same scoping network as the port.  In addition, if an IP\r
-                 * address is specified it has to be a valid address for the subnet and not\r
-                 * already in use (or be the gateway IP address of the subnet)\r
-                 */\r
-                List<Neutron_IPs> fixedIPs = test.getFixedIPs();\r
-                if (fixedIPs != null && fixedIPs.size() > 0) {\r
-                    Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
-                    while (fixedIPIterator.hasNext()) {\r
-                        Neutron_IPs ip = fixedIPIterator.next();\r
-                        if (ip.getSubnetUUID() == null)\r
-                            return Response.status(400).build();\r
-                        if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
-                            return Response.status(400).build();\r
-                        NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
-                        if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
-                            return Response.status(400).build();\r
-                        if (ip.getIpAddress() != null) {\r
-                            if (!subnet.isValidIP(ip.getIpAddress()))\r
-                                return Response.status(400).build();\r
-                            //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the\r
-                            //same bulk create\r
-                            if (subnet.isIPInUse(ip.getIpAddress()))\r
-                                return Response.status(409).build();\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            //once everything has passed, then we can add to the cache\r
-            i = bulk.iterator();\r
-            while (i.hasNext()) {\r
-                NeutronPort test = i.next();\r
-                portInterface.addPort(test);\r
-                if (instances != null) {\r
-                    for (Object instance : instances) {\r
-                        INeutronPortAware service = (INeutronPortAware) instance;\r
-                        service.neutronPortCreated(test);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return Response.status(201).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Updates a Port */\r
-\r
-    @Path("{portUUID}")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackPorts.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response updatePort(\r
-            @PathParam("portUUID") String portUUID,\r
-            NeutronPortRequest input\r
-            ) {\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        // port has to exist and only a single delta is supported\r
-        if (!portInterface.portExists(portUUID))\r
-            return Response.status(404).build();\r
-        NeutronPort target = portInterface.getPort(portUUID);\r
-        if (!input.isSingleton())\r
-            return Response.status(400).build();\r
-        NeutronPort singleton = input.getSingleton();\r
-        NeutronPort original = portInterface.getPort(portUUID);\r
-\r
-        // deltas restricted by Neutron\r
-        if (singleton.getID() != null || singleton.getTenantID() != null ||\r
-                singleton.getStatus() != null)\r
-            return Response.status(400).build();\r
-\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronPortAware service = (INeutronPortAware) instance;\r
-                int status = service.canUpdatePort(singleton, original);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-\r
-        // Verify the new fixed ips are valid\r
-        List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();\r
-        if (fixedIPs != null && fixedIPs.size() > 0) {\r
-            Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();\r
-            while (fixedIPIterator.hasNext()) {\r
-                Neutron_IPs ip = fixedIPIterator.next();\r
-                if (ip.getSubnetUUID() == null)\r
-                    return Response.status(400).build();\r
-                if (!subnetInterface.subnetExists(ip.getSubnetUUID()))\r
-                    return Response.status(400).build();\r
-                NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());\r
-                if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))\r
-                    return Response.status(400).build();\r
-                if (ip.getIpAddress() != null) {\r
-                    if (!subnet.isValidIP(ip.getIpAddress()))\r
-                        return Response.status(400).build();\r
-                    if (subnet.isIPInUse(ip.getIpAddress()))\r
-                        return Response.status(409).build();\r
-                }\r
-            }\r
-        }\r
-\r
-//        TODO: Support change of security groups\r
-        // update the port and return the modified object\r
-        portInterface.updatePort(portUUID, singleton);\r
-        NeutronPort updatedPort = portInterface.getPort(portUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronPortAware service = (INeutronPortAware) instance;\r
-                service.neutronPortUpdated(updatedPort);\r
-            }\r
-        }\r
-        return Response.status(200).entity(\r
-                new NeutronPortRequest(updatedPort)).build();\r
-\r
-    }\r
-\r
-    /**\r
-     * Deletes a Port */\r
-\r
-    @Path("{portUUID}")\r
-    @DELETE\r
-    @StatusCodes({\r
-        @ResponseCode(code = 204, condition = "No Content"),\r
-        @ResponseCode(code = 401, condition = "Unauthorized"),\r
-        @ResponseCode(code = 403, condition = "Forbidden"),\r
-        @ResponseCode(code = 404, condition = "Not Found"),\r
-        @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response deletePort(\r
-            @PathParam("portUUID") String portUUID) {\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        // port has to exist and not be owned by anyone.  then it can be removed from the cache\r
-        if (!portInterface.portExists(portUUID))\r
-            return Response.status(404).build();\r
-        NeutronPort port = portInterface.getPort(portUUID);\r
-        if (port.getDeviceID() != null ||\r
-                port.getDeviceOwner() != null)\r
-            Response.status(403).build();\r
-        NeutronPort singleton = portInterface.getPort(portUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronPortAware service = (INeutronPortAware) instance;\r
-                int status = service.canDeletePort(singleton);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        portInterface.removePort(portUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronPortAware service = (INeutronPortAware) instance;\r
-                service.neutronPortDeleted(singleton);\r
-            }\r
-        }\r
-        return Response.status(204).build();\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/ports")
+public class NeutronPortsNorthbound {
+
+    private NeutronPort extractFields(NeutronPort o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all Ports */
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackPorts.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response listPorts(
+            // return fields
+            @QueryParam("fields") List<String> fields,
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them
+            @QueryParam("id") String queryID,
+            @QueryParam("network_id") String queryNetworkID,
+            @QueryParam("name") String queryName,
+            @QueryParam("admin_state_up") String queryAdminStateUp,
+            @QueryParam("status") String queryStatus,
+            @QueryParam("mac_address") String queryMACAddress,
+            @QueryParam("device_id") String queryDeviceID,
+            @QueryParam("device_owner") String queryDeviceOwner,
+            @QueryParam("tenant_id") String queryTenantID,
+            // pagination
+            @QueryParam("limit") String limit,
+            @QueryParam("marker") String marker,
+            @QueryParam("page_reverse") String pageReverse
+            // sorting not supported
+            ) {
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronPort> allPorts = portInterface.getAllPorts();
+        List<NeutronPort> ans = new ArrayList<NeutronPort>();
+        Iterator<NeutronPort> i = allPorts.iterator();
+        while (i.hasNext()) {
+            NeutronPort oSS = i.next();
+            if ((queryID == null || queryID.equals(oSS.getID())) &&
+                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+                    (queryName == null || queryName.equals(oSS.getName())) &&
+                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+                    (queryMACAddress == null || queryMACAddress.equals(oSS.getMacAddress())) &&
+                    (queryDeviceID == null || queryDeviceID.equals(oSS.getDeviceID())) &&
+                    (queryDeviceOwner == null || queryDeviceOwner.equals(oSS.getDeviceOwner())) &&
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+                if (fields.size() > 0)
+                    ans.add(extractFields(oSS,fields));
+                else
+                    ans.add(oSS);
+            }
+        }
+        //TODO: apply pagination to results
+        return Response.status(200).entity(
+                new NeutronPortRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Port */
+
+    @Path("{portUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackPorts.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response showPort(
+            @PathParam("portUUID") String portUUID,
+            // return fields
+            @QueryParam("fields") List<String> fields ) {
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!portInterface.portExists(portUUID))
+            return Response.status(404).build();
+        if (fields.size() > 0) {
+            NeutronPort ans = portInterface.getPort(portUUID);
+            return Response.status(200).entity(
+                    new NeutronPortRequest(extractFields(ans, fields))).build();
+        } else
+            return Response.status(200).entity(
+                    new NeutronPortRequest(portInterface.getPort(portUUID))).build();
+    }
+
+    /**
+     * Creates new Ports */
+
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackPorts.class)
+    @StatusCodes({
+            @ResponseCode(code = 201, condition = "Created"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented"),
+            @ResponseCode(code = 503, condition = "MAC generation failure") })
+    public Response createPorts(final NeutronPortRequest input) {
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (input.isSingleton()) {
+            NeutronPort singleton = input.getSingleton();
+
+            /*
+             * the port must be part of an existing network, must not already exist,
+             * have a valid MAC and the MAC not be in use
+             */
+            if (singleton.getNetworkUUID() == null)
+                return Response.status(400).build();
+            if (portInterface.portExists(singleton.getID()))
+                return Response.status(400).build();
+            if (!networkInterface.networkExists(singleton.getNetworkUUID()))
+                return Response.status(404).build();
+            if (singleton.getMacAddress() == null ||
+                    !singleton.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+                return Response.status(400).build();
+            if (portInterface.macInUse(singleton.getMacAddress()))
+                return Response.status(409).build();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronPortAware service = (INeutronPortAware) instance;
+                    int status = service.canCreatePort(singleton);
+                    if (status < 200 || status > 299)
+                        return Response.status(status).build();
+                }
+            }
+            /*
+             * if fixed IPs are specified, each one has to have an existing subnet ID
+             * that is in the same scoping network as the port.  In addition, if an IP
+             * address is specified it has to be a valid address for the subnet and not
+             * already in use
+             */
+            List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+            if (fixedIPs != null && fixedIPs.size() > 0) {
+                Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+                while (fixedIPIterator.hasNext()) {
+                    Neutron_IPs ip = fixedIPIterator.next();
+                    if (ip.getSubnetUUID() == null)
+                        return Response.status(400).build();
+                    if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+                        return Response.status(400).build();
+                    NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+                    if (!singleton.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+                        return Response.status(400).build();
+                    if (ip.getIpAddress() != null) {
+                        if (!subnet.isValidIP(ip.getIpAddress()))
+                            return Response.status(400).build();
+                        if (subnet.isIPInUse(ip.getIpAddress()))
+                            return Response.status(409).build();
+                    }
+                }
+            }
+
+            // add the port to the cache
+            portInterface.addPort(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronPortAware service = (INeutronPortAware) instance;
+                    service.neutronPortCreated(singleton);
+                }
+            }
+        } else {
+            List<NeutronPort> bulk = input.getBulk();
+            Iterator<NeutronPort> i = bulk.iterator();
+            HashMap<String, NeutronPort> testMap = new HashMap<String, NeutronPort>();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+            while (i.hasNext()) {
+                NeutronPort test = i.next();
+
+                /*
+                 * the port must be part of an existing network, must not already exist,
+                 * have a valid MAC and the MAC not be in use.  Further the bulk request
+                 * can't already contain a new port with the same UUID
+                 */
+                if (portInterface.portExists(test.getID()))
+                    return Response.status(400).build();
+                if (testMap.containsKey(test.getID()))
+                    return Response.status(400).build();
+                for (NeutronPort check : testMap.values()) {
+                    if (test.getMacAddress().equalsIgnoreCase(check.getMacAddress()))
+                        return Response.status(409).build();
+                    for (Neutron_IPs test_fixedIP : test.getFixedIPs()) {
+                        for (Neutron_IPs check_fixedIP : check.getFixedIPs()) {
+                            if (test_fixedIP.getIpAddress().equals(check_fixedIP.getIpAddress()))
+                                return Response.status(409).build();
+                        }
+                    }
+                }
+                testMap.put(test.getID(), test);
+                if (!networkInterface.networkExists(test.getNetworkUUID()))
+                    return Response.status(404).build();
+                if (!test.getMacAddress().matches("^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$"))
+                    return Response.status(400).build();
+                if (portInterface.macInUse(test.getMacAddress()))
+                    return Response.status(409).build();
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronPortAware service = (INeutronPortAware) instance;
+                        int status = service.canCreatePort(test);
+                        if (status < 200 || status > 299)
+                            return Response.status(status).build();
+                    }
+                }
+                /*
+                 * if fixed IPs are specified, each one has to have an existing subnet ID
+                 * that is in the same scoping network as the port.  In addition, if an IP
+                 * address is specified it has to be a valid address for the subnet and not
+                 * already in use (or be the gateway IP address of the subnet)
+                 */
+                List<Neutron_IPs> fixedIPs = test.getFixedIPs();
+                if (fixedIPs != null && fixedIPs.size() > 0) {
+                    Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+                    while (fixedIPIterator.hasNext()) {
+                        Neutron_IPs ip = fixedIPIterator.next();
+                        if (ip.getSubnetUUID() == null)
+                            return Response.status(400).build();
+                        if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+                            return Response.status(400).build();
+                        NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+                        if (!test.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+                            return Response.status(400).build();
+                        if (ip.getIpAddress() != null) {
+                            if (!subnet.isValidIP(ip.getIpAddress()))
+                                return Response.status(400).build();
+                            //TODO: need to add consideration for a fixed IP being assigned the same address as a allocated IP in the
+                            //same bulk create
+                            if (subnet.isIPInUse(ip.getIpAddress()))
+                                return Response.status(409).build();
+                        }
+                    }
+                }
+            }
+
+            //once everything has passed, then we can add to the cache
+            i = bulk.iterator();
+            while (i.hasNext()) {
+                NeutronPort test = i.next();
+                portInterface.addPort(test);
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronPortAware service = (INeutronPortAware) instance;
+                        service.neutronPortCreated(test);
+                    }
+                }
+            }
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Port */
+
+    @Path("{portUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackPorts.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response updatePort(
+            @PathParam("portUUID") String portUUID,
+            NeutronPortRequest input
+            ) {
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        // port has to exist and only a single delta is supported
+        if (!portInterface.portExists(portUUID))
+            return Response.status(404).build();
+        NeutronPort target = portInterface.getPort(portUUID);
+        if (!input.isSingleton())
+            return Response.status(400).build();
+        NeutronPort singleton = input.getSingleton();
+        NeutronPort original = portInterface.getPort(portUUID);
+
+        // deltas restricted by Neutron
+        if (singleton.getID() != null || singleton.getTenantID() != null ||
+                singleton.getStatus() != null)
+            return Response.status(400).build();
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronPortAware service = (INeutronPortAware) instance;
+                int status = service.canUpdatePort(singleton, original);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+
+        // Verify the new fixed ips are valid
+        List<Neutron_IPs> fixedIPs = singleton.getFixedIPs();
+        if (fixedIPs != null && fixedIPs.size() > 0) {
+            Iterator<Neutron_IPs> fixedIPIterator = fixedIPs.iterator();
+            while (fixedIPIterator.hasNext()) {
+                Neutron_IPs ip = fixedIPIterator.next();
+                if (ip.getSubnetUUID() == null)
+                    return Response.status(400).build();
+                if (!subnetInterface.subnetExists(ip.getSubnetUUID()))
+                    return Response.status(400).build();
+                NeutronSubnet subnet = subnetInterface.getSubnet(ip.getSubnetUUID());
+                if (!target.getNetworkUUID().equalsIgnoreCase(subnet.getNetworkUUID()))
+                    return Response.status(400).build();
+                if (ip.getIpAddress() != null) {
+                    if (!subnet.isValidIP(ip.getIpAddress()))
+                        return Response.status(400).build();
+                    if (subnet.isIPInUse(ip.getIpAddress()))
+                        return Response.status(409).build();
+                }
+            }
+        }
+
+//        TODO: Support change of security groups
+        // update the port and return the modified object
+        portInterface.updatePort(portUUID, singleton);
+        NeutronPort updatedPort = portInterface.getPort(portUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronPortAware service = (INeutronPortAware) instance;
+                service.neutronPortUpdated(updatedPort);
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronPortRequest(updatedPort)).build();
+
+    }
+
+    /**
+     * Deletes a Port */
+
+    @Path("{portUUID}")
+    @DELETE
+    @StatusCodes({
+        @ResponseCode(code = 204, condition = "No Content"),
+        @ResponseCode(code = 401, condition = "Unauthorized"),
+        @ResponseCode(code = 403, condition = "Forbidden"),
+        @ResponseCode(code = 404, condition = "Not Found"),
+        @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response deletePort(
+            @PathParam("portUUID") String portUUID) {
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        // port has to exist and not be owned by anyone.  then it can be removed from the cache
+        if (!portInterface.portExists(portUUID))
+            return Response.status(404).build();
+        NeutronPort port = portInterface.getPort(portUUID);
+        if (port.getDeviceID() != null ||
+                port.getDeviceOwner() != null)
+            Response.status(403).build();
+        NeutronPort singleton = portInterface.getPort(portUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronPortAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronPortAware service = (INeutronPortAware) instance;
+                int status = service.canDeletePort(singleton);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        portInterface.removePort(portUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronPortAware service = (INeutronPortAware) instance;
+                service.neutronPortDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
index 1fcc9a9e912b25d0912a3ed99b3253d599e615ba..806fd69e8af50ff0b85f48366521b0f0556f25a4 100644 (file)
@@ -1,57 +1,57 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronRouterRequest {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="router")\r
-    NeutronRouter singletonRouter;\r
-\r
-    @XmlElement(name="routers")\r
-    List<NeutronRouter> bulkRequest;\r
-\r
-    NeutronRouterRequest() {\r
-    }\r
-\r
-    NeutronRouterRequest(List<NeutronRouter> bulk) {\r
-        bulkRequest = bulk;\r
-        singletonRouter = null;\r
-    }\r
-\r
-    NeutronRouterRequest(NeutronRouter router) {\r
-        singletonRouter = router;\r
-    }\r
-\r
-    public List<NeutronRouter> getBulk() {\r
-        return bulkRequest;\r
-    }\r
-\r
-    public NeutronRouter getSingleton() {\r
-        return singletonRouter;\r
-    }\r
-\r
-    public boolean isSingleton() {\r
-        return (singletonRouter != null);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronRouterRequest {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="router")
+    NeutronRouter singletonRouter;
+
+    @XmlElement(name="routers")
+    List<NeutronRouter> bulkRequest;
+
+    NeutronRouterRequest() {
+    }
+
+    NeutronRouterRequest(List<NeutronRouter> bulk) {
+        bulkRequest = bulk;
+        singletonRouter = null;
+    }
+
+    NeutronRouterRequest(NeutronRouter router) {
+        singletonRouter = router;
+    }
+
+    public List<NeutronRouter> getBulk() {
+        return bulkRequest;
+    }
+
+    public NeutronRouter getSingleton() {
+        return singletonRouter;
+    }
+
+    public boolean isSingleton() {
+        return (singletonRouter != null);
+    }
+}
index df2009ed2b76170bd281be4fd57d100f3f2203dc..fc7e0f7efbf429014859c760caf86add6f326518 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronPort;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing the open DOVE\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/routers")\r
-public class NeutronRoutersNorthbound {\r
-\r
-    private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {\r
-        return o.extractFields(fields);\r
-    }\r
-\r
-    /**\r
-     * Returns a list of all Routers */\r
-\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouters.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response listRouters(\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields,\r
-            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
-            @QueryParam("id") String queryID,\r
-            @QueryParam("name") String queryName,\r
-            @QueryParam("admin_state_up") String queryAdminStateUp,\r
-            @QueryParam("status") String queryStatus,\r
-            @QueryParam("tenant_id") String queryTenantID,\r
-            @QueryParam("external_gateway_info") String queryExternalGatewayInfo,\r
-            // pagination\r
-            @QueryParam("limit") String limit,\r
-            @QueryParam("marker") String marker,\r
-            @QueryParam("page_reverse") String pageReverse\r
-            // sorting not supported\r
-            ) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        List<NeutronRouter> allRouters = routerInterface.getAllRouters();\r
-        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();\r
-        Iterator<NeutronRouter> i = allRouters.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronRouter oSS = i.next();\r
-            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
-                    (queryName == null || queryName.equals(oSS.getName())) &&\r
-                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&\r
-                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&\r
-                    (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&\r
-                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
-                if (fields.size() > 0)\r
-                    ans.add(extractFields(oSS,fields));\r
-                else\r
-                    ans.add(oSS);\r
-            }\r
-        }\r
-        //TODO: apply pagination to results\r
-        return Response.status(200).entity(\r
-                new NeutronRouterRequest(ans)).build();\r
-    }\r
-\r
-    /**\r
-     * Returns a specific Router */\r
-\r
-    @Path("{routerUUID}")\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouters.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response showRouter(\r
-            @PathParam("routerUUID") String routerUUID,\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!routerInterface.routerExists(routerUUID))\r
-            return Response.status(404).build();\r
-        if (fields.size() > 0) {\r
-            NeutronRouter ans = routerInterface.getRouter(routerUUID);\r
-            return Response.status(200).entity(\r
-                    new NeutronRouterRequest(extractFields(ans, fields))).build();\r
-        } else\r
-            return Response.status(200).entity(\r
-                    new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
-    }\r
-\r
-    /**\r
-     * Creates new Routers */\r
-\r
-    @POST\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouters.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 201, condition = "Created"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response createRouters(final NeutronRouterRequest input) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (input.isSingleton()) {\r
-            NeutronRouter singleton = input.getSingleton();\r
-\r
-            /*\r
-             * verify that the router doesn't already exist (issue: is deeper inspection necessary?)\r
-             * if there is external gateway information provided, verify that the specified network\r
-             * exists and has been designated as "router:external"\r
-             */\r
-            if (routerInterface.routerExists(singleton.getID()))\r
-                return Response.status(400).build();\r
-            if (singleton.getExternalGatewayInfo() != null) {\r
-                String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
-                if (!networkInterface.networkExists(externNetworkPtr))\r
-                    return Response.status(400).build();\r
-                NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
-                if (!externNetwork.isRouterExternal())\r
-                    return Response.status(400).build();\r
-            }\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                    int status = service.canCreateRouter(singleton);\r
-                    if (status < 200 || status > 299)\r
-                        return Response.status(status).build();\r
-                }\r
-            }\r
-\r
-            /*\r
-             * add router to the cache\r
-             */\r
-            routerInterface.addRouter(singleton);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                    service.neutronRouterCreated(singleton);\r
-                }\r
-            }\r
-        } else {\r
-\r
-            /*\r
-             * only singleton router creates supported\r
-             */\r
-            return Response.status(400).build();\r
-        }\r
-        return Response.status(201).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Updates a Router */\r
-\r
-    @Path("{routerUUID}")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouters.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response updateRouter(\r
-            @PathParam("routerUUID") String routerUUID,\r
-            NeutronRouterRequest input\r
-            ) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * router has to exist and only a single delta can be supplied\r
-         */\r
-        if (!routerInterface.routerExists(routerUUID))\r
-            return Response.status(404).build();\r
-        if (!input.isSingleton())\r
-            return Response.status(400).build();\r
-        NeutronRouter singleton = input.getSingleton();\r
-        NeutronRouter original = routerInterface.getRouter(routerUUID);\r
-\r
-        /*\r
-         * attribute changes blocked by Neutron\r
-         */\r
-        if (singleton.getID() != null || singleton.getTenantID() != null ||\r
-                singleton.getStatus() != null)\r
-            return Response.status(400).build();\r
-\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                int status = service.canUpdateRouter(singleton, original);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        /*\r
-         * if the external gateway info is being changed, verify that the new network\r
-         * exists and has been designated as an external network\r
-         */\r
-        if (singleton.getExternalGatewayInfo() != null) {\r
-            String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();\r
-            if (!networkInterface.networkExists(externNetworkPtr))\r
-                return Response.status(400).build();\r
-            NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);\r
-            if (!externNetwork.isRouterExternal())\r
-                return Response.status(400).build();\r
-        }\r
-\r
-        /*\r
-         * update the router entry and return the modified object\r
-         */\r
-        routerInterface.updateRouter(routerUUID, singleton);\r
-        NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.neutronRouterUpdated(updatedRouter);\r
-            }\r
-        }\r
-        return Response.status(200).entity(\r
-                new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();\r
-\r
-    }\r
-\r
-    /**\r
-     * Deletes a Router */\r
-\r
-    @Path("{routerUUID}")\r
-    @DELETE\r
-    @StatusCodes({\r
-            @ResponseCode(code = 204, condition = "No Content"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response deleteRouter(\r
-            @PathParam("routerUUID") String routerUUID) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * verify that the router exists and is not in use before removing it\r
-         */\r
-        if (!routerInterface.routerExists(routerUUID))\r
-            return Response.status(404).build();\r
-        if (routerInterface.routerInUse(routerUUID))\r
-            return Response.status(409).build();\r
-        NeutronRouter singleton = routerInterface.getRouter(routerUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                int status = service.canDeleteRouter(singleton);\r
-                if (status < 200 || status > 299)\r
-                    return Response.status(status).build();\r
-            }\r
-        }\r
-        routerInterface.removeRouter(routerUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.neutronRouterDeleted(singleton);\r
-            }\r
-        }\r
-        return Response.status(204).build();\r
-    }\r
-\r
-    /**\r
-     * Adds an interface to a router */\r
-\r
-    @Path("{routerUUID}/add_router_interface")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouterInterfaces.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response addRouterInterface(\r
-            @PathParam("routerUUID") String routerUUID,\r
-            NeutronRouter_Interface input\r
-            ) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         *  While the Neutron specification says that the router has to exist and the input can only specify either a subnet id\r
-         *  or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present\r
-         */\r
-        if (!routerInterface.routerExists(routerUUID))\r
-            return Response.status(400).build();\r
-        NeutronRouter target = routerInterface.getRouter(routerUUID);\r
-        if (input.getSubnetUUID() == null ||\r
-                    input.getPortUUID() == null)\r
-                return Response.status(400).build();\r
-\r
-        // check that the port is part of the subnet\r
-        NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
-        if (targetSubnet == null)\r
-            return Response.status(400).build();\r
-        NeutronPort targetPort = portInterface.getPort(input.getPortUUID());\r
-        if (targetPort == null)\r
-            return Response.status(400).build();\r
-        if (!targetSubnet.getPortsInSubnet().contains(targetPort))\r
-            return Response.status(400).build();\r
-\r
-        if (targetPort.getFixedIPs().size() != 1)\r
-            return Response.status(400).build();\r
-        if (targetPort.getDeviceID() != null ||\r
-                targetPort.getDeviceOwner() != null)\r
-            return Response.status(409).build();\r
-\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.canAttachInterface(target, input);\r
-            }\r
-        }\r
-\r
-        //mark the port device id and device owner fields\r
-        targetPort.setDeviceOwner("network:router_interface");\r
-        targetPort.setDeviceID(routerUUID);\r
-\r
-        target.addInterface(input.getPortUUID(), input);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.neutronRouterInterfaceAttached(target, input);\r
-            }\r
-        }\r
-\r
-        return Response.status(200).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Removes an interface to a router */\r
-\r
-    @Path("{routerUUID}/remove_router_interface")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackRouterInterfaces.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response removeRouterInterface(\r
-            @PathParam("routerUUID") String routerUUID,\r
-            NeutronRouter_Interface input\r
-            ) {\r
-        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);\r
-        if (routerInterface == null) {\r
-            throw new ServiceUnavailableException("Router CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);\r
-        if (portInterface == null) {\r
-            throw new ServiceUnavailableException("Port CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        // verify the router exists\r
-        if (!routerInterface.routerExists(routerUUID))\r
-            return Response.status(400).build();\r
-        NeutronRouter target = routerInterface.getRouter(routerUUID);\r
-\r
-        /*\r
-         * remove by subnet id.  Collect information about the impacted router for the response and\r
-         * remove the port corresponding to the gateway IP address of the subnet\r
-         */\r
-        if (input.getPortUUID() == null &&\r
-                input.getSubnetUUID() != null) {\r
-            NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());\r
-            if (port == null)\r
-                return Response.status(404).build();\r
-            input.setPortUUID(port.getID());\r
-            input.setID(target.getID());\r
-            input.setTenantID(target.getTenantID());\r
-\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                    service.canDetachInterface(target, input);\r
-                }\r
-            }\r
-\r
-            // reset the port ownership\r
-            port.setDeviceID(null);\r
-            port.setDeviceOwner(null);\r
-\r
-            target.removeInterface(input.getPortUUID());\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                    service.neutronRouterInterfaceDetached(target, input);\r
-                }\r
-            }\r
-            return Response.status(200).entity(input).build();\r
-        }\r
-\r
-        /*\r
-         * remove by port id. collect information about the impacted router for the response\r
-         * remove the interface and reset the port ownership\r
-         */\r
-        if (input.getPortUUID() != null &&\r
-                input.getSubnetUUID() == null) {\r
-            NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());\r
-            input.setSubnetUUID(targetInterface.getSubnetUUID());\r
-            input.setID(target.getID());\r
-            input.setTenantID(target.getTenantID());\r
-            NeutronPort port = portInterface.getPort(input.getPortUUID());\r
-            port.setDeviceID(null);\r
-            port.setDeviceOwner(null);\r
-            target.removeInterface(input.getPortUUID());\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.neutronRouterInterfaceDetached(target, input);\r
-            }\r
-            return Response.status(200).entity(input).build();\r
-        }\r
-\r
-        /*\r
-         * remove by both port and subnet ID.  Verify that the first fixed IP of the port is a valid\r
-         * IP address for the subnet, and then remove the interface, collecting information about the\r
-         * impacted router for the response and reset port ownership\r
-         */\r
-        if (input.getPortUUID() != null &&\r
-                input.getSubnetUUID() != null) {\r
-            NeutronPort port = portInterface.getPort(input.getPortUUID());\r
-            NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());\r
-            if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))\r
-                return Response.status(409).build();\r
-            input.setID(target.getID());\r
-            input.setTenantID(target.getTenantID());\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                    service.canDetachInterface(target, input);\r
-                }\r
-            }\r
-            port.setDeviceID(null);\r
-            port.setDeviceOwner(null);\r
-            target.removeInterface(input.getPortUUID());\r
-            for (Object instance : instances) {\r
-                INeutronRouterAware service = (INeutronRouterAware) instance;\r
-                service.neutronRouterInterfaceDetached(target, input);\r
-            }\r
-            return Response.status(200).entity(input).build();\r
-        }\r
-\r
-        // have to specify either a port ID or a subnet ID\r
-        return Response.status(400).build();\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronRouterCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter;
+import org.opendaylight.controller.networkconfig.neutron.NeutronRouter_Interface;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing the open DOVE
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/routers")
+public class NeutronRoutersNorthbound {
+
+    private NeutronRouter extractFields(NeutronRouter o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+    /**
+     * Returns a list of all Routers */
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouters.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response listRouters(
+            // return fields
+            @QueryParam("fields") List<String> fields,
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them
+            @QueryParam("id") String queryID,
+            @QueryParam("name") String queryName,
+            @QueryParam("admin_state_up") String queryAdminStateUp,
+            @QueryParam("status") String queryStatus,
+            @QueryParam("tenant_id") String queryTenantID,
+            @QueryParam("external_gateway_info") String queryExternalGatewayInfo,
+            // pagination
+            @QueryParam("limit") String limit,
+            @QueryParam("marker") String marker,
+            @QueryParam("page_reverse") String pageReverse
+            // sorting not supported
+            ) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronRouter> allRouters = routerInterface.getAllRouters();
+        List<NeutronRouter> ans = new ArrayList<NeutronRouter>();
+        Iterator<NeutronRouter> i = allRouters.iterator();
+        while (i.hasNext()) {
+            NeutronRouter oSS = i.next();
+            if ((queryID == null || queryID.equals(oSS.getID())) &&
+                    (queryName == null || queryName.equals(oSS.getName())) &&
+                    (queryAdminStateUp == null || queryAdminStateUp.equals(oSS.getAdminStateUp())) &&
+                    (queryStatus == null || queryStatus.equals(oSS.getStatus())) &&
+                    (queryExternalGatewayInfo == null || queryExternalGatewayInfo.equals(oSS.getExternalGatewayInfo())) &&
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+                if (fields.size() > 0)
+                    ans.add(extractFields(oSS,fields));
+                else
+                    ans.add(oSS);
+            }
+        }
+        //TODO: apply pagination to results
+        return Response.status(200).entity(
+                new NeutronRouterRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Router */
+
+    @Path("{routerUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouters.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response showRouter(
+            @PathParam("routerUUID") String routerUUID,
+            // return fields
+            @QueryParam("fields") List<String> fields) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!routerInterface.routerExists(routerUUID))
+            return Response.status(404).build();
+        if (fields.size() > 0) {
+            NeutronRouter ans = routerInterface.getRouter(routerUUID);
+            return Response.status(200).entity(
+                    new NeutronRouterRequest(extractFields(ans, fields))).build();
+        } else
+            return Response.status(200).entity(
+                    new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+    }
+
+    /**
+     * Creates new Routers */
+
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouters.class)
+    @StatusCodes({
+            @ResponseCode(code = 201, condition = "Created"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response createRouters(final NeutronRouterRequest input) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (input.isSingleton()) {
+            NeutronRouter singleton = input.getSingleton();
+
+            /*
+             * verify that the router doesn't already exist (issue: is deeper inspection necessary?)
+             * if there is external gateway information provided, verify that the specified network
+             * exists and has been designated as "router:external"
+             */
+            if (routerInterface.routerExists(singleton.getID()))
+                return Response.status(400).build();
+            if (singleton.getExternalGatewayInfo() != null) {
+                String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+                if (!networkInterface.networkExists(externNetworkPtr))
+                    return Response.status(400).build();
+                NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+                if (!externNetwork.isRouterExternal())
+                    return Response.status(400).build();
+            }
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronRouterAware service = (INeutronRouterAware) instance;
+                    int status = service.canCreateRouter(singleton);
+                    if (status < 200 || status > 299)
+                        return Response.status(status).build();
+                }
+            }
+
+            /*
+             * add router to the cache
+             */
+            routerInterface.addRouter(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronRouterAware service = (INeutronRouterAware) instance;
+                    service.neutronRouterCreated(singleton);
+                }
+            }
+        } else {
+
+            /*
+             * only singleton router creates supported
+             */
+            return Response.status(400).build();
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Router */
+
+    @Path("{routerUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouters.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response updateRouter(
+            @PathParam("routerUUID") String routerUUID,
+            NeutronRouterRequest input
+            ) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * router has to exist and only a single delta can be supplied
+         */
+        if (!routerInterface.routerExists(routerUUID))
+            return Response.status(404).build();
+        if (!input.isSingleton())
+            return Response.status(400).build();
+        NeutronRouter singleton = input.getSingleton();
+        NeutronRouter original = routerInterface.getRouter(routerUUID);
+
+        /*
+         * attribute changes blocked by Neutron
+         */
+        if (singleton.getID() != null || singleton.getTenantID() != null ||
+                singleton.getStatus() != null)
+            return Response.status(400).build();
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                int status = service.canUpdateRouter(singleton, original);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        /*
+         * if the external gateway info is being changed, verify that the new network
+         * exists and has been designated as an external network
+         */
+        if (singleton.getExternalGatewayInfo() != null) {
+            String externNetworkPtr = singleton.getExternalGatewayInfo().getNetworkID();
+            if (!networkInterface.networkExists(externNetworkPtr))
+                return Response.status(400).build();
+            NeutronNetwork externNetwork = networkInterface.getNetwork(externNetworkPtr);
+            if (!externNetwork.isRouterExternal())
+                return Response.status(400).build();
+        }
+
+        /*
+         * update the router entry and return the modified object
+         */
+        routerInterface.updateRouter(routerUUID, singleton);
+        NeutronRouter updatedRouter = routerInterface.getRouter(routerUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.neutronRouterUpdated(updatedRouter);
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronRouterRequest(routerInterface.getRouter(routerUUID))).build();
+
+    }
+
+    /**
+     * Deletes a Router */
+
+    @Path("{routerUUID}")
+    @DELETE
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "No Content"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response deleteRouter(
+            @PathParam("routerUUID") String routerUUID) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify that the router exists and is not in use before removing it
+         */
+        if (!routerInterface.routerExists(routerUUID))
+            return Response.status(404).build();
+        if (routerInterface.routerInUse(routerUUID))
+            return Response.status(409).build();
+        NeutronRouter singleton = routerInterface.getRouter(routerUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                int status = service.canDeleteRouter(singleton);
+                if (status < 200 || status > 299)
+                    return Response.status(status).build();
+            }
+        }
+        routerInterface.removeRouter(routerUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.neutronRouterDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+
+    /**
+     * Adds an interface to a router */
+
+    @Path("{routerUUID}/add_router_interface")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouterInterfaces.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response addRouterInterface(
+            @PathParam("routerUUID") String routerUUID,
+            NeutronRouter_Interface input
+            ) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         *  While the Neutron specification says that the router has to exist and the input can only specify either a subnet id
+         *  or a port id, but not both, this code assumes that the plugin has filled everything in for us and so both must be present
+         */
+        if (!routerInterface.routerExists(routerUUID))
+            return Response.status(400).build();
+        NeutronRouter target = routerInterface.getRouter(routerUUID);
+        if (input.getSubnetUUID() == null ||
+                    input.getPortUUID() == null)
+                return Response.status(400).build();
+
+        // check that the port is part of the subnet
+        NeutronSubnet targetSubnet = subnetInterface.getSubnet(input.getSubnetUUID());
+        if (targetSubnet == null)
+            return Response.status(400).build();
+        NeutronPort targetPort = portInterface.getPort(input.getPortUUID());
+        if (targetPort == null)
+            return Response.status(400).build();
+        if (!targetSubnet.getPortsInSubnet().contains(targetPort))
+            return Response.status(400).build();
+
+        if (targetPort.getFixedIPs().size() != 1)
+            return Response.status(400).build();
+        if (targetPort.getDeviceID() != null ||
+                targetPort.getDeviceOwner() != null)
+            return Response.status(409).build();
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.canAttachInterface(target, input);
+            }
+        }
+
+        //mark the port device id and device owner fields
+        targetPort.setDeviceOwner("network:router_interface");
+        targetPort.setDeviceID(routerUUID);
+
+        target.addInterface(input.getPortUUID(), input);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.neutronRouterInterfaceAttached(target, input);
+            }
+        }
+
+        return Response.status(200).entity(input).build();
+    }
+
+    /**
+     * Removes an interface to a router */
+
+    @Path("{routerUUID}/remove_router_interface")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackRouterInterfaces.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response removeRouterInterface(
+            @PathParam("routerUUID") String routerUUID,
+            NeutronRouter_Interface input
+            ) {
+        INeutronRouterCRUD routerInterface = NeutronCRUDInterfaces.getINeutronRouterCRUD(this);
+        if (routerInterface == null) {
+            throw new ServiceUnavailableException("Router CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronPortCRUD portInterface = NeutronCRUDInterfaces.getINeutronPortCRUD(this);
+        if (portInterface == null) {
+            throw new ServiceUnavailableException("Port CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        // verify the router exists
+        if (!routerInterface.routerExists(routerUUID))
+            return Response.status(400).build();
+        NeutronRouter target = routerInterface.getRouter(routerUUID);
+
+        /*
+         * remove by subnet id.  Collect information about the impacted router for the response and
+         * remove the port corresponding to the gateway IP address of the subnet
+         */
+        if (input.getPortUUID() == null &&
+                input.getSubnetUUID() != null) {
+            NeutronPort port = portInterface.getGatewayPort(input.getSubnetUUID());
+            if (port == null)
+                return Response.status(404).build();
+            input.setPortUUID(port.getID());
+            input.setID(target.getID());
+            input.setTenantID(target.getTenantID());
+
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronRouterAware service = (INeutronRouterAware) instance;
+                    service.canDetachInterface(target, input);
+                }
+            }
+
+            // reset the port ownership
+            port.setDeviceID(null);
+            port.setDeviceOwner(null);
+
+            target.removeInterface(input.getPortUUID());
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronRouterAware service = (INeutronRouterAware) instance;
+                    service.neutronRouterInterfaceDetached(target, input);
+                }
+            }
+            return Response.status(200).entity(input).build();
+        }
+
+        /*
+         * remove by port id. collect information about the impacted router for the response
+         * remove the interface and reset the port ownership
+         */
+        if (input.getPortUUID() != null &&
+                input.getSubnetUUID() == null) {
+            NeutronRouter_Interface targetInterface = target.getInterfaces().get(input.getPortUUID());
+            input.setSubnetUUID(targetInterface.getSubnetUUID());
+            input.setID(target.getID());
+            input.setTenantID(target.getTenantID());
+            NeutronPort port = portInterface.getPort(input.getPortUUID());
+            port.setDeviceID(null);
+            port.setDeviceOwner(null);
+            target.removeInterface(input.getPortUUID());
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.neutronRouterInterfaceDetached(target, input);
+            }
+            return Response.status(200).entity(input).build();
+        }
+
+        /*
+         * remove by both port and subnet ID.  Verify that the first fixed IP of the port is a valid
+         * IP address for the subnet, and then remove the interface, collecting information about the
+         * impacted router for the response and reset port ownership
+         */
+        if (input.getPortUUID() != null &&
+                input.getSubnetUUID() != null) {
+            NeutronPort port = portInterface.getPort(input.getPortUUID());
+            NeutronSubnet subnet = subnetInterface.getSubnet(input.getSubnetUUID());
+            if (!subnet.isValidIP(port.getFixedIPs().get(0).getIpAddress()))
+                return Response.status(409).build();
+            input.setID(target.getID());
+            input.setTenantID(target.getTenantID());
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronRouterAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronRouterAware service = (INeutronRouterAware) instance;
+                    service.canDetachInterface(target, input);
+                }
+            }
+            port.setDeviceID(null);
+            port.setDeviceOwner(null);
+            target.removeInterface(input.getPortUUID());
+            for (Object instance : instances) {
+                INeutronRouterAware service = (INeutronRouterAware) instance;
+                service.neutronRouterInterfaceDetached(target, input);
+            }
+            return Response.status(200).entity(input).build();
+        }
+
+        // have to specify either a port ID or a subnet ID
+        return Response.status(400).build();
+    }
+}
index ab91399879e97ebc97fc0b44dbf318e0eb2c6784..aed9db58bd34c3255c54830c8b76957da6d4de5c 100644 (file)
@@ -1,56 +1,56 @@
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-import java.util.List;\r
-\r
-import javax.xml.bind.annotation.XmlAccessType;\r
-import javax.xml.bind.annotation.XmlAccessorType;\r
-import javax.xml.bind.annotation.XmlElement;\r
-import javax.xml.bind.annotation.XmlRootElement;\r
-\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-\r
-@XmlRootElement\r
-@XmlAccessorType(XmlAccessType.NONE)\r
-\r
-public class NeutronSubnetRequest {\r
-    // See OpenStack Network API v2.0 Reference for description of\r
-    // annotated attributes\r
-\r
-    @XmlElement(name="subnet")\r
-    NeutronSubnet singletonSubnet;\r
-\r
-    @XmlElement(name="subnets")\r
-    List<NeutronSubnet> bulkRequest;\r
-\r
-    NeutronSubnetRequest() {\r
-    }\r
-\r
-    NeutronSubnetRequest(List<NeutronSubnet> bulk) {\r
-        bulkRequest = bulk;\r
-        singletonSubnet = null;\r
-    }\r
-\r
-    NeutronSubnetRequest(NeutronSubnet subnet) {\r
-        singletonSubnet = subnet;\r
-    }\r
-\r
-    public NeutronSubnet getSingleton() {\r
-        return singletonSubnet;\r
-    }\r
-\r
-    public List<NeutronSubnet> getBulk() {\r
-        return bulkRequest;\r
-    }\r
-\r
-    public boolean isSingleton() {\r
-        return (singletonSubnet != null);\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class NeutronSubnetRequest {
+    // See OpenStack Network API v2.0 Reference for description of
+    // annotated attributes
+
+    @XmlElement(name="subnet")
+    NeutronSubnet singletonSubnet;
+
+    @XmlElement(name="subnets")
+    List<NeutronSubnet> bulkRequest;
+
+    NeutronSubnetRequest() {
+    }
+
+    NeutronSubnetRequest(List<NeutronSubnet> bulk) {
+        bulkRequest = bulk;
+        singletonSubnet = null;
+    }
+
+    NeutronSubnetRequest(NeutronSubnet subnet) {
+        singletonSubnet = subnet;
+    }
+
+    public NeutronSubnet getSingleton() {
+        return singletonSubnet;
+    }
+
+    public List<NeutronSubnet> getBulk() {
+        return bulkRequest;
+    }
+
+    public boolean isSingleton() {
+        return (singletonSubnet != null);
+    }
+}
index 699aee9fc3a7d3503e7b1a6d464926da1aefd24f..dffac55c5030ac96da1b52bde366f009cbb4a63d 100644 (file)
-/*\r
- * Copyright IBM Corporation, 2013.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.controller.networkconfig.neutron.northbound;\r
-\r
-\r
-import java.util.ArrayList;\r
-import java.util.HashMap;\r
-import java.util.Iterator;\r
-import java.util.List;\r
-import javax.ws.rs.Consumes;\r
-import javax.ws.rs.DELETE;\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.POST;\r
-import javax.ws.rs.PUT;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.PathParam;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.QueryParam;\r
-import javax.ws.rs.core.MediaType;\r
-import javax.ws.rs.core.Response;\r
-\r
-import org.codehaus.enunciate.jaxrs.ResponseCode;\r
-import org.codehaus.enunciate.jaxrs.StatusCodes;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;\r
-import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;\r
-import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;\r
-import org.opendaylight.controller.northbound.commons.RestMessages;\r
-import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;\r
-import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;\r
-import org.opendaylight.controller.sal.utils.ServiceHelper;\r
-\r
-/**\r
- * Open DOVE Northbound REST APIs.<br>\r
- * This class provides REST APIs for managing open DOVE internals related to Subnets\r
- *\r
- * <br>\r
- * <br>\r
- * Authentication scheme : <b>HTTP Basic</b><br>\r
- * Authentication realm : <b>opendaylight</b><br>\r
- * Transport : <b>HTTP and HTTPS</b><br>\r
- * <br>\r
- * HTTPS Authentication is disabled by default. Administrator can enable it in\r
- * tomcat-server.xml after adding a proper keystore / SSL certificate from a\r
- * trusted authority.<br>\r
- * More info :\r
- * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration\r
- *\r
- */\r
-\r
-@Path("/subnets")\r
-public class NeutronSubnetsNorthbound {\r
-\r
-    private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {\r
-        return o.extractFields(fields);\r
-    }\r
-\r
-\r
-    /**\r
-     * Returns a list of all Subnets */\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackSubnets.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response listSubnets(\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields,\r
-            // note: openstack isn't clear about filtering on lists, so we aren't handling them\r
-            @QueryParam("id") String queryID,\r
-            @QueryParam("network_id") String queryNetworkID,\r
-            @QueryParam("name") String queryName,\r
-            @QueryParam("ip_version") String queryIPVersion,\r
-            @QueryParam("cidr") String queryCIDR,\r
-            @QueryParam("gateway_ip") String queryGatewayIP,\r
-            @QueryParam("enable_dhcp") String queryEnableDHCP,\r
-            @QueryParam("tenant_id") String queryTenantID,\r
-            // pagination\r
-            @QueryParam("limit") String limit,\r
-            @QueryParam("marker") String marker,\r
-            @QueryParam("page_reverse") String pageReverse\r
-            // sorting not supported\r
-            ) {\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();\r
-        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();\r
-        Iterator<NeutronSubnet> i = allNetworks.iterator();\r
-        while (i.hasNext()) {\r
-            NeutronSubnet oSS = i.next();\r
-            if ((queryID == null || queryID.equals(oSS.getID())) &&\r
-                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&\r
-                    (queryName == null || queryName.equals(oSS.getName())) &&\r
-                    (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&\r
-                    (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&\r
-                    (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&\r
-                    (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&\r
-                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {\r
-                if (fields.size() > 0) {\r
-                    ans.add(extractFields(oSS,fields));\r
-                } else {\r
-                    ans.add(oSS);\r
-                }\r
-            }\r
-        }\r
-        //TODO: apply pagination to results\r
-        return Response.status(200).entity(\r
-                new NeutronSubnetRequest(ans)).build();\r
-    }\r
-\r
-    /**\r
-     * Returns a specific Subnet */\r
-\r
-    @Path("{subnetUUID}")\r
-    @GET\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackSubnets.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response showSubnet(\r
-            @PathParam("subnetUUID") String subnetUUID,\r
-            // return fields\r
-            @QueryParam("fields") List<String> fields) {\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (!subnetInterface.subnetExists(subnetUUID)) {\r
-            return Response.status(404).build();\r
-        }\r
-        if (fields.size() > 0) {\r
-            NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);\r
-            return Response.status(200).entity(\r
-                    new NeutronSubnetRequest(extractFields(ans, fields))).build();\r
-        } else {\r
-            return Response.status(200).entity(\r
-                    new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Creates new Subnets */\r
-\r
-    @POST\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackSubnets.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 201, condition = "Created"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response createSubnets(final NeutronSubnetRequest input) {\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);\r
-        if (networkInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-        if (input.isSingleton()) {\r
-            NeutronSubnet singleton = input.getSingleton();\r
-\r
-            /*\r
-             *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
-             *  the specified network exists, the subnet has a valid network address,\r
-             *  and that the gateway IP doesn't overlap with the allocation pools\r
-             *  *then* add the subnet to the cache\r
-             */\r
-            if (subnetInterface.subnetExists(singleton.getID())) {\r
-                return Response.status(400).build();\r
-            }\r
-            if (!networkInterface.networkExists(singleton.getNetworkUUID())) {\r
-                return Response.status(404).build();\r
-            }\r
-            if (!singleton.isValidCIDR()) {\r
-                return Response.status(400).build();\r
-            }\r
-            if (!singleton.initDefaults()) {\r
-                throw new InternalServerErrorException("subnet object could not be initialized properly");\r
-            }\r
-            if (singleton.gatewayIP_Pool_overlap()) {\r
-                return Response.status(409).build();\r
-            }\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                    int status = service.canCreateSubnet(singleton);\r
-                    if (status < 200 || status > 299) {\r
-                        return Response.status(status).build();\r
-                    }\r
-                }\r
-            }\r
-            subnetInterface.addSubnet(singleton);\r
-            if (instances != null) {\r
-                for (Object instance : instances) {\r
-                    INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                    service.neutronSubnetCreated(singleton);\r
-                }\r
-            }\r
-        } else {\r
-            List<NeutronSubnet> bulk = input.getBulk();\r
-            Iterator<NeutronSubnet> i = bulk.iterator();\r
-            HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();\r
-            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
-            while (i.hasNext()) {\r
-                NeutronSubnet test = i.next();\r
-\r
-                /*\r
-                 *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)\r
-                 *  the specified network exists, the subnet has a valid network address,\r
-                 *  and that the gateway IP doesn't overlap with the allocation pools,\r
-                 *  and that the bulk request doesn't already contain a subnet with this id\r
-                 */\r
-\r
-                if (!test.initDefaults()) {\r
-                    throw new InternalServerErrorException("subnet object could not be initialized properly");\r
-                }\r
-                if (subnetInterface.subnetExists(test.getID())) {\r
-                    return Response.status(400).build();\r
-                }\r
-                if (testMap.containsKey(test.getID())) {\r
-                    return Response.status(400).build();\r
-                }\r
-                testMap.put(test.getID(), test);\r
-                if (!networkInterface.networkExists(test.getNetworkUUID())) {\r
-                    return Response.status(404).build();\r
-                }\r
-                if (!test.isValidCIDR()) {\r
-                    return Response.status(400).build();\r
-                }\r
-                if (test.gatewayIP_Pool_overlap()) {\r
-                    return Response.status(409).build();\r
-                }\r
-                if (instances != null) {\r
-                    for (Object instance : instances) {\r
-                        INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                        int status = service.canCreateSubnet(test);\r
-                        if (status < 200 || status > 299) {\r
-                            return Response.status(status).build();\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-\r
-            /*\r
-             * now, each element of the bulk request can be added to the cache\r
-             */\r
-            i = bulk.iterator();\r
-            while (i.hasNext()) {\r
-                NeutronSubnet test = i.next();\r
-                subnetInterface.addSubnet(test);\r
-                if (instances != null) {\r
-                    for (Object instance : instances) {\r
-                        INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                        service.neutronSubnetCreated(test);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return Response.status(201).entity(input).build();\r
-    }\r
-\r
-    /**\r
-     * Updates a Subnet */\r
-\r
-    @Path("{subnetUUID}")\r
-    @PUT\r
-    @Produces({ MediaType.APPLICATION_JSON })\r
-    @Consumes({ MediaType.APPLICATION_JSON })\r
-    //@TypeHint(OpenStackSubnets.class)\r
-    @StatusCodes({\r
-            @ResponseCode(code = 200, condition = "Operation successful"),\r
-            @ResponseCode(code = 400, condition = "Bad Request"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 403, condition = "Forbidden"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response updateSubnet(\r
-            @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input\r
-            ) {\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Subnet CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * verify the subnet exists and there is only one delta provided\r
-         */\r
-        if (!subnetInterface.subnetExists(subnetUUID)) {\r
-            return Response.status(404).build();\r
-        }\r
-        if (!input.isSingleton()) {\r
-            return Response.status(400).build();\r
-        }\r
-        NeutronSubnet delta = input.getSingleton();\r
-        NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);\r
-\r
-        /*\r
-         * updates restricted by Neutron\r
-         */\r
-        if (delta.getID() != null || delta.getTenantID() != null ||\r
-                delta.getIpVersion() != null || delta.getCidr() != null ||\r
-                delta.getAllocationPools() != null) {\r
-            return Response.status(400).build();\r
-        }\r
-\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                int status = service.canUpdateSubnet(delta, original);\r
-                if (status < 200 || status > 299) {\r
-                    return Response.status(status).build();\r
-                }\r
-            }\r
-        }\r
-\r
-        /*\r
-         * update the object and return it\r
-         */\r
-        subnetInterface.updateSubnet(subnetUUID, delta);\r
-        NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                service.neutronSubnetUpdated(updatedSubnet);\r
-            }\r
-        }\r
-        return Response.status(200).entity(\r
-                new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();\r
-    }\r
-\r
-    /**\r
-     * Deletes a Subnet */\r
-\r
-    @Path("{subnetUUID}")\r
-    @DELETE\r
-    @StatusCodes({\r
-            @ResponseCode(code = 204, condition = "No Content"),\r
-            @ResponseCode(code = 401, condition = "Unauthorized"),\r
-            @ResponseCode(code = 404, condition = "Not Found"),\r
-            @ResponseCode(code = 409, condition = "Conflict"),\r
-            @ResponseCode(code = 501, condition = "Not Implemented") })\r
-    public Response deleteSubnet(\r
-            @PathParam("subnetUUID") String subnetUUID) {\r
-        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);\r
-        if (subnetInterface == null) {\r
-            throw new ServiceUnavailableException("Network CRUD Interface "\r
-                    + RestMessages.SERVICEUNAVAILABLE.toString());\r
-        }\r
-\r
-        /*\r
-         * verify the subnet exists and it isn't currently in use\r
-         */\r
-        if (!subnetInterface.subnetExists(subnetUUID)) {\r
-            return Response.status(404).build();\r
-        }\r
-        if (subnetInterface.subnetInUse(subnetUUID)) {\r
-            return Response.status(409).build();\r
-        }\r
-        NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);\r
-        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                int status = service.canDeleteSubnet(singleton);\r
-                if (status < 200 || status > 299) {\r
-                    return Response.status(status).build();\r
-                }\r
-            }\r
-        }\r
-\r
-        /*\r
-         * remove it and return 204 status\r
-         */\r
-        subnetInterface.removeSubnet(subnetUUID);\r
-        if (instances != null) {\r
-            for (Object instance : instances) {\r
-                INeutronSubnetAware service = (INeutronSubnetAware) instance;\r
-                service.neutronSubnetDeleted(singleton);\r
-            }\r
-        }\r
-        return Response.status(204).build();\r
-    }\r
-}\r
+/*
+ * Copyright IBM Corporation, 2013.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.networkconfig.neutron.northbound;
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.codehaus.enunciate.jaxrs.ResponseCode;
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronCRUDInterfaces;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
+import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
+import org.opendaylight.controller.northbound.commons.exception.ServiceUnavailableException;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+/**
+ * Open DOVE Northbound REST APIs.<br>
+ * This class provides REST APIs for managing open DOVE internals related to Subnets
+ *
+ * <br>
+ * <br>
+ * Authentication scheme : <b>HTTP Basic</b><br>
+ * Authentication realm : <b>opendaylight</b><br>
+ * Transport : <b>HTTP and HTTPS</b><br>
+ * <br>
+ * HTTPS Authentication is disabled by default. Administrator can enable it in
+ * tomcat-server.xml after adding a proper keystore / SSL certificate from a
+ * trusted authority.<br>
+ * More info :
+ * http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html#Configuration
+ *
+ */
+
+@Path("/subnets")
+public class NeutronSubnetsNorthbound {
+
+    private NeutronSubnet extractFields(NeutronSubnet o, List<String> fields) {
+        return o.extractFields(fields);
+    }
+
+
+    /**
+     * Returns a list of all Subnets */
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackSubnets.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response listSubnets(
+            // return fields
+            @QueryParam("fields") List<String> fields,
+            // note: openstack isn't clear about filtering on lists, so we aren't handling them
+            @QueryParam("id") String queryID,
+            @QueryParam("network_id") String queryNetworkID,
+            @QueryParam("name") String queryName,
+            @QueryParam("ip_version") String queryIPVersion,
+            @QueryParam("cidr") String queryCIDR,
+            @QueryParam("gateway_ip") String queryGatewayIP,
+            @QueryParam("enable_dhcp") String queryEnableDHCP,
+            @QueryParam("tenant_id") String queryTenantID,
+            // pagination
+            @QueryParam("limit") String limit,
+            @QueryParam("marker") String marker,
+            @QueryParam("page_reverse") String pageReverse
+            // sorting not supported
+            ) {
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        List<NeutronSubnet> allNetworks = subnetInterface.getAllSubnets();
+        List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
+        Iterator<NeutronSubnet> i = allNetworks.iterator();
+        while (i.hasNext()) {
+            NeutronSubnet oSS = i.next();
+            if ((queryID == null || queryID.equals(oSS.getID())) &&
+                    (queryNetworkID == null || queryNetworkID.equals(oSS.getNetworkUUID())) &&
+                    (queryName == null || queryName.equals(oSS.getName())) &&
+                    (queryIPVersion == null || queryIPVersion.equals(oSS.getIpVersion())) &&
+                    (queryCIDR == null || queryCIDR.equals(oSS.getCidr())) &&
+                    (queryGatewayIP == null || queryGatewayIP.equals(oSS.getGatewayIP())) &&
+                    (queryEnableDHCP == null || queryEnableDHCP.equals(oSS.getEnableDHCP())) &&
+                    (queryTenantID == null || queryTenantID.equals(oSS.getTenantID()))) {
+                if (fields.size() > 0) {
+                    ans.add(extractFields(oSS,fields));
+                } else {
+                    ans.add(oSS);
+                }
+            }
+        }
+        //TODO: apply pagination to results
+        return Response.status(200).entity(
+                new NeutronSubnetRequest(ans)).build();
+    }
+
+    /**
+     * Returns a specific Subnet */
+
+    @Path("{subnetUUID}")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackSubnets.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response showSubnet(
+            @PathParam("subnetUUID") String subnetUUID,
+            // return fields
+            @QueryParam("fields") List<String> fields) {
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (!subnetInterface.subnetExists(subnetUUID)) {
+            return Response.status(404).build();
+        }
+        if (fields.size() > 0) {
+            NeutronSubnet ans = subnetInterface.getSubnet(subnetUUID);
+            return Response.status(200).entity(
+                    new NeutronSubnetRequest(extractFields(ans, fields))).build();
+        } else {
+            return Response.status(200).entity(
+                    new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+        }
+    }
+
+    /**
+     * Creates new Subnets */
+
+    @POST
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackSubnets.class)
+    @StatusCodes({
+            @ResponseCode(code = 201, condition = "Created"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response createSubnets(final NeutronSubnetRequest input) {
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD(this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        INeutronNetworkCRUD networkInterface = NeutronCRUDInterfaces.getINeutronNetworkCRUD( this);
+        if (networkInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+        if (input.isSingleton()) {
+            NeutronSubnet singleton = input.getSingleton();
+
+            /*
+             *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+             *  the specified network exists, the subnet has a valid network address,
+             *  and that the gateway IP doesn't overlap with the allocation pools
+             *  *then* add the subnet to the cache
+             */
+            if (subnetInterface.subnetExists(singleton.getID())) {
+                return Response.status(400).build();
+            }
+            if (!networkInterface.networkExists(singleton.getNetworkUUID())) {
+                return Response.status(404).build();
+            }
+            if (!singleton.isValidCIDR()) {
+                return Response.status(400).build();
+            }
+            if (!singleton.initDefaults()) {
+                throw new InternalServerErrorException("subnet object could not be initialized properly");
+            }
+            if (singleton.gatewayIP_Pool_overlap()) {
+                return Response.status(409).build();
+            }
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                    int status = service.canCreateSubnet(singleton);
+                    if (status < 200 || status > 299) {
+                        return Response.status(status).build();
+                    }
+                }
+            }
+            subnetInterface.addSubnet(singleton);
+            if (instances != null) {
+                for (Object instance : instances) {
+                    INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                    service.neutronSubnetCreated(singleton);
+                }
+            }
+        } else {
+            List<NeutronSubnet> bulk = input.getBulk();
+            Iterator<NeutronSubnet> i = bulk.iterator();
+            HashMap<String, NeutronSubnet> testMap = new HashMap<String, NeutronSubnet>();
+            Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+            while (i.hasNext()) {
+                NeutronSubnet test = i.next();
+
+                /*
+                 *  Verify that the subnet doesn't already exist (Issue: is a deeper check necessary?)
+                 *  the specified network exists, the subnet has a valid network address,
+                 *  and that the gateway IP doesn't overlap with the allocation pools,
+                 *  and that the bulk request doesn't already contain a subnet with this id
+                 */
+
+                if (!test.initDefaults()) {
+                    throw new InternalServerErrorException("subnet object could not be initialized properly");
+                }
+                if (subnetInterface.subnetExists(test.getID())) {
+                    return Response.status(400).build();
+                }
+                if (testMap.containsKey(test.getID())) {
+                    return Response.status(400).build();
+                }
+                testMap.put(test.getID(), test);
+                if (!networkInterface.networkExists(test.getNetworkUUID())) {
+                    return Response.status(404).build();
+                }
+                if (!test.isValidCIDR()) {
+                    return Response.status(400).build();
+                }
+                if (test.gatewayIP_Pool_overlap()) {
+                    return Response.status(409).build();
+                }
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                        int status = service.canCreateSubnet(test);
+                        if (status < 200 || status > 299) {
+                            return Response.status(status).build();
+                        }
+                    }
+                }
+            }
+
+            /*
+             * now, each element of the bulk request can be added to the cache
+             */
+            i = bulk.iterator();
+            while (i.hasNext()) {
+                NeutronSubnet test = i.next();
+                subnetInterface.addSubnet(test);
+                if (instances != null) {
+                    for (Object instance : instances) {
+                        INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                        service.neutronSubnetCreated(test);
+                    }
+                }
+            }
+        }
+        return Response.status(201).entity(input).build();
+    }
+
+    /**
+     * Updates a Subnet */
+
+    @Path("{subnetUUID}")
+    @PUT
+    @Produces({ MediaType.APPLICATION_JSON })
+    @Consumes({ MediaType.APPLICATION_JSON })
+    //@TypeHint(OpenStackSubnets.class)
+    @StatusCodes({
+            @ResponseCode(code = 200, condition = "Operation successful"),
+            @ResponseCode(code = 400, condition = "Bad Request"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 403, condition = "Forbidden"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response updateSubnet(
+            @PathParam("subnetUUID") String subnetUUID, final NeutronSubnetRequest input
+            ) {
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Subnet CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the subnet exists and there is only one delta provided
+         */
+        if (!subnetInterface.subnetExists(subnetUUID)) {
+            return Response.status(404).build();
+        }
+        if (!input.isSingleton()) {
+            return Response.status(400).build();
+        }
+        NeutronSubnet delta = input.getSingleton();
+        NeutronSubnet original = subnetInterface.getSubnet(subnetUUID);
+
+        /*
+         * updates restricted by Neutron
+         */
+        if (delta.getID() != null || delta.getTenantID() != null ||
+                delta.getIpVersion() != null || delta.getCidr() != null ||
+                delta.getAllocationPools() != null) {
+            return Response.status(400).build();
+        }
+
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                int status = service.canUpdateSubnet(delta, original);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * update the object and return it
+         */
+        subnetInterface.updateSubnet(subnetUUID, delta);
+        NeutronSubnet updatedSubnet = subnetInterface.getSubnet(subnetUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                service.neutronSubnetUpdated(updatedSubnet);
+            }
+        }
+        return Response.status(200).entity(
+                new NeutronSubnetRequest(subnetInterface.getSubnet(subnetUUID))).build();
+    }
+
+    /**
+     * Deletes a Subnet */
+
+    @Path("{subnetUUID}")
+    @DELETE
+    @StatusCodes({
+            @ResponseCode(code = 204, condition = "No Content"),
+            @ResponseCode(code = 401, condition = "Unauthorized"),
+            @ResponseCode(code = 404, condition = "Not Found"),
+            @ResponseCode(code = 409, condition = "Conflict"),
+            @ResponseCode(code = 501, condition = "Not Implemented") })
+    public Response deleteSubnet(
+            @PathParam("subnetUUID") String subnetUUID) {
+        INeutronSubnetCRUD subnetInterface = NeutronCRUDInterfaces.getINeutronSubnetCRUD( this);
+        if (subnetInterface == null) {
+            throw new ServiceUnavailableException("Network CRUD Interface "
+                    + RestMessages.SERVICEUNAVAILABLE.toString());
+        }
+
+        /*
+         * verify the subnet exists and it isn't currently in use
+         */
+        if (!subnetInterface.subnetExists(subnetUUID)) {
+            return Response.status(404).build();
+        }
+        if (subnetInterface.subnetInUse(subnetUUID)) {
+            return Response.status(409).build();
+        }
+        NeutronSubnet singleton = subnetInterface.getSubnet(subnetUUID);
+        Object[] instances = ServiceHelper.getGlobalInstances(INeutronSubnetAware.class, this, null);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                int status = service.canDeleteSubnet(singleton);
+                if (status < 200 || status > 299) {
+                    return Response.status(status).build();
+                }
+            }
+        }
+
+        /*
+         * remove it and return 204 status
+         */
+        subnetInterface.removeSubnet(subnetUUID);
+        if (instances != null) {
+            for (Object instance : instances) {
+                INeutronSubnetAware service = (INeutronSubnetAware) instance;
+                service.neutronSubnetDeleted(singleton);
+            }
+        }
+        return Response.status(204).build();
+    }
+}
index da7735d4c59a9c086f5ec688612999c28a71b8fa..9041004605dded75ce2fe44f129c617656ab6e60 100644 (file)
@@ -132,12 +132,17 @@ public class MessageReadWriteService implements IMessageReadWrite {
             throw new AsynchronousCloseException();
         }
 
-        inBuffer.flip();
-        msgs = factory.parseMessages(inBuffer);
-        if (inBuffer.hasRemaining()) {
-            inBuffer.compact();
-        } else {
+        try {
+            inBuffer.flip();
+            msgs = factory.parseMessages(inBuffer);
+            if (inBuffer.hasRemaining()) {
+                inBuffer.compact();
+            } else {
+                inBuffer.clear();
+            }
+        } catch (Exception e) {
             inBuffer.clear();
+            logger.debug("Caught exception: ", e);
         }
         return msgs;
     }
index f0922d3658f946c474e48002874bf4a34295221a..90b47cf26421e6ff6a05c0e6ef21451c52173ac9 100644 (file)
@@ -282,12 +282,17 @@ public class SecureMessageReadWriteService implements IMessageReadWrite {
                     peerNetData.position(), peerNetData.limit());
         }
 
-        peerAppData.flip();
-        msgs = factory.parseMessages(peerAppData);
-        if (peerAppData.hasRemaining()) {
-            peerAppData.compact();
-        } else {
+        try {
+            peerAppData.flip();
+            msgs = factory.parseMessages(peerAppData);
+            if (peerAppData.hasRemaining()) {
+                peerAppData.compact();
+            } else {
+                peerAppData.clear();
+            }
+        } catch (Exception e) {
             peerAppData.clear();
+            logger.debug("Caught exception: ", e);
         }
 
         this.socket.register(this.selector, SelectionKey.OP_READ, this);
index 6e000022df12909e1f4facdcbcf4236d20d3fd69..6fddef06a8388a80a5278ce2f9a3234ae4461982 100644 (file)
@@ -359,8 +359,6 @@ public class SwitchHandler implements ISwitch {
         }
 
         if (msgs == null) {
-            logger.info("{} is down", this);
-            reportSwitchStateChange(false);
             return;
         }
         for (OFMessage msg : msgs) {
@@ -369,16 +367,15 @@ public class SwitchHandler implements ISwitch {
             OFType type = msg.getType();
             switch (type) {
             case HELLO:
-                // send feature request
-                OFMessage featureRequest = factory.getMessage(OFType.FEATURES_REQUEST);
-                asyncFastSend(featureRequest);
-                this.state = SwitchState.WAIT_FEATURES_REPLY;
-                startSwitchTimer();
+                sendFeaturesRequest();
                 break;
             case ECHO_REQUEST:
                 OFEchoReply echoReply = (OFEchoReply) factory.getMessage(OFType.ECHO_REPLY);
                 // respond immediately
                 asyncSendNow(echoReply, msg.getXid());
+
+                // send features request if not sent yet
+                sendFeaturesRequest();
                 break;
             case ECHO_REPLY:
                 this.probeSent = false;
@@ -507,6 +504,16 @@ public class SwitchHandler implements ISwitch {
         return this.sid;
     }
 
+    private void sendFeaturesRequest() {
+        if (!isOperational() && (this.state != SwitchState.WAIT_FEATURES_REPLY)) {
+            // send feature request
+            OFMessage featureRequest = factory.getMessage(OFType.FEATURES_REQUEST);
+            asyncFastSend(featureRequest);
+            this.state = SwitchState.WAIT_FEATURES_REPLY;
+            startSwitchTimer();
+        }
+    }
+
     private void processFeaturesReply(OFFeaturesReply reply) {
         if (this.state == SwitchState.WAIT_FEATURES_REPLY) {
             this.sid = reply.getDatapathId();
index 99482debd6d7e51c84415d3064ed38d05b5ca77e..4d2aea203601dafe6e19fcacc208ae4760819b0f 100644 (file)
@@ -111,6 +111,19 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     private boolean isDefaultContainer = true;
     private static final int REPLACE_RETRY = 1;
 
+    /* Information about the default subnet. If there have been no configured subnets, i.e.,
+     * subnets.size() == 0 or subnetsConfigList.size() == 0, then this subnet will be the
+     * only subnet returned. As soon as a user-configured subnet is created this one will
+     * vanish.
+     */
+    protected static SubnetConfig DEFAULT_SUBNETCONFIG;
+    protected static Subnet DEFAULT_SUBNET;
+    protected static String DEFAULT_SUBNET_NAME = "default (cannot be modifed)";
+    static{
+        DEFAULT_SUBNETCONFIG = new SubnetConfig(DEFAULT_SUBNET_NAME, "0.0.0.0/0", new ArrayList<String>());
+        DEFAULT_SUBNET = new Subnet(DEFAULT_SUBNETCONFIG);
+    }
+
     public void notifySubnetChange(Subnet sub, boolean add) {
         synchronized (switchManagerAware) {
             for (Object subAware : switchManagerAware) {
@@ -295,12 +308,22 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
 
     @Override
     public List<SubnetConfig> getSubnetsConfigList() {
-        return new ArrayList<SubnetConfig>(subnetsConfigList.values());
+        // if there are no subnets, return the default subnet
+        if(subnetsConfigList.size() == 0){
+            return Collections.singletonList(DEFAULT_SUBNETCONFIG);
+        }else{
+            return new ArrayList<SubnetConfig>(subnetsConfigList.values());
+        }
     }
 
     @Override
     public SubnetConfig getSubnetConfig(String subnet) {
-        return subnetsConfigList.get(subnet);
+        // if there are no subnets, return the default subnet
+        if(subnetsConfigList.size() == 0 && subnet == DEFAULT_SUBNET_NAME){
+            return DEFAULT_SUBNETCONFIG;
+        }else{
+            return subnetsConfigList.get(subnet);
+        }
     }
 
     private List<SpanConfig> getSpanConfigList(Node node) {
@@ -646,6 +669,11 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
 
     @Override
     public Subnet getSubnetByNetworkAddress(InetAddress networkAddress) {
+        // if there are no subnets, return the default subnet
+        if (subnets.size() == 0) {
+            return DEFAULT_SUBNET;
+        }
+
         Subnet sub;
         Set<InetAddress> indices = subnets.keySet();
         for (InetAddress i : indices) {