Merge "Added explicit revision date import of ietf-inet-types to opendaylight-statist...
authorEd Warnicke <eaw@cisco.com>
Thu, 27 Mar 2014 16:09:12 +0000 (16:09 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 27 Mar 2014 16:09:12 +0000 (16:09 +0000)
170 files changed:
.gitignore
opendaylight/archetypes/odl-model-project/pom.xml
opendaylight/archetypes/odl-model-project/src/main/resources/archetype-resources/pom.xml
opendaylight/archetypes/pom.xml
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/Activator.java
opendaylight/arphandler/src/main/java/org/opendaylight/controller/arphandler/internal/ArpHandler.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterGlobalManager.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManagerCommon.java
opendaylight/commons/checkstyle/pom.xml
opendaylight/commons/opendaylight/pom.xml
opendaylight/commons/parent/pom.xml
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java [deleted file]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java [new file with mode: 0644]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java [deleted file]
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java
opendaylight/config/pom.xml
opendaylight/config/yang-store-api/pom.xml [deleted file]
opendaylight/config/yang-store-impl/.gitignore [deleted file]
opendaylight/config/yang-store-impl/pom.xml [deleted file]
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java [deleted file]
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java [deleted file]
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java [deleted file]
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java [deleted file]
opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java [deleted file]
opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java [deleted file]
opendaylight/config/yang-test/pom.xml
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java
opendaylight/md-sal/clustered-data-store/implementation/pom.xml
opendaylight/md-sal/clustered-data-store/integrationtest/pom.xml
opendaylight/md-sal/inventory-manager/pom.xml
opendaylight/md-sal/inventory-manager/src/main/java/org/opendaylight/controller/md/inventory/manager/InventoryMapping.xtend
opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang
opendaylight/md-sal/model/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-binding-api/pom.xml
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/BindingAwareBroker.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationListener.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationProviderService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/NotificationService.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcConsumerRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/RpcProviderRegistry.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/data/SynchronizedTransaction.java
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/sal/binding/api/rpc/RpcRouter.java
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/RpcProviderRegistryImpl.java
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/AbstractTest.java
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalConsumerInstance.java
opendaylight/md-sal/sal-binding-util/src/main/java/org/opendaylight/controller/md/sal/binding/util/AbstractBindingSalProviderInstance.java
opendaylight/md-sal/sal-common-api/pom.xml
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataCommitHandler.java
opendaylight/md-sal/sal-common-api/src/main/java/org/opendaylight/controller/md/sal/common/api/data/DataModification.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractDataModification.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractRegistration.java [deleted file]
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractRoutedRegistration.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataBroker.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/AbstractDataTransaction.java
opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/service/TwoPhaseCommit.java
opendaylight/md-sal/sal-dom-api/pom.xml
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/Broker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountInstance.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountProvisionService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/mount/MountService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationPublishService.java
opendaylight/md-sal/sal-dom-broker/pom.xml
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/NotificationModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/NotificationRouterImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/SchemaContextProvider.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/NotificationPublishServiceProxy.java
opendaylight/md-sal/sal-netconf-connector/pom.xml
opendaylight/md-sal/sal-remote/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/implementation/pom.xml
opendaylight/md-sal/sal-remoterpc-connector/integrationtest/test-it/pom.xml
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/restconf/impl/RestconfImpl.xtend
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/listeners/Notificator.java
opendaylight/md-sal/sal-rest-connector/src/main/java/org/opendaylight/controller/sal/streams/websockets/WebSocketServer.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/CnSnToXmlAndJsonInstanceIdentifierTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/MediaTypesTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestGetOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestPostOperationTest.java
opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/RestconfImplTest.java
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/impl/NotificationServiceImpl.java
opendaylight/md-sal/sal-restconf-broker/src/main/java/org/opendaylight/controller/sal/restconf/broker/transactions/RemoteDataModificationTransaction.java
opendaylight/md-sal/samples/toaster-consumer/pom.xml
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java
opendaylight/md-sal/samples/toaster-provider/pom.xml
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java
opendaylight/md-sal/samples/toaster/pom.xml
opendaylight/md-sal/statistics-manager/pom.xml
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/MultipartMessageManager.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsListener.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/md-sal/topology-manager/pom.xml
opendaylight/netconf/config-netconf-connector/pom.xml
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/get/Get.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/getconfig/GetConfig.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/Activator.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationProvider.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceFactoryImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImpl.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreException.java [moved from opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreException.java with 88% similarity]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreService.java [moved from opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreService.java with 89% similarity]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceImpl.java [new file with mode: 0644]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceTracker.java [deleted file]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshot.java [moved from opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java with 69% similarity]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreSnapshotImpl.java [moved from opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/MbeParser.java with 52% similarity]
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/util/Util.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/NetconfOperationServiceImplTest.java
opendaylight/netconf/netconf-impl/pom.xml
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-it/pom.xml
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/HardcodedYangStoreService.java [moved from opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/HardcodedYangStoreService.java with 54% similarity]
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfConfigPersisterITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITSecureTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfMonitoringITTest.java
opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/pax/IdentityRefNetconfTest.java
opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/threads/SocketThread.java
opendaylight/netconf/pom.xml
opendaylight/networkconfiguration/neutron/implementation/pom.xml
opendaylight/networkconfiguration/neutron/pom.xml
opendaylight/networkconfiguration/neutron/src/main/java/org/opendaylight/controller/networkconfig/neutron/NeutronSubnet_IPAllocationPool.java
opendaylight/northbound/archetype-app-northbound/pom.xml [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/main/resources/META-INF/maven/archetype-metadata.xml [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/pom.xml [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/java/Northbound.java [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/resources/WEB-INF/web.xml [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/archetype.properties [new file with mode: 0644]
opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/goal.txt [new file with mode: 0644]
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/NorthboundApplication.java
opendaylight/northbound/networkconfiguration/bridgedomain/src/main/java/org/opendaylight/controller/networkconfig/bridgedomain/northbound/BridgeDomainNorthbound.java
opendaylight/northbound/networkconfiguration/neutron/pom.xml
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/internal/DiscoveryService.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/topology/TopoEdgeUpdate.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java
opendaylight/sal/api/src/test/java/org/opendaylight/controller/sal/utils/NetUtilsTest.java
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/Activator.java
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleBroadcastHandlerImpl.java
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/Activator.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/ControllerProperties.java [new file with mode: 0644]
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/IControllerProperties.java [new file with mode: 0644]
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java
opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java
opendaylight/web/flows/src/main/resources/js/page.js
third-party/commons/thirdparty/pom.xml

index b079cba0a10d3a76e09c824bfeb8db16922756c7..175ab5f0a0c2eb35ffeff038ad72df428a93affc 100644 (file)
@@ -21,3 +21,5 @@ opendaylight/northbound/integrationtest/logs/*
 xtend-gen
 classes
 out/
+.externalToolBuilders
+maven-eclipse.xml
index 63759c63dd4c913178826e112a6ee97602dd2cc0..d2896027fb330edc255739d740847cd7fb10b00a 100644 (file)
@@ -7,6 +7,12 @@
   <version>1.1-SNAPSHOT</version>
   <packaging>maven-archetype</packaging>
 
+  <properties>
+    <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+    <nexus.repository.release>opendaylight.release</nexus.repository.release>
+    <nexus.repository.snapshot>opendaylight.snapshot</nexus.repository.snapshot>
+  </properties>
+
   <name>odl-model-project</name>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
   <distributionManagement>
     <repository>
       <id>opendaylight-release</id>
-      <url>http://nexus.opendaylight.org/content/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <site>
       <id>website</id>
index ebb9302b78487282f2e40c802429161809ea6c4b..016c30d787bde6a7871f012fb40d3df7c52c85b3 100644 (file)
@@ -9,6 +9,8 @@
   <properties>\r
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
     <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
+    <nexus.repository.release>opendaylight.release</nexus.repository.release>
+    <nexus.repository.snapshot>opendaylight.release</nexus.repository.snaphot>
     <yang.version>0.6.2-SNAPSHOT</yang.version>\r
     <yang.codegen.version>0.6.2-SNAPSHOT</yang.codegen.version>\r
     <bundle.plugin.version>2.3.7</bundle.plugin.version>\r
     <pluginRepository>\r
       <id>opendaylight-snapshot</id>\r
       <name>opendaylight-snapshot</name>\r
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
       <snapshots>\r
           <enabled>true</enabled>\r
       </snapshots>\r
     <repository>\r
       <id>opendaylight-snapshot</id>\r
       <name>opendaylight-snapshot</name>\r
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
       <snapshots>\r
           <enabled>true</enabled>\r
       </snapshots>\r
     <!-- OpenDayLight Released artifact -->\r
     <repository>\r
       <id>opendaylight-release</id>\r
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>\r
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>\r
     <!-- OpenDayLight Snapshot artifact -->\r
     <snapshotRepository>\r
       <id>opendaylight-snapshot</id>\r
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>\r
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>\r
     <!-- Site deployment -->\r
     <site>\r
index 7924ade6252795b803d1673c7a96c97e51e2d807..36af861e84826e109ed53e97fadee123b6056c18 100644 (file)
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
index b253179c87185d50834240f654a524409a0fa392..b7639bed2b2b41db2c5459cd0b8babe976b92bfb 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.controller.hosttracker.hostAware.IHostFinder;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.opendaylight.controller.sal.packet.IDataPacketService;
 import org.opendaylight.controller.sal.packet.IListenDataPacket;
-import org.opendaylight.controller.sal.routing.IRouting;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
 import org.slf4j.Logger;
@@ -44,6 +43,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { ArpHandler.class };
         return res;
@@ -62,6 +62,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * also optional per-container different behavior if needed, usually
      * should not be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(ArpHandler.class)) {
             // export the service
@@ -100,10 +101,6 @@ public class Activator extends ComponentActivatorAbstractBase {
                    "setClusterContainerService", "unsetClusterContainerService")
                    .setRequired(true));
 
-            c.add(createContainerServiceDependency(containerName).setService(
-                   IRouting.class).setCallbacks("setRouting","unsetRouting")
-                   .setRequired(false));
-
             // the Host Listener is optional
             c.add(createContainerServiceDependency(containerName).setService(
                     IfHostListener.class).setCallbacks("setHostListener",
index 8ae038c30f38bb38410b1c093c7a7a6b791ca507..083e2ed0e9784d31355ceaac1a995bde2c386278 100644 (file)
@@ -113,16 +113,6 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         }
     }
 
-    void setRouting(IRouting r) {
-        this.routing = r;
-    }
-
-    void unsetRouting(IRouting r) {
-        if (this.routing == r) {
-            this.routing = null;
-        }
-    }
-
     void setHostListener(IfHostListener s) {
         if (this.hostListeners != null) {
             this.hostListeners.add(s);
@@ -172,6 +162,12 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         byte[] targetIP = tIP.getAddress();
         ARP arp = createARP(ARP.REPLY, sMAC, senderIP, tMAC, targetIP);
 
+        if(log.isTraceEnabled()) {
+            log.trace("Sending Arp Reply with srcMac {} - srcIp {} - dstMac {} - dstIp {} - outport {}",
+                    HexEncode.bytesToHexString(sMAC),
+                    sIP, HexEncode.bytesToHexString(tMAC), tIP, p);
+        }
+
         Ethernet ethernet = createEthernet(sMAC, tMAC, arp);
 
         RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
@@ -180,8 +176,28 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         this.dataPacketService.transmitDataPacket(destPkt);
     }
 
+    private void logArpPacket(ARP pkt, NodeConnector p) {
+        try {
+            if (pkt.getOpCode() == ARP.REQUEST) {
+                log.trace("Received Arp Request with srcMac {} - srcIp {} - dstMac {} - dstIp {} - inport {}", HexEncode.bytesToHexString(pkt.getSenderHardwareAddress()),
+                        InetAddress.getByAddress(pkt.getSenderProtocolAddress()), HexEncode.bytesToHexString(pkt.getTargetHardwareAddress()),
+                        InetAddress.getByAddress(pkt.getTargetProtocolAddress()), p);
+            } else if(pkt.getOpCode() == ARP.REPLY) {
+                log.trace("Received Arp Reply with srcMac {} - srcIp {} - dstMac {} - dstIp {} - inport {}", HexEncode.bytesToHexString(pkt.getSenderHardwareAddress()),
+                        InetAddress.getByAddress(pkt.getSenderProtocolAddress()), HexEncode.bytesToHexString(pkt.getTargetHardwareAddress()),
+                        InetAddress.getByAddress(pkt.getTargetProtocolAddress()), p);
+            }
+        } catch(UnknownHostException e) {
+            log.warn("Illegal Ip Address in the ARP packet", e);
+        }
+    }
+
     protected void handleARPPacket(Ethernet eHeader, ARP pkt, NodeConnector p) {
 
+        if(log.isTraceEnabled()) {
+            logArpPacket(pkt, p);
+        }
+
         byte[] sourceMAC = eHeader.getSourceMACAddress();
         byte[] targetMAC = eHeader.getDestinationMACAddress();
         /*
@@ -357,6 +373,11 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
             byte[] targetIPByte = targetIP.getAddress();
             ARP arp = createARP(ARP.REQUEST, getControllerMAC(), senderIP, targetHardwareAddress, targetIPByte);
 
+            if(log.isTraceEnabled()) {
+                log.trace("Sending Broadcast Arp Request with srcMac {} - srcIp {} - dstMac {} - dstIp {} - outport {}", HexEncode.bytesToHexString(getControllerMAC()),
+                        subnet.getNetworkAddress(), HexEncode.bytesToHexString(targetHardwareAddress), targetIP, p);
+            }
+
             byte[] destMACAddress = NetUtils.getBroadcastMACAddr();
             Ethernet ethernet = createEthernet(getControllerMAC(), destMACAddress, arp);
 
@@ -387,6 +408,13 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
         byte[] targetMAC = host.getDataLayerAddressBytes();
         ARP arp = createARP(ARP.REQUEST, getControllerMAC(), senderIP, targetMAC, targetIP);
 
+        if(log.isTraceEnabled()) {
+            log.trace("Sending Unicast Arp Request with srcMac {} - srcIp {} - dstMac {} - dstIp {} - outport {}",
+                    HexEncode.bytesToHexString(getControllerMAC()),
+                    subnet.getNetworkAddress(), HexEncode.bytesToHexString(targetMAC), host.getNetworkAddress(),
+                    outPort);
+        }
+
         Ethernet ethernet = createEthernet(getControllerMAC(), targetMAC, arp);
 
         RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
@@ -469,41 +497,18 @@ public class ArpHandler implements IHostFinder, IListenDataPacket, ICacheUpdateA
 
         // see if we know about the host
         // Hosttracker hosts db key implementation
-        IHostId id = HostIdFactory.create(dIP, null);
-        HostNodeConnector host = hostTracker.hostFind(id);
+        HostNodeConnector host = hostTracker.hostFind(dIP);
 
         if (host == null) {
-            // if we don't, know about the host, try to find it
+            // if we don't know about the host, try to find it
             log.trace("Punted IP pkt to {}, sending bcast ARP event...", dIP);
             /*
              * unknown destination host, initiate bcast ARP request
              */
             arpRequestReplyEvent.put(new ARPRequest(dIP, subnet), false);
 
-        } else if (routing == null || routing.getRoute(p.getNode(), host.getnodeconnectorNode()) != null) {
-            /*
-             * if IRouting is available, make sure that this packet can get it's
-             * destination normally before teleporting it there. If it's not
-             * available, then assume it's reachable.
-             *
-             * TODO: come up with a way to do this in the absence of IRouting
-             */
-
-            log.trace("forwarding punted IP pkt to {} received at {}", dIP, p);
-
-            /*
-             * if we know where the host is and there's a path from where this
-             * packet was punted to where the host is, then deliver it to the
-             * host for now
-             */
-            NodeConnector nc = host.getnodeConnector();
-
-            // re-encode the Ethernet packet (the parent of the IPv4 packet)
-            RawPacket rp = this.dataPacketService.encodeDataPacket(pkt.getParent());
-            rp.setOutgoingNodeConnector(nc);
-            this.dataPacketService.transmitDataPacket(rp);
         } else {
-            log.trace("ignoring punted IP pkt to {} because there is no route from {}", dIP, p);
+            log.trace("Ignoring punted IP pkt to known host: {} (received on: {})", dIP, p);
         }
     }
 
index 34ddb7a207edcd5b262f2de09366fbc11c3dde62..e05f9dfe169555237e4b3469c917e5c09f11b882 100644 (file)
@@ -10,6 +10,7 @@
 package org.opendaylight.controller.clustering.services_implementation.internal;
 
 import java.util.Map;
+
 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.slf4j.Logger;
@@ -22,7 +23,7 @@ public class ClusterGlobalManager
 
     @Override
     void setCacheUpdateAware(Map props, ICacheUpdateAware s) {
-        logger.trace("setCacheUpdateAware");
+        logger.trace("setCacheUpdateAware: {}",s);
         if (props.get("containerName") != null) {
             // If we got a reference with the containerName property
             // that is not what we are looking for, so filter it out.
@@ -33,7 +34,7 @@ public class ClusterGlobalManager
 
     @Override
     void unsetCacheUpdateAware(Map props, ICacheUpdateAware s) {
-        logger.trace("unsetCacheUpdateAware");
+        logger.trace("unsetCacheUpdateAware: {}",s);
         if (props.get("containerName") != null) {
             // If we got a reference with the containerName property
             // that is not what we are looking for, so filter it out.
index 97d9ded6c86b864f06356ff026bd170cc6dbe4d5..06e5bc5b611c0480de04ff4bff814095804048bf 100644 (file)
@@ -58,6 +58,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon {
      * export the interface ICoordinatorChangeAware
      */
     class ListenCoordinatorChange implements IListenRoleChange {
+        @Override
         public void newActiveAvailable() {
             if (coordinatorChangeAware != null) {
                 // Make sure to look the set while walking it
@@ -93,13 +94,9 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon {
                 logger.trace("cachenames provided below:");
                 for (String cache : caches) {
                     if (this.cacheUpdateAware.get(cache) != null) {
-                        logger.error("cachename:{} on container:{} has " +
-                                     "already a listener", cache,
-                                     this.containerName);
+                        logger.error("cachename:{} on container:{} has already a listener", cache, this.containerName);
                     } else {
-                        GetUpdatesContainer<?, ?> up =
-                            new GetUpdatesContainer(s, this.containerName,
-                                                    cache);
+                        GetUpdatesContainer<?, ?> up = new GetUpdatesContainer(s, this.containerName, cache);
                         if (up != null) {
                             try {
                                 this.clusterService.addListener(this.containerName,
@@ -109,6 +106,7 @@ public abstract class ClusterManagerCommon implements IClusterServicesCommon {
                                              "been registered", cache,
                                              this.containerName);
                             } catch (CacheListenerAddException exc) {
+                                logger.debug("Cache {} didn't exist when {} tried to register to its updates", cache, s);
                                 // Do nothing, the important is that
                                 // we don't register the listener in
                                 // the shadow, and we are not doing
index 9f2bf9040e979e8294366f9220f2ced0d341d1d2..55567af43783a229118086be282c898b753f38fa 100644 (file)
 
   <properties>
     <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+    <nexus.repository.release>opendaylight.release</nexus.repository.release>
+    <nexus.repository.snapshot>opendaylight.snapshot</nexus.repository.snapshot>
     <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
   </properties>
   <distributionManagement>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
index 77c807b0ed936fa27361274591aeb749e034f141..e7c7bbe6370c1750d88d454c8faffdd4ac2eadae 100644 (file)
@@ -91,7 +91,7 @@
     <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
     <concepts.version>0.5.2-SNAPSHOT</concepts.version>
     <protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
-    <netty.version>4.0.10.Final</netty.version>
+    <netty.version>4.0.17.Final</netty.version>
     <commons.io.version>2.4</commons.io.version>
     <bundlescanner.version>0.4.2-SNAPSHOT</bundlescanner.version>
     <usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
           <artifactId>concepts</artifactId>
           <version>${concepts.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal-remoterpc-connector</artifactId>
+            <version>${mdsal.version}</version>
+        </dependency>
 
 
         <!-- config-->
           <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>
     <pluginRepository>
       <id>opendaylight-snapshot</id>
       <name>opendaylight-snapshot</name>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
       <snapshots>
           <enabled>true</enabled>
       </snapshots>
     <repository>
       <id>opendaylight-snapshot</id>
       <name>opendaylight-snapshot</name>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
       <snapshots>
           <enabled>true</enabled>
       </snapshots>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
index 085096d206b5aa8d13ebc4ff34f5b9a3eb0fef74..c81dba75de1064a561d536ba1ddc709c241d9a25 100644 (file)
@@ -16,7 +16,9 @@
   </scm>
 
   <properties>
-    <nexusdeploy>http://nexus.opendaylight.org/content</nexusdeploy>
+    <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+    <nexus.repository.release>opendaylight.release</nexus.repository.release>
+    <nexus.repository.snapshot>opendaylight.snapshot</nexus.repository.snapshot>
     <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
     <releaseplugin.version>2.3.2</releaseplugin.version>
   </properties>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusdeploy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusdeploy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BindingIndependentMappingServiceTracker.java
deleted file mode 100644 (file)
index dbc862a..0000000
+++ /dev/null
@@ -1,60 +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.manager.impl.osgi;
-
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class BindingIndependentMappingServiceTracker implements ServiceTrackerCustomizer<BindingIndependentMappingService, BindingIndependentMappingService> {
-    private static final Logger logger = LoggerFactory.getLogger(BindingIndependentMappingServiceTracker.class);
-
-    private final ConfigManagerActivator activator;
-    private final BundleContext ctx;
-    private BindingIndependentMappingService service;
-
-    public BindingIndependentMappingServiceTracker(BundleContext context, ConfigManagerActivator activator) {
-        this.ctx = context;
-        this.activator = activator;
-    }
-
-    @Override
-    public synchronized BindingIndependentMappingService addingService(
-            ServiceReference<BindingIndependentMappingService> moduleFactoryServiceReference) {
-
-        if (service != null) {
-            // FIXME
-            // Second registration appears from
-            // org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModule
-            logger.debug("BindingIndependentMappingService was already added as {}" + " now added as {}",
-                    service, ctx.getService(moduleFactoryServiceReference));
-            return null;
-        }
-
-        BindingIndependentMappingService service = ctx.getService(moduleFactoryServiceReference);
-        this.service = service;
-        CodecRegistry codecRegistry = service.getCodecRegistry();
-        logger.debug("Codec registry acquired {}", codecRegistry);
-//        activator.initConfigManager(ctx, codecRegistry);
-        return service;
-    }
-
-    @Override
-    public void modifiedService(ServiceReference <BindingIndependentMappingService> moduleFactoryServiceReference, BindingIndependentMappingService o) {
-        // TODO crash
-    }
-
-    @Override
-    public void removedService(ServiceReference<BindingIndependentMappingService> moduleFactoryServiceReference, BindingIndependentMappingService o) {
-        // TODO crash
-    }
-}
index 02cc5ea1e4a01681e9c6b2fe73b435c1a7699db4..308b137403fad9ec60b671813c752ebacf083629 100644 (file)
@@ -7,52 +7,52 @@
  */
 package org.opendaylight.controller.config.manager.impl.osgi;
 
-import java.lang.management.ManagementFactory;
-import java.util.Collection;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.MBeanServer;
-
 import org.opendaylight.controller.config.manager.impl.ConfigRegistryImpl;
 import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegistrator;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.CodecRegistryProvider;
 import org.opendaylight.controller.config.manager.impl.osgi.mapping.ModuleInfoBundleTracker;
-import org.opendaylight.controller.config.manager.impl.osgi.mapping.RuntimeGeneratedMappingServiceActivator;
+import org.opendaylight.controller.config.manager.impl.osgi.mapping.RefreshingSCPModuleInfoRegistry;
+import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
 import org.opendaylight.controller.config.spi.ModuleFactory;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
-import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
 import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-public class ConfigManagerActivator implements BundleActivator {
-    private static final Logger logger = LoggerFactory.getLogger(ConfigManagerActivator.class);
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanServer;
+import java.lang.management.ManagementFactory;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
 
-    private ExtensibleBundleTracker<Collection<Registration<YangModuleInfo>>> bundleTracker;
-    private ConfigRegistryImpl configRegistry;
-    private ConfigRegistryJMXRegistrator configRegistryJMXRegistrator;
-    private ServiceRegistration configRegistryServiceRegistration;
+import static org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil.registerService;
+import static org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil.wrap;
 
+public class ConfigManagerActivator implements BundleActivator {
     private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
 
-    private RuntimeGeneratedMappingServiceActivator mappingServiceActivator;
+    private AutoCloseable autoCloseable;
 
     @Override
     public void start(BundleContext context) {
 
-        // track bundles containing YangModuleInfo
-        ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker();
-        mappingServiceActivator = new RuntimeGeneratedMappingServiceActivator(moduleInfoBundleTracker);
-        CodecRegistry codecRegistry = mappingServiceActivator.startRuntimeMappingService(context).getCodecRegistry();
+        ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();// the inner strategy is backed by thread context cl?
+
+        RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry(
+                moduleInfoBackedContext, moduleInfoBackedContext, context);
+
+        ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper);
+
+        CodecRegistryProvider codecRegistryProvider = new CodecRegistryProvider(moduleInfoBackedContext, context);
 
         // start config registry
         BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver(
                 context);
-        configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer,
-                codecRegistry);
+        ConfigRegistryImpl configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, configMBeanServer,
+                codecRegistryProvider.getCodecRegistry());
 
         // track bundles containing factories
         BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(
@@ -61,53 +61,32 @@ public class ConfigManagerActivator implements BundleActivator {
                 blankTransactionServiceTracker);
 
         // start extensible tracker
-        bundleTracker = new ExtensibleBundleTracker<>(context, moduleInfoBundleTracker, moduleFactoryBundleTracker);
+        ExtensibleBundleTracker<Collection<ObjectRegistration<YangModuleInfo>>> bundleTracker = new ExtensibleBundleTracker<>(context, moduleInfoBundleTracker, moduleFactoryBundleTracker);
         bundleTracker.open();
 
         // register config registry to OSGi
-        configRegistryServiceRegistration = context.registerService(ConfigRegistryImpl.class, configRegistry, null);
+        AutoCloseable configRegReg = registerService(context, configRegistry, ConfigRegistryImpl.class);
 
         // register config registry to jmx
-        configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(configMBeanServer);
+        ConfigRegistryJMXRegistrator configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(configMBeanServer);
         try {
             configRegistryJMXRegistrator.registerToJMX(configRegistry);
         } catch (InstanceAlreadyExistsException e) {
             throw new IllegalStateException("Config Registry was already registered to JMX", e);
         }
 
+        // TODO wire directly via moduleInfoBundleTracker
         ServiceTracker<ModuleFactory, Object> serviceTracker = new ServiceTracker<>(context, ModuleFactory.class,
                 blankTransactionServiceTracker);
         serviceTracker.open();
+
+        List<AutoCloseable> list = Arrays.asList(
+                codecRegistryProvider, configRegistry, wrap(bundleTracker), configRegReg, configRegistryJMXRegistrator, wrap(serviceTracker));
+        autoCloseable = OsgiRegistrationUtil.aggregate(list);
     }
 
     @Override
-    public void stop(BundleContext context) {
-        try {
-            configRegistry.close();
-        } catch (Exception e) {
-            logger.warn("Exception while closing config registry", e);
-        }
-        try {
-            bundleTracker.close();
-        } catch (Exception e) {
-            logger.warn("Exception while closing extender", e);
-        }
-        try {
-            configRegistryJMXRegistrator.close();
-        } catch (Exception e) {
-            logger.warn(
-                    "Exception while closing config registry jmx registrator",
-                    e);
-        }
-        try {
-            configRegistryServiceRegistration.unregister();
-        } catch (Exception e) {
-            logger.warn("Exception while unregistering config registry", e);
-        }
-        try {
-            mappingServiceActivator.close();
-        } catch (Exception e) {
-            logger.warn("Exception while closing mapping service", e);
-        }
+    public void stop(BundleContext context) throws Exception {
+        autoCloseable.close();
     }
 }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/CodecRegistryProvider.java
new file mode 100644 (file)
index 0000000..9d0fbd8
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.manager.impl.osgi.mapping;
+
+import javassist.ClassPool;
+import org.opendaylight.controller.config.manager.impl.util.OsgiRegistrationUtil;
+import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Creates and initializes {@link RuntimeGeneratedMappingServiceImpl}, which is used to get {@link CodecRegistry}.
+ * Also maintains service registrations of {@link RuntimeGeneratedMappingServiceImpl}.
+ */
+// TODO move to yang runtime
+public class CodecRegistryProvider implements AutoCloseable {
+    private static final ClassPool CLASS_POOL = ClassPool.getDefault();
+
+    private final RuntimeGeneratedMappingServiceImpl service;
+    private final AutoCloseable registration;
+
+    public CodecRegistryProvider(ClassLoadingStrategy classLoadingStrategy, BundleContext context) {
+        service = new RuntimeGeneratedMappingServiceImpl(classLoadingStrategy);
+        service.setPool(CLASS_POOL);
+        service.init();
+        registration = OsgiRegistrationUtil.registerService(context, service,
+                SchemaServiceListener.class, BindingIndependentMappingService.class);
+    }
+
+    public CodecRegistry getCodecRegistry() {
+        return service.getCodecRegistry();
+    }
+
+    @Override
+    public void close() throws Exception {
+        registration.close();
+    }
+}
index a8fdfda7d7201f9cb00f50f590265e64825d2751..48fdd8855de12c9735a9a10a25ae5b5a9382b7f0 100644 (file)
@@ -7,10 +7,17 @@
  */
 package org.opendaylight.controller.config.manager.impl.osgi.mapping;
 
+import static java.lang.String.format;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
 import org.apache.commons.io.IOUtils;
-import org.opendaylight.yangtools.concepts.Registration;
-import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.osgi.framework.Bundle;
@@ -19,68 +26,58 @@ import org.osgi.util.tracker.BundleTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-import static java.lang.String.format;
-
 /**
- * Tracks bundles and attempts to retrieve YangModuleInfo.
+ * Tracks bundles and attempts to retrieve YangModuleInfo, which is then fed into ModuleInfoRegistry
  */
-public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Collection<Registration<YangModuleInfo>>> {
+public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Collection<ObjectRegistration<YangModuleInfo>>> {
 
     private static final Logger logger = LoggerFactory.getLogger(ModuleInfoBundleTracker.class);
-    public static final String GET_MODULE_INFO_METHOD = "getModuleInfo";
 
     public static final String MODULE_INFO_PROVIDER_PATH_PREFIX = "META-INF/services/";
 
-    private ModuleInfoBackedContext moduleInfoLoadingStrategy = ModuleInfoBackedContext.create();
 
-    public GeneratedClassLoadingStrategy getModuleInfoLoadingStrategy() {
-        return moduleInfoLoadingStrategy;
+    private final ModuleInfoRegistry moduleInfoRegistry;
+
+    public ModuleInfoBundleTracker(ModuleInfoRegistry moduleInfoRegistry) {
+        this.moduleInfoRegistry = moduleInfoRegistry;
     }
 
     @Override
-    public Collection<Registration<YangModuleInfo>> addingBundle(Bundle bundle, BundleEvent event) {
+    public Collection<ObjectRegistration<YangModuleInfo>> addingBundle(Bundle bundle, BundleEvent event) {
         URL resource = bundle.getEntry(MODULE_INFO_PROVIDER_PATH_PREFIX + YangModelBindingProvider.class.getName());
-
+        logger.debug("Got addingBundle({}) with YangModelBindingProvider resource {}", bundle, resource);
         if(resource==null) {
             return null;
         }
-
-        List<Registration<YangModuleInfo>> registrations = new LinkedList<>();
+        List<ObjectRegistration<YangModuleInfo>> registrations = new LinkedList<>();
 
         try (InputStream inputStream = resource.openStream()) {
             List<String> lines = IOUtils.readLines(inputStream);
             for (String moduleInfoName : lines) {
+                logger.trace("Retrieve ModuleInfo({}, {})", moduleInfoName, bundle);
                 YangModuleInfo moduleInfo = retrieveModuleInfo(moduleInfoName, bundle);
-                registrations.add(moduleInfoLoadingStrategy.registerModuleInfo(moduleInfo));
+                registrations.add(moduleInfoRegistry.registerModuleInfo(moduleInfo));
             }
 
-
         } catch (Exception e) {
             logger.error("Error while reading {}", resource, e);
             throw new RuntimeException(e);
         }
-
+        logger.trace("Got following registrations {}", registrations);
         return registrations;
     }
 
     @Override
-    public void modifiedBundle(Bundle bundle, BundleEvent event, Collection<Registration<YangModuleInfo>> object) {
-        // NOOP
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Collection<ObjectRegistration<YangModuleInfo>> object) {
     }
 
     @Override
-    public void removedBundle(Bundle bundle, BundleEvent event, Collection<Registration<YangModuleInfo>> regs) {
+    public void removedBundle(Bundle bundle, BundleEvent event, Collection<ObjectRegistration<YangModuleInfo>> regs) {
         if(regs == null) {
             return;
         }
 
-        for (Registration<YangModuleInfo> reg : regs) {
+        for (ObjectRegistration<YangModuleInfo> reg : regs) {
             try {
                 reg.close();
             } catch (Exception e) {
@@ -105,7 +102,7 @@ public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Co
             errorMessage = logMessage("Could not instantiate {} in bundle {}, reason {}", moduleInfoClass, bundle, e);
             throw new IllegalStateException(errorMessage, e);
         } catch (IllegalAccessException e) {
-            errorMessage = logMessage("Illegal access during instatiation of class {} in bundle {}, reason {}",
+            errorMessage = logMessage("Illegal access during instantiation of class {} in bundle {}, reason {}",
                     moduleInfoClass, bundle, e);
             throw new IllegalStateException(errorMessage, e);
         }
@@ -123,7 +120,7 @@ public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Co
         try {
             return bundle.loadClass(moduleInfoClass);
         } catch (ClassNotFoundException e) {
-            String errorMessage = logMessage("Could not find class {} in bunde {}, reason {}", moduleInfoClass, bundle, e);
+            String errorMessage = logMessage("Could not find class {} in bundle {}, reason {}", moduleInfoClass, bundle, e);
             throw new IllegalStateException(errorMessage);
         }
     }
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RefreshingSCPModuleInfoRegistry.java
new file mode 100644 (file)
index 0000000..e51cf8d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.manager.impl.osgi.mapping;
+
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.sal.binding.generator.api.ModuleInfoRegistry;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import java.util.Hashtable;
+
+/**
+ * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed.
+ */
+public class RefreshingSCPModuleInfoRegistry implements ModuleInfoRegistry, AutoCloseable {
+
+    private final ModuleInfoRegistry moduleInfoRegistry;
+    private final ServiceRegistration<SchemaContextProvider> osgiReg;
+
+    public RefreshingSCPModuleInfoRegistry(ModuleInfoRegistry moduleInfoRegistry,
+                                           SchemaContextProvider schemaContextProvider, BundleContext bundleContext) {
+        this.moduleInfoRegistry = moduleInfoRegistry;
+        osgiReg = bundleContext.registerService(SchemaContextProvider.class, schemaContextProvider, new Hashtable<String, String>());
+    }
+
+    private void updateService() {
+        osgiReg.setProperties(null); // send modifiedService event
+    }
+
+    @Override
+    public ObjectRegistration<YangModuleInfo> registerModuleInfo(YangModuleInfo yangModuleInfo) {
+        ObjectRegistration<YangModuleInfo> yangModuleInfoObjectRegistration = moduleInfoRegistry.registerModuleInfo(yangModuleInfo);
+        ObjectRegistrationWrapper wrapper = new ObjectRegistrationWrapper(yangModuleInfoObjectRegistration);
+        updateService();
+        return wrapper;
+    }
+
+
+    @Override
+    public void close() {
+        osgiReg.unregister();
+    }
+
+    private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
+        private final ObjectRegistration<YangModuleInfo> inner;
+
+        private ObjectRegistrationWrapper(ObjectRegistration<YangModuleInfo> inner) {
+            this.inner = inner;
+        }
+
+        @Override
+        public YangModuleInfo getInstance() {
+            return inner.getInstance();
+        }
+
+        @Override
+        public void close() throws Exception {
+            inner.close();
+            updateService();// send modify event when a bundle disappears
+        }
+
+
+        @Override
+        public String toString() {
+            return inner.toString();
+        }
+    }
+}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/RuntimeGeneratedMappingServiceActivator.java
deleted file mode 100644 (file)
index a267a6b..0000000
+++ /dev/null
@@ -1,51 +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.manager.impl.osgi.mapping;
-
-import javassist.ClassPool;
-import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
-import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
-import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-
-import java.util.Hashtable;
-
-public class RuntimeGeneratedMappingServiceActivator implements AutoCloseable {
-
-    private static final ClassPool CLASS_POOL = ClassPool.getDefault();
-
-    private ServiceRegistration<SchemaServiceListener> listenerReg;
-    private ServiceRegistration<BindingIndependentMappingService> mappingReg;
-    private ModuleInfoBundleTracker moduleInfoBundleTracker;
-
-    public RuntimeGeneratedMappingServiceActivator(ModuleInfoBundleTracker moduleInfoBundleTracker) {
-        this.moduleInfoBundleTracker = moduleInfoBundleTracker;
-    }
-
-    public RuntimeGeneratedMappingServiceImpl startRuntimeMappingService(BundleContext context) {
-        RuntimeGeneratedMappingServiceImpl service = new RuntimeGeneratedMappingServiceImpl(moduleInfoBundleTracker.getModuleInfoLoadingStrategy());
-        service.setPool(CLASS_POOL);
-        service.init();
-        startRuntimeMappingService(service, context);
-        return service;
-    }
-
-    private void startRuntimeMappingService(RuntimeGeneratedMappingServiceImpl service, BundleContext context) {
-        Hashtable<String, String> properties = new Hashtable<String, String>();
-        listenerReg = context.registerService(SchemaServiceListener.class, service, properties);
-        mappingReg = context.registerService(BindingIndependentMappingService.class, service, properties);
-
-    }
-
-    @Override
-    public void close() throws Exception {
-        mappingReg.unregister();
-        listenerReg.unregister();
-    }
-}
diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java
new file mode 100644 (file)
index 0000000..8873596
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * 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.manager.impl.util;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class OsgiRegistrationUtil {
+    private static final Logger logger = LoggerFactory.getLogger(OsgiRegistrationUtil.class);
+
+    @SafeVarargs
+    public static <T> AutoCloseable registerService(BundleContext bundleContext, T service, Class<? super T> ... interfaces) {
+        checkNotNull(service);
+        checkNotNull(interfaces);
+        List<AutoCloseable> autoCloseableList = new ArrayList<>();
+        for (Class<? super T> ifc : interfaces) {
+            ServiceRegistration<? super T> serviceRegistration = bundleContext.registerService(ifc, service, null);
+            autoCloseableList.add(wrap(serviceRegistration));
+        }
+        return aggregate(autoCloseableList);
+    }
+
+    public static AutoCloseable wrap(final ServiceRegistration<?> reg) {
+        checkNotNull(reg);
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                reg.unregister();
+            }
+        };
+    }
+
+    public static AutoCloseable wrap(final BundleTracker bundleTracker) {
+        checkNotNull(bundleTracker);
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                bundleTracker.close();
+            }
+        };
+    }
+
+    public static AutoCloseable wrap(final ServiceTracker<?, ?> serviceTracker) {
+        checkNotNull(serviceTracker);
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                serviceTracker.close();
+            }
+        };
+    }
+
+    /**
+     * Close list of auto closeables in reverse order
+     */
+    public static AutoCloseable aggregate(final List<? extends AutoCloseable> list) {
+        checkNotNull(list);
+
+        return new AutoCloseable() {
+            @Override
+            public void close() throws Exception {
+                Exception firstException = null;
+                for (ListIterator<? extends AutoCloseable> it = list.listIterator(list.size()); it.hasPrevious();) {
+                    AutoCloseable ac = it.previous();
+                    try {
+                        ac.close();
+                    } catch (Exception e) {
+                        logger.warn("Exception while closing {}", ac, e);
+                        if (firstException == null) {
+                            firstException = e;
+                        } else {
+                            firstException.addSuppressed(e);
+                        }
+                    }
+                }
+                if (firstException != null) {
+                    throw firstException;
+                }
+            }
+        };
+    }
+}
index 3ae29062ed0e27c04ec9d09aa5acf9837de31e11..278d0d2456d50b1e310df894ca9924d9d059b0df 100644 (file)
@@ -91,8 +91,11 @@ public class DirectoryStorageAdapterTest {
     private void assertSnapshot(ConfigSnapshotHolder result, String directory) throws Exception {
         SortedSet<String> expectedCapabilities = new TreeSet<>(IOUtils.readLines(getClass().getResourceAsStream("/" + directory + "/expectedCapabilities.txt")));
         String expectedSnapshot = IOUtils.toString(getClass().getResourceAsStream("/" + directory + "/expectedSnapshot.xml"));
+        expectedSnapshot = expectedSnapshot.replaceAll("\r","");
+        String _snapshot = result.getConfigSnapshot();
+        _snapshot = _snapshot.replaceAll("\r","");
         assertEquals(expectedCapabilities, result.getCapabilities());
-        assertEquals(expectedSnapshot, result.getConfigSnapshot());
+        assertEquals(expectedSnapshot, _snapshot);
     }
 
 }
index 4ec7e2f64b6143560c731a8f8f1bcd56602cff3f..6b55b6ad16ab85e6f15dd30eb96e2dbc9ed1ad44 100644 (file)
@@ -27,8 +27,6 @@
         <module>config-persister-file-xml-adapter</module>
         <module>yang-jmx-generator</module>
         <module>yang-jmx-generator-plugin</module>
-        <module>yang-store-api</module>
-        <module>yang-store-impl</module>
         <module>yang-test</module>
         <module>logback-config</module>
         <module>threadpool-config-api</module>
                 <artifactId>yang-maven-plugin-spi</artifactId>
                 <version>${yangtools.version}</version>
             </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>yang-store-api</artifactId>
-                <version>${config.version}</version>
-            </dependency>
 
             <dependency>
                 <groupId>org.opendaylight.controller</groupId>
diff --git a/opendaylight/config/yang-store-api/pom.xml b/opendaylight/config/yang-store-api/pom.xml
deleted file mode 100644 (file)
index dfd9adb..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<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>
-        <artifactId>config-subsystem</artifactId>
-        <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.5-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-    <artifactId>yang-store-api</artifactId>
-    <name>${project.artifactId}</name>
-    <packaging>bundle</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-jmx-generator</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Export-Package>
-                            org.opendaylight.controller.config.yang.store.api,
-                        </Export-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/opendaylight/config/yang-store-impl/.gitignore b/opendaylight/config/yang-store-impl/.gitignore
deleted file mode 100644 (file)
index fc1d35e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-target
-.classpath
-.settings
diff --git a/opendaylight/config/yang-store-impl/pom.xml b/opendaylight/config/yang-store-impl/pom.xml
deleted file mode 100644 (file)
index 8a88cd0..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-<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>
-        <artifactId>config-subsystem</artifactId>
-        <groupId>org.opendaylight.controller</groupId>
-        <version>0.2.5-SNAPSHOT</version>
-        <relativePath>..</relativePath>
-    </parent>
-    <artifactId>yang-store-impl</artifactId>
-    <name>${project.artifactId}</name>
-    <packaging>bundle</packaging>
-
-    <dependencies>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-jmx-generator</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>binding-type-provider</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-io</groupId>
-            <artifactId>commons-io</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>mockito-configuration</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.findbugs</groupId>
-            <artifactId>jsr305</artifactId>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Bundle-Activator>org.opendaylight.controller.config.yang.store.impl.YangStoreActivator</Bundle-Activator>
-                        <Export-Package>
-                        </Export-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-            <!-- test jar -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java
deleted file mode 100644 (file)
index 889d246..0000000
+++ /dev/null
@@ -1,222 +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.yang.store.impl;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleEvent;
-import org.osgi.util.tracker.BundleTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Note on consistency:
- * When this bundle is activated after other bundles containing yang files, the resolving order
- * is not preserved. We thus maintain two maps, one containing consistent snapshot, other inconsistent. The
- * container should eventually send all events and thus making the inconsistent map redundant.
- */
-public class ExtenderYangTracker extends BundleTracker<Object> implements YangStoreService, AutoCloseable {
-
-    private static final Logger logger = LoggerFactory.getLogger(ExtenderYangTracker.class);
-
-    private final Multimap<Bundle, URL> consistentBundlesToYangURLs = HashMultimap.create();
-
-    /*
-    Map of currently problematic yang files that should get fixed eventually after all events are received.
-     */
-    private final Multimap<Bundle, URL> inconsistentBundlesToYangURLs = HashMultimap.create();
-
-    private final YangStoreCache cache = new YangStoreCache();
-    private final MbeParser mbeParser;
-
-
-    public ExtenderYangTracker(Optional<Pattern> maybeBlacklist, BundleContext bundleContext) {
-        this(new MbeParser(), maybeBlacklist, bundleContext);
-    }
-
-    @GuardedBy("this")
-    private Optional<Pattern> maybeBlacklist;
-
-    @VisibleForTesting
-    ExtenderYangTracker(MbeParser mbeParser, Optional<Pattern> maybeBlacklist, BundleContext bundleContext) {
-        super(bundleContext, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, null);
-        this.mbeParser = mbeParser;
-        this.maybeBlacklist = maybeBlacklist;
-        open();
-    }
-
-    @Override
-    public synchronized Object addingBundle(Bundle bundle, BundleEvent event) {
-
-        // Ignore system bundle:
-        // system bundle might have config-api on classpath &&
-        // config-api contains yang files =>
-        // system bundle might contain yang files from that bundle
-        if (bundle.getBundleId() == 0)
-            return bundle;
-
-        if (maybeBlacklist.isPresent()) {
-            Matcher m = maybeBlacklist.get().matcher(bundle.getSymbolicName());
-            if (m.matches()) {
-                logger.debug("Ignoring {} because it is in blacklist {}", bundle, maybeBlacklist);
-                return bundle;
-            }
-        }
-
-        Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
-        if (enumeration != null && enumeration.hasMoreElements()) {
-            synchronized (this) {
-                List<URL> addedURLs = new ArrayList<>();
-                while (enumeration.hasMoreElements()) {
-                    URL url = enumeration.nextElement();
-                    addedURLs.add(url);
-                }
-                logger.trace("Bundle {} has event {}, bundle state {}, URLs {}", bundle, event, bundle.getState(), addedURLs);
-                // test that yang store is consistent
-                Multimap<Bundle, URL> proposedNewState = HashMultimap.create(consistentBundlesToYangURLs);
-                proposedNewState.putAll(inconsistentBundlesToYangURLs);
-                proposedNewState.putAll(bundle, addedURLs);
-
-                Preconditions.checkArgument(addedURLs.size() > 0, "No change can occur when no URLs are changed");
-
-                try(YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, proposedNewState)) {
-                    onSnapshotSuccess(proposedNewState, snapshot);
-                } catch(YangStoreException e) {
-                    onSnapshotFailure(bundle, addedURLs, e);
-                }
-            }
-        }
-        return bundle;
-    }
-
-    private synchronized void onSnapshotFailure(Bundle bundle, List<URL> addedURLs, Exception failureReason) {
-        // inconsistent state
-        inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
-
-        logger.debug("Yang store is falling back to last consistent state containing {}, inconsistent yang files {}",
-                consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason);
-        logger.info("Yang store is falling back to last consistent state containing {} files, keeping {} inconsistent yang files due to {}",
-                consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason.toString());
-        cache.setInconsistentURLsForReporting(inconsistentBundlesToYangURLs.values());
-    }
-
-    private synchronized void onSnapshotSuccess(Multimap<Bundle, URL> proposedNewState, YangStoreSnapshotImpl snapshot) {
-        // consistent state
-        // merge into
-        consistentBundlesToYangURLs.clear();
-        consistentBundlesToYangURLs.putAll(proposedNewState);
-
-        logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs);
-
-        // If we cleared up some inconsistent models, report that
-        if (!inconsistentBundlesToYangURLs.isEmpty()) {
-            inconsistentBundlesToYangURLs.clear();
-            logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
-        }
-
-        updateCache(snapshot);
-        cache.setInconsistentURLsForReporting(Collections.<URL> emptySet());
-    }
-
-    private synchronized void updateCache(YangStoreSnapshotImpl snapshot) {
-        cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
-    }
-
-    @Override
-    public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
-        logger.debug("Modified bundle {} {} {}", bundle, event, object);
-    }
-
-    /**
-     * If removing YANG files makes yang store inconsistent, method {@link #getYangStoreSnapshot()}
-     * will throw exception. There is no rollback.
-     */
-    @Override
-    public synchronized void removedBundle(Bundle bundle, BundleEvent event, Object object) {
-        logger.debug("Removed bundle {} {} {}", bundle, event, object);
-        inconsistentBundlesToYangURLs.removeAll(bundle);
-        consistentBundlesToYangURLs.removeAll(bundle);
-    }
-
-    @Override
-    public synchronized YangStoreSnapshot getYangStoreSnapshot()
-            throws YangStoreException {
-        Optional<YangStoreSnapshot> yangStoreOpt = cache.getSnapshotIfPossible(consistentBundlesToYangURLs);
-        if (yangStoreOpt.isPresent()) {
-            logger.debug("Returning cached yang store {}", yangStoreOpt.get());
-            return yangStoreOpt.get();
-        }
-
-        YangStoreSnapshotImpl snapshot = createSnapshot(mbeParser, consistentBundlesToYangURLs);
-        updateCache(snapshot);
-        return snapshot;
-    }
-
-    private static YangStoreSnapshotImpl createSnapshot(MbeParser mbeParser, Multimap<Bundle, URL> multimap) throws YangStoreException {
-        try {
-            YangStoreSnapshotImpl yangStoreSnapshot = mbeParser.parseYangFiles(fromUrlsToInputStreams(multimap));
-            logger.trace("{} module entries parsed successfully from {} yang files",
-                    yangStoreSnapshot.countModuleMXBeanEntries(), multimap.values().size());
-            return yangStoreSnapshot;
-        } catch (RuntimeException e) {
-            StringBuffer causeStr = new StringBuffer();
-            Throwable cause = e;
-            while (cause != null) {
-                causeStr.append(e.getMessage());
-                causeStr.append("\n");
-                cause = e.getCause();
-            }
-            throw new YangStoreException("Unable to parse yang files. \n" + causeStr.toString() +
-                    "URLs: " + multimap, e);
-        }
-    }
-
-    private static Collection<InputStream> fromUrlsToInputStreams(Multimap<Bundle, URL> multimap) {
-        return Collections2.transform(multimap.values(),
-                new Function<URL, InputStream>() {
-
-                    @Override
-                    public InputStream apply(URL url) {
-                        try {
-                            return url.openStream();
-                        } catch (IOException e) {
-                            logger.warn("Unable to open stream from {}", url);
-                            throw new IllegalStateException(
-                                    "Unable to open stream from " + url, e);
-                        }
-                    }
-                });
-    }
-
-    public synchronized void setMaybeBlacklist(Optional<Pattern> maybeBlacklistPattern) {
-        maybeBlacklist = maybeBlacklistPattern;
-        cache.invalidate();
-    }
-}
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangParserWrapper.java
deleted file mode 100644 (file)
index 7c42818..0000000
+++ /dev/null
@@ -1,68 +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.yang.store.impl;
-
-import com.google.common.collect.Sets;
-import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-public class YangParserWrapper {
-
-    /**
-     * throw IllegalStateException if it is unable to parse yang files
-     */
-    public static SchemaContext parseYangFiles(Collection<? extends InputStream> yangFilesAsInputStreams) {
-        YangParserImpl parser = getYangParserInstance();
-        Map<InputStream, Module> mappedYangModules = null;
-        try {
-            mappedYangModules = parseYangFiles(parser, yangFilesAsInputStreams);
-        } catch (YangStoreException e) {
-            throw new IllegalStateException("Unable to parse yang files", e);
-        }
-        return getSchemaContextFromModules(parser, mappedYangModules);
-    }
-
-    static YangParserImpl getYangParserInstance() {
-        return new YangParserImpl();
-    }
-
-    static SchemaContext getSchemaContextFromModules(YangModelParser parser, Map<InputStream, Module> allYangModules) {
-        return parser.resolveSchemaContext(Sets
-                .newHashSet(allYangModules.values()));
-    }
-
-    static Map<InputStream, Module> parseYangFiles(YangModelParser parser, Collection<? extends InputStream> allInput) throws YangStoreException {
-        List<InputStream> bufferedInputStreams = new ArrayList<>();
-        for (InputStream is : allInput) {
-            String content;
-            try {
-                content = IOUtils.toString(is);
-            } catch (IOException e) {
-                throw new YangStoreException("Can not get yang as String from "
-                        + is, e);
-            }
-            InputStream buf = new ByteArrayInputStream(content.getBytes());
-            bufferedInputStreams.add(buf);
-        }
-
-        return parser
-                .parseYangModelsFromStreamsMapped(bufferedInputStreams);
-    }
-}
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreActivator.java
deleted file mode 100644 (file)
index a25b05a..0000000
+++ /dev/null
@@ -1,46 +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.yang.store.impl;
-
-import com.google.common.base.Optional;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.regex.Pattern;
-
-public class YangStoreActivator implements BundleActivator {
-    private static final Logger logger = LoggerFactory.getLogger(YangStoreActivator.class);
-
-    @Override
-    public void start(BundleContext context) throws Exception {
-        // get blacklist
-        Optional<Pattern> maybeBlacklistPattern = Optional.absent();
-        String blacklist = context.getProperty("yangstore.blacklist");
-        if (blacklist != null) {
-            try {
-                maybeBlacklistPattern = Optional.of(Pattern.compile(blacklist));
-            } catch (RuntimeException e) {
-                logger.error("Cannot parse blacklist regex " + blacklist, e);
-                throw e;
-            }
-        }
-        ExtenderYangTracker extenderYangTracker = new ExtenderYangTracker(maybeBlacklistPattern, context);
-        Dictionary<String, ?> properties = new Hashtable<>();
-        context.registerService(YangStoreService.class, extenderYangTracker, properties);
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-
-    }
-}
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreCache.java
deleted file mode 100644 (file)
index 48bce78..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2014 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.yang.store.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.osgi.framework.Bundle;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.GuardedBy;
-import java.net.URL;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-class YangStoreCache {
-    private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class);
-
-    @GuardedBy("this")
-    private Set<URL> cachedUrls = null;
-    @GuardedBy("this")
-    private Optional<YangStoreSnapshot> cachedYangStoreSnapshot = getInitialSnapshot();
-    @GuardedBy("this")
-    private Collection<URL> inconsistentURLsForReporting = Collections.emptySet();
-
-    synchronized Optional<YangStoreSnapshot> getSnapshotIfPossible(Multimap<Bundle, URL> bundlesToYangURLs) {
-        Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
-
-        if (cachedUrls==null || cachedUrls.equals(urls)) {
-            Preconditions.checkState(cachedYangStoreSnapshot.isPresent());
-            YangStoreSnapshot freshSnapshot = YangStoreSnapshotImpl.copy(cachedYangStoreSnapshot.get());
-            if (inconsistentURLsForReporting.size() > 0){
-                logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting);
-            }
-            return Optional.of(freshSnapshot);
-        }
-
-        return Optional.absent();
-    }
-
-    private static Set<URL> setFromMultimapValues(
-            Multimap<Bundle, URL> bundlesToYangURLs) {
-        Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
-        Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
-        return urls;
-    }
-
-    synchronized void cacheYangStore(Multimap<Bundle, URL> urls,
-                                     YangStoreSnapshot yangStoreSnapshot) {
-        this.cachedUrls = setFromMultimapValues(urls);
-        this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot);
-    }
-
-    synchronized void invalidate() {
-        cachedUrls.clear();
-        if (cachedYangStoreSnapshot.isPresent()){
-            cachedYangStoreSnapshot.get().close();
-            cachedYangStoreSnapshot = Optional.absent();
-        }
-    }
-
-    public synchronized void setInconsistentURLsForReporting(Collection<URL> urls){
-        inconsistentURLsForReporting = urls;
-    }
-
-    private Optional<YangStoreSnapshot> getInitialSnapshot() {
-        YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() {
-            @Override
-            public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
-                return Collections.emptyMap();
-            }
-
-            @Override
-            public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
-                return Collections.emptyMap();
-            }
-
-            @Override
-            public Set<Module> getModules() {
-                return Collections.emptySet();
-            }
-
-            @Override
-            public Map<Module, String> getModulesToSources() {
-                return Collections.emptyMap();
-            }
-
-            @Override
-            public String getModuleSource(Module module) {
-                throw new IllegalArgumentException("Cannot get sources in empty snapshot");
-            }
-
-            @Override
-            public int countModuleMXBeanEntries() {
-                return 0;
-            }
-
-            @Override
-            public void close() {
-            }
-        };
-        return Optional.of(initialSnapshot);
-    }
-}
diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java
deleted file mode 100644 (file)
index 474d754..0000000
+++ /dev/null
@@ -1,96 +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.yang.store.impl;
-
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-public class YangStoreSnapshotImpl implements YangStoreSnapshot {
-    private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
-
-    @Deprecated
-    private final Map<String /* Namespace from yang file */,
-            Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
-
-    private final Map<Module, String> modulesToSources;
-    private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
-
-    public YangStoreSnapshotImpl(Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap,
-                                 Map<Module, String> modulesToSources,
-                                 Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries) {
-
-        this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
-        this.modulesToSources = Collections.unmodifiableMap(modulesToSources);
-        this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
-    }
-
-    public static YangStoreSnapshotImpl copy(YangStoreSnapshot yangStoreSnapshot) {
-        return new YangStoreSnapshotImpl(
-                yangStoreSnapshot.getModuleMXBeanEntryMap(),
-                yangStoreSnapshot.getModulesToSources(),
-                yangStoreSnapshot.getQNamesToIdentitiesToModuleMXBeanEntries());
-    }
-
-    /**
-     * @return all loaded config modules. Key of outer map is namespace of yang file.
-     * Key of inner map is name of module entry. Value is module entry.
-     */
-    @Override
-    public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
-        return moduleMXBeanEntryMap;
-    }
-
-    @Override
-    public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
-        return qNamesToIdentitiesToModuleMXBeanEntries;
-    }
-
-    @Override
-    public Set<Module> getModules() {
-        return modulesToSources.keySet();
-    }
-
-    @Override
-    public String getModuleSource(Module module) {
-        String result = modulesToSources.get(module);
-        if (result == null) {
-            logger.trace("Cannot find module {} in {}", module, modulesToSources);
-            throw new IllegalArgumentException("Module not found in this snapshot:" + module);
-        }
-        return result;
-    }
-
-    @Override
-    public Map<Module, String> getModulesToSources() {
-        return modulesToSources;
-    }
-
-    @Override
-    public int countModuleMXBeanEntries() {
-        int i = 0;
-        for (Map<String, ModuleMXBeanEntry> value : moduleMXBeanEntryMap
-                .values()) {
-            i += value.keySet().size();
-        }
-        return i;
-    }
-
-    @Override
-    public void close() {
-        // TODO: reference counting
-    }
-
-}
diff --git a/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java b/opendaylight/config/yang-store-impl/src/test/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTrackerCustomizerTest.java
deleted file mode 100644 (file)
index 8a7b95f..0000000
+++ /dev/null
@@ -1,171 +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.yang.store.impl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.yangtools.yang.model.api.Module;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleListener;
-
-import java.io.InputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyCollectionOf;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class ExtenderYangTrackerCustomizerTest {
-
-
-    private ExtenderYangTracker tested;
-    @Mock
-    private MbeParser parser;
-    @Mock
-    private YangStoreSnapshotImpl yangStoreSnapshot;
-    @Mock
-    private BundleContext bundleContext;
-
-    private Map<String, Map.Entry<Module, String>> moduleMap = Maps.newHashMap();
-
-    @Before
-    public void setUp() throws YangStoreException {
-
-        moduleMap.put("1", new Map.Entry<Module, String>() {
-            @Override
-            public Module getKey() {
-                return mock(Module.class);
-            }
-
-            @Override
-            public String getValue() {
-                return "v";
-            }
-
-            @Override
-            public String setValue(String value) {
-                return "v";
-            }
-        });
-
-        MockitoAnnotations.initMocks(this);
-        doNothing().when(bundleContext).addBundleListener(any(BundleListener.class));
-        doReturn(new Bundle[0]).when(bundleContext).getBundles();
-        tested = new ExtenderYangTracker(parser, Optional.<Pattern>absent(), bundleContext);
-        doReturn(yangStoreSnapshot).when(parser).parseYangFiles(
-                anyCollectionOf(InputStream.class));
-        doReturn(22).when(yangStoreSnapshot).countModuleMXBeanEntries();
-        doReturn("mock yang store").when(yangStoreSnapshot).toString();
-        doNothing().when(yangStoreSnapshot).close();
-        doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModuleMXBeanEntryMap();
-        doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModulesToSources();
-        doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getQNamesToIdentitiesToModuleMXBeanEntries();
-    }
-
-    @Test
-    public void testCache() throws MalformedURLException, YangStoreException,
-            InterruptedException {
-        Bundle bundle = getMockedBundle(5, false);
-        tested.addingBundle(bundle, null);
-        bundle = getMockedBundle(2, false);
-        tested.addingBundle(bundle, null);
-        bundle = getMockedBundle(10, false);
-        tested.addingBundle(bundle, null);
-        YangStoreSnapshot returnedStore;
-
-        returnedStore = tested.getYangStoreSnapshot();
-
-
-        tested.removedBundle(bundle, null, null);
-        tested.getYangStoreSnapshot();
-
-        bundle = getMockedBundle(10, false);
-        tested.addingBundle(bundle, null);
-
-        for(int i = 0; i< 20; i++){
-            tested.getYangStoreSnapshot();
-        }
-
-        verify(parser, times(5)).parseYangFiles(anyCollectionOf(InputStream.class));
-
-        returnedStore = tested.getYangStoreSnapshot();
-
-        verifyNoMoreInteractions(parser);
-    }
-
-    int bundleCounter = 1;
-
-    private Bundle getMockedBundle(int sizeOfUrls, boolean system)
-            throws MalformedURLException {
-        Bundle mock = mock(Bundle.class);
-        doReturn(32).when(mock).getState();//mock just for logging
-
-        List<URL> urls = Lists.newArrayList();
-        for (int i = 0; i < sizeOfUrls; i++) {
-            urls.add(new URL("http://127.0." + bundleCounter++ + "." + i));
-        }
-        Enumeration<URL> abc = new TestEnumeration(urls);
-
-        doReturn(abc).when(mock).findEntries("META-INF/yang", "*.yang", false);
-        if (system)
-            doReturn(0L).when(mock).getBundleId();
-        else
-            doReturn(1L).when(mock).getBundleId();
-
-        doReturn("mockedBundle").when(mock).toString();
-        doReturn("mockedBundle").when(mock).getSymbolicName();
-
-        return mock;
-    }
-
-    private static final class TestEnumeration implements Enumeration<URL> {
-
-        private final List<URL> urls;
-        int currentPos = 0;
-
-        public TestEnumeration(List<URL> urls) {
-            this.urls = urls;
-        }
-
-        @Override
-        public boolean hasMoreElements() {
-            try {
-                urls.get(currentPos);
-            } catch (IndexOutOfBoundsException e) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public URL nextElement() {
-            URL url = urls.get(currentPos++);
-            return url;
-        }
-
-    }
-}
index 6caee4108ae8d93ff49d265e61ac89fdda093569..3e75d00943dec03e12074ebc0c5aff04bdfa46a5 100644 (file)
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>config</id>
-                        <goals>
-                            <goal>generate-sources</goal>
-                        </goals>
-                        <configuration>
-                            <yangFilesRootDir>src/main/yang</yangFilesRootDir>
-                            <codeGenerators>
-                                <generator>
-                                    <codeGeneratorClass>
-                                        org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-                                    </codeGeneratorClass>
-                                    <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
-                                    <additionalConfiguration>
-                                        <namespaceToPackage1>
-                                            urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang
-                                        </namespaceToPackage1>
-                                    </additionalConfiguration>
-                                </generator>
-                            </codeGenerators>
-                            <inspectDependencies>true</inspectDependencies>
-                        </configuration>
-                    </execution>
-
-                    <execution>
-                        <id>types</id>
-                        <goals>
-                            <goal>generate-sources</goal>
-                        </goals>
-                        <configuration>
-                            <yangFilesRootDir>src/main/yang/types</yangFilesRootDir>
-                            <codeGenerators>
-                              <generator>
-                                    <codeGeneratorClass>
-                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
-                                    </codeGeneratorClass>
-                                    <outputBaseDir>
-                                        ${project.build.directory}/generated-sources/sal
-                                    </outputBaseDir>
-                                </generator>
-                            </codeGenerators>
-                            <inspectDependencies>true</inspectDependencies>
-                        </configuration>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.opendaylight.controller</groupId>
-                        <artifactId>yang-jmx-generator-plugin</artifactId>
-                        <version>${config.version}</version>
-                    </dependency>
-
-                    <dependency>
-                        <groupId>org.opendaylight.yangtools</groupId>
-                        <artifactId>maven-sal-api-gen-plugin</artifactId>
-                        <version>${yangtools.version}</version>
-                    </dependency>
-                </dependencies>
             </plugin>
             <plugin>
                 <groupId>org.opendaylight.controller</groupId>
index 773c6cac508b9b8974846d7d1ad38ad80fadc1fb..ebc56928a23856a158b4247d98c2720af9f98ac6 100644 (file)
@@ -127,17 +127,6 @@ public class ConnectionManager implements IConnectionManager,
     }
 
     public void started() {
-        String schemeStr = System.getProperty("connection.scheme");
-        for (ConnectionMgmtScheme scheme : ConnectionMgmtScheme.values()) {
-            AbstractScheme schemeImpl = SchemeFactory.getScheme(scheme,
-                    clusterServices);
-            if (schemeImpl != null) {
-                schemes.put(scheme, schemeImpl);
-                if (scheme.name().equalsIgnoreCase(schemeStr)) {
-                    activeScheme = scheme;
-                }
-            }
-        }
 
         connectionEventThread.start();
 
@@ -152,6 +141,17 @@ public class ConnectionManager implements IConnectionManager,
                 "ConnectionEvent Thread");
         this.connectionEvents = new LinkedBlockingQueue<ConnectionMgmtEvent>();
         schemes = new ConcurrentHashMap<ConnectionMgmtScheme, AbstractScheme>();
+
+        String schemeStr = System.getProperty("connection.scheme");
+        for (ConnectionMgmtScheme scheme : ConnectionMgmtScheme.values()) {
+            AbstractScheme schemeImpl = SchemeFactory.getScheme(scheme, clusterServices);
+            if (schemeImpl != null) {
+                schemes.put(scheme, schemeImpl);
+                if (scheme.name().equalsIgnoreCase(schemeStr)) {
+                    activeScheme = scheme;
+                }
+            }
+        }
     }
 
     public void stopping() {
@@ -290,7 +290,7 @@ public class ConnectionManager implements IConnectionManager,
     }
 
     /*
-     * Clustering Services' doesnt provide the existing states in the cache
+     * Clustering Services doesn't provide the existing states in the cache
      * update callbacks. Hence, using a scratch local cache to maintain the
      * existing state.
      */
@@ -303,21 +303,17 @@ public class ConnectionManager implements IConnectionManager,
             return;
         Set<InetAddress> existingControllers = existingConnections.get(node);
         if (existingControllers != null) {
-            logger.debug(
-                    "Processing Update for : {} NewControllers : {} existingControllers : {}",
-                    node, newControllers.toString(),
-                    existingControllers.toString());
+            logger.debug("Processing Update for : {} NewControllers : {} existingControllers : {}", node,
+                    newControllers.toString(), existingControllers.toString());
             if (newControllers.size() < existingControllers.size()) {
-                Set<InetAddress> removed = new HashSet<InetAddress>(
-                        existingControllers);
+                Set<InetAddress> removed = new HashSet<InetAddress>(existingControllers);
                 if (removed.removeAll(newControllers)) {
                     logger.debug("notifyNodeDisconnectFromMaster({})", node);
                     notifyNodeDisconnectedEvent(node);
                 }
             }
         } else {
-            logger.debug("Ignoring the Update for : {} NewControllers : {}",
-                    node, newControllers.toString());
+            logger.debug("Ignoring the Update for : {} NewControllers : {}", node, newControllers.toString());
         }
         existingConnections.put(node, newControllers);
     }
@@ -326,7 +322,7 @@ public class ConnectionManager implements IConnectionManager,
     public void entryDeleted(Node key, String cacheName, boolean originLocal) {
         if (originLocal)
             return;
-        logger.debug("Deleted : {} cache : {}", key, cacheName);
+        logger.debug("Deleted entry {} from cache : {}", key, cacheName);
         notifyNodeDisconnectedEvent(key);
     }
 
index 1d0e86ecd167b3191290c269bb861cc08d9e05a7..68d1b233b2ebe7c71663f4341983a98e9938ccc1 100644 (file)
@@ -54,7 +54,7 @@ public abstract class AbstractScheme {
             allocateCaches();
             retrieveCaches();
         } else {
-            log.error("Couldn't retrieve caches for scheme %s. Clustering service unavailable", name);
+            log.error("Couldn't retrieve caches for scheme {}. Clustering service unavailable", name);
         }
     }
 
@@ -335,4 +335,56 @@ public abstract class AbstractScheme {
             log.error("An error occured",e);
         }
     }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((nodeConnections == null) ? 0 : nodeConnections.hashCode());
+        result = prime * result + ((nodeConnectionsCacheName == null) ? 0 : nodeConnectionsCacheName.hashCode());
+        return result;
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (!(obj instanceof AbstractScheme)) {
+            return false;
+        }
+        AbstractScheme other = (AbstractScheme) obj;
+        if (name == null) {
+            if (other.name != null) {
+                return false;
+            }
+        } else if (!name.equals(other.name)) {
+            return false;
+        }
+        if (nodeConnections == null) {
+            if (other.nodeConnections != null) {
+                return false;
+            }
+        } else if (!nodeConnections.equals(other.nodeConnections)) {
+            return false;
+        }
+        if (nodeConnectionsCacheName == null) {
+            if (other.nodeConnectionsCacheName != null) {
+                return false;
+            }
+        } else if (!nodeConnectionsCacheName.equals(other.nodeConnectionsCacheName)) {
+            return false;
+        }
+        return true;
+    }
 }
index 38dc454ac3c98b9614bda2dc30c6f6e0e8ceec4a..a38a9b4f935cd401428dd2c0b86f3e24024fd01c 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>
-  <prerequisites>
-    <maven>3.0</maven>
-  </prerequisites>
-  <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:Main</url>
-    <tag>HEAD</tag>
-  </scm>
-  <parent>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>commons.opendaylight</artifactId>
-    <version>1.4.2-SNAPSHOT</version>
-    <relativePath>../../commons/opendaylight</relativePath>
-  </parent>
+<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>
+    <prerequisites>
+        <maven>3.0</maven>
+    </prerequisites>
+    <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:Main</url>
+        <tag>HEAD</tag>
+    </scm>
+    <parent>
+        <groupId>org.opendaylight.controller</groupId>
+        <artifactId>commons.opendaylight</artifactId>
+        <version>1.4.2-SNAPSHOT</version>
+        <relativePath>../../commons/opendaylight</relativePath>
+    </parent>
+    <artifactId>distribution.opendaylight</artifactId>
+    <version>0.1.2-SNAPSHOT</version>
+    <packaging>pom</packaging>
 
-  <profiles>
-    <profile>
-      <id>notduringrelease</id>
-      <activation>
-        <property>
-          <name>!DOINGRELEASE</name>
-        </property>
-      </activation>
-      <dependencies>
-        <!-- md-sal -->
+
+    <profiles>
+        <profile>
+            <id>notduringrelease</id>
+            <activation>
+                <property>
+                    <name>!DOINGRELEASE</name>
+                </property>
+            </activation>
+            <dependencies>
+                <!-- md-sal -->
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-common</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-common-util</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-netconf-connector</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-core-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-broker-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-remote</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-restconf-broker</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-core-spi</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-common-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-common-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-binding-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-binding-config</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-binding-broker-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-compatibility</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-connector-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-rest-connector</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-inventory</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-flow-base</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-flow-service</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-flow-statistics</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-flow-management</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.md</groupId>
+                    <artifactId>inventory-manager</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.md</groupId>
+                    <artifactId>forwardingrules-manager</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.md</groupId>
+                    <artifactId>topology-lldp-discovery</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.md</groupId>
+                    <artifactId>topology-manager</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.model</groupId>
+                    <artifactId>model-topology</artifactId>
+                    <version>1.1-SNAPSHOT</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.model</groupId>
+                    <artifactId>ietf-topology</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-binding-util</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.md</groupId>
+                    <artifactId>statistics-manager</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>concepts</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>protocol-framework</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>concepts</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>restconf-client-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>restconf-client-impl</artifactId>
+                </dependency>
+
+                <!-- clustering -->
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>remoterpc-routingtable.implementation</artifactId>
+                    <version>${mdsal.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sal-remoterpc-connector</artifactId>
+                </dependency>
+
+                <!-- config-->
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-manager</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>yang-jmx-generator</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>logback-config</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-file-adapter</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-file-xml-adapter</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-directory-adapter</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-directory-xml-adapter</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+                </dependency>
+
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>shutdown-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>shutdown-impl</artifactId>
+                </dependency>
+
+                <!-- Netconf -->
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-util</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-client</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-mapping-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-ssh</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-netconf-connector</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netconf-monitoring</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>${project.groupId}</groupId>
+                    <artifactId>ietf-netconf-monitoring</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>${project.groupId}</groupId>
+                    <artifactId>ietf-netconf-monitoring-extension</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>config-persister-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.servicemix.bundles</groupId>
+                    <artifactId>org.apache.servicemix.bundles.xerces</artifactId>
+                    <version>2.11.0_1</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.eclipse.birt.runtime.3_7_1</groupId>
+                    <artifactId>org.apache.xml.resolver</artifactId>
+                    <version>1.2.0</version>
+                </dependency>
+
+                <!-- threadpool -->
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>threadpool-config-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netty-config-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>threadpool-config-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netty-threadgroup-config</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netty-event-executor-config</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>netty-timer-config</artifactId>
+                </dependency>
+
+                <!-- toaster example I'm pretty sure we should trim -->
+                <dependency>
+                    <groupId>org.opendaylight.controller.samples</groupId>
+                    <artifactId>sample-toaster</artifactId>
+                    <version>${mdsal.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.samples</groupId>
+                    <artifactId>sample-toaster-consumer</artifactId>
+                    <version>${mdsal.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.samples</groupId>
+                    <artifactId>sample-toaster-provider</artifactId>
+                    <version>${mdsal.version}</version>
+                </dependency>
+                <!-- yangtools dependencies I'm pretty sure we can trim -->
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-binding</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-type-provider</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-generator-spi</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-generator-api</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-generator-impl</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-generator-util</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>binding-model-api</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>commons-lang</groupId>
+                    <artifactId>commons-lang</artifactId>
+                    <version>2.4</version>
+                </dependency>
+
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+                    <artifactId>antlr4-runtime-osgi-nohead</artifactId>
+                    <version>4.0</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.thirdparty</groupId>
+                    <artifactId>xtend-lib-osgi</artifactId>
+                    <version>2.4.3</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-parser-api</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-model-util</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-parser-impl</artifactId>
+                    <version>${yangtools.version}</version>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-common</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-data-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-data-impl</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-data-util</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools</groupId>
+                    <artifactId>yang-model-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.model</groupId>
+                    <artifactId>yang-ext</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.controller.thirdparty</groupId>
+                    <artifactId>ganymed</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.zeromq</groupId>
+                    <artifactId>jeromq</artifactId>
+                    <version>0.3.1</version>
+                </dependency>
+                <!-- yang model dependencies -->
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.model</groupId>
+                    <artifactId>ietf-inet-types</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.model</groupId>
+                    <artifactId>ietf-yang-types</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>org.opendaylight.yangtools.model</groupId>
+                    <artifactId>opendaylight-l2-types</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+        <profile>
+            <id>integrationtests</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-dependency-plugin</artifactId>
+                        <version>2.8</version>
+                        <dependencies>
+                            <dependency>
+                                <groupId>org.opendaylight.controller</groupId>
+                                <artifactId>sanitytest</artifactId>
+                                <version>${controller.version}</version>
+                            </dependency>
+                        </dependencies>
+                        <executions>
+                            <execution>
+                                <id>copy</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>copy</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.opendaylight.controller</groupId>
+                                    <artifactId>sanitytest</artifactId>
+                                    <type>jar</type>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>exec-maven-plugin</artifactId>
+                        <version>1.2.1</version>
+                        <executions>
+                            <execution>
+                                <id>sanity-test</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>exec</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                        <configuration>
+                            <executable>${java.home}/bin/java</executable>
+                            <arguments>
+                                <argument>-cp</argument>
+                                <argument>./target/dependency/*</argument>
+                                <argument>org.opendaylight.controller.distribution.Sanity</argument>
+                            </arguments>
+                            <environmentVariables>
+                                <JAVA_HOME>
+                                    ${java.home}
+                                </JAVA_HOME>
+                            </environmentVariables>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+            <dependencies>
+                <dependency>
+                    <groupId>org.opendaylight.controller</groupId>
+                    <artifactId>sanitytest</artifactId>
+                </dependency>
+            </dependencies>
+        </profile>
+    </profiles>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>forwarding.staticrouting</artifactId>
+        </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-common</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>clustering.services</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-common-util</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>clustering.services-implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-netconf-connector</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>configuration</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-core-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>configuration.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-broker-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>routing.dijkstra_implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-remote</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>arphandler</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-restconf-broker</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>hosttracker</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-core-spi</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>hosttracker.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-common-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>containermanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-common-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>containermanager.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-binding-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>appauth</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-binding-config</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>switchmanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-binding-broker-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>switchmanager.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-compatibility</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>statisticsmanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-connector-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>statisticsmanager.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-rest-connector</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>topologymanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-inventory</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>usermanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-flow-base</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>usermanager.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-flow-service</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>connectionmanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-flow-statistics</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>connectionmanager.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-flow-management</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>security</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.md</groupId>
-          <artifactId>inventory-manager</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>forwardingrulesmanager</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.md</groupId>
-          <artifactId>forwardingrules-manager</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>forwardingrulesmanager.implementation</artifactId>
+        </dependency>
+
+        <!-- SAL bundles -->
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.md</groupId>
-          <artifactId>topology-lldp-discovery</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal.implementation</artifactId>
         </dependency>
+
+        <!-- SAL Extension bundles -->
+
         <dependency>
-          <groupId>org.opendaylight.controller.md</groupId>
-          <artifactId>topology-manager</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal.connection</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller.model</groupId>
-          <artifactId>model-topology</artifactId>
-          <version>1.1-SNAPSHOT</version>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal.connection.implementation</artifactId>
         </dependency>
         <dependency>
-         <groupId>org.opendaylight.yangtools.model</groupId>
-         <artifactId>ietf-topology</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal.networkconfiguration</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-binding-util</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>sal.networkconfiguration.implementation</artifactId>
         </dependency>
+
+        <!--  Web bundles -->
+
         <dependency>
-          <groupId>org.opendaylight.controller.md</groupId>
-          <artifactId>statistics-manager</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>web</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>concepts</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>flows.web</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>protocol-framework</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>devices.web</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>concepts</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>troubleshoot.web</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>restconf-client-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>topology.web</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>restconf-client-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>osgi-brandfragment.web</artifactId>
         </dependency>
 
-        <!-- clustering -->
+        <!--  Neutron -->
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>networkconfig.neutron</artifactId>
+        </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>remoterpc-routingtable.implementation</artifactId>
-          <version>${mdsal.version}</version>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>networkconfig.neutron.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sal-remoterpc-connector</artifactId>
-          <version>${mdsal.version}</version>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>networkconfig.neutron.northbound</artifactId>
         </dependency>
 
-        <!-- config-->
+        <!-- Northbound bundles -->
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>commons.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-manager</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>bundlescanner</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>yang-jmx-generator</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>bundlescanner.implementation</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>yang-store-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>topology.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>yang-store-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>forwarding.staticrouting.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>logback-config</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>statistics.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>flowprogrammer.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-file-adapter</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>hosttracker.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-file-xml-adapter</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>subnets.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-directory-adapter</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>switchmanager.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-directory-xml-adapter</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>containermanager.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>networkconfig.bridgedomain.northbound</artifactId>
         </dependency>
-
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>shutdown-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>httpservice-bridge</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>shutdown-impl</artifactId>
+            <groupId>org.jolokia</groupId>
+            <artifactId>jolokia-osgi</artifactId>
         </dependency>
-
-       <!-- Netconf -->
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>jolokia-bridge</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-impl</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>connectionmanager.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-util</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>usermanager.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-client</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>controllermanager.northbound</artifactId>
         </dependency>
+        <!-- Debug and logging -->
+
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-mapping-api</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>logging.bridge</artifactId>
         </dependency>
+
+        <!-- Southbound bundles -->
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-ssh</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>protocol_plugins.openflow</artifactId>
         </dependency>
+
+        <!-- samples -->
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-netconf-connector</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>samples.loadbalancer</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>netconf-monitoring</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>samples.loadbalancer.northbound</artifactId>
         </dependency>
         <dependency>
-          <groupId>${project.groupId}</groupId>
-          <artifactId>ietf-netconf-monitoring</artifactId>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>samples.simpleforwarding</artifactId>
         </dependency>
+
+        <!-- Third party depedencies -->
         <dependency>
-          <groupId>${project.groupId}</groupId>
-          <artifactId>ietf-netconf-monitoring-extension</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl-over-slf4j</artifactId>
         </dependency>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>config-persister-impl</artifactId>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.apache.servicemix.bundles</groupId>
-            <artifactId>org.apache.servicemix.bundles.xerces</artifactId>
-            <version>2.11.0_1</version>
+            <groupId>org.slf4j</groupId>
+            <artifactId>log4j-over-slf4j</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.eclipse.birt.runtime.3_7_1</groupId>
-            <artifactId>org.apache.xml.resolver</artifactId>
-            <version>1.2.0</version>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
         </dependency>
-
-         <!-- threadpool -->
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>threadpool-config-api</artifactId>
-          </dependency>
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>netty-config-api</artifactId>
-          </dependency>
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>threadpool-config-impl</artifactId>
-          </dependency>
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>netty-threadgroup-config</artifactId>
-          </dependency>
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>netty-event-executor-config</artifactId>
-          </dependency>
-          <dependency>
-              <groupId>org.opendaylight.controller</groupId>
-              <artifactId>netty-timer-config</artifactId>
-          </dependency>
-
-          <!-- toaster example I'm pretty sure we should trim -->
-         <dependency>
-          <groupId>org.opendaylight.controller.samples</groupId>
-          <artifactId>sample-toaster</artifactId>
-          <version>${mdsal.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.controller.samples</groupId>
-          <artifactId>sample-toaster-consumer</artifactId>
-          <version>${mdsal.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.controller.samples</groupId>
-          <artifactId>sample-toaster-provider</artifactId>
-          <version>${mdsal.version}</version>
-         </dependency>
-         <!-- yangtools dependencies I'm pretty sure we can trim -->
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-binding</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-type-provider</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-spi</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-api</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-impl</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-generator-util</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>binding-model-api</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-           <groupId>commons-lang</groupId>
-           <artifactId>commons-lang</artifactId>
-           <version>2.4</version>
-         </dependency>
-
-         <dependency>
-          <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-          <artifactId>antlr4-runtime-osgi-nohead</artifactId>
-          <version>4.0</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-          <artifactId>xtend-lib-osgi</artifactId>
-          <version>2.4.3</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-parser-api</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-model-util</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-parser-impl</artifactId>
-          <version>${yangtools.version}</version>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-common</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-data-api</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-data-impl</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-data-util</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools</groupId>
-          <artifactId>yang-model-api</artifactId>
-         </dependency>
-         <dependency>
-          <groupId>org.opendaylight.yangtools.model</groupId>
-          <artifactId>yang-ext</artifactId>
-         </dependency>
-        <dependency>
-         <groupId>org.opendaylight.controller.thirdparty</groupId>
-         <artifactId>ganymed</artifactId>
-        </dependency>
-        <dependency>
-              <groupId>org.zeromq</groupId>
-          <artifactId>jeromq</artifactId>
-          <version>0.3.1</version>
-        </dependency>
-        <!-- yang model dependencies -->
-        <dependency>
-          <groupId>org.opendaylight.yangtools.model</groupId>
-          <artifactId>ietf-inet-types</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>org.opendaylight.yangtools.model</groupId>
-          <artifactId>ietf-yang-types</artifactId>
-        </dependency>
-        <dependency>
-          <groupId>org.opendaylight.yangtools.model</groupId>
-          <artifactId>opendaylight-l2-types</artifactId>
-        </dependency>
-      </dependencies>
-    </profile>
-    <profile>
-      <id>integrationtests</id>
-      <activation>
-        <activeByDefault>false</activeByDefault>
-      </activation>
-      <build>
-        <plugins>
-          <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-dependency-plugin</artifactId>
-            <version>2.8</version>
-            <dependencies>
-              <dependency>
-                <groupId>org.opendaylight.controller</groupId>
-                <artifactId>sanitytest</artifactId>
-                <version>${controller.version}</version>
-             </dependency>
-            </dependencies>
-            <executions>
-              <execution>
-                <id>copy</id>
-                <phase>package</phase>
-                <goals>
-                  <goal>copy</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>org.opendaylight.controller</groupId>
-                  <artifactId>sanitytest</artifactId>
-                  <type>jar</type>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </plugin>
-          <plugin>
-            <groupId>org.codehaus.mojo</groupId>
-            <artifactId>exec-maven-plugin</artifactId>
-            <version>1.2.1</version>
-            <executions>
-              <execution>
-                <id>sanity-test</id>
-                <phase>package</phase>
-                <goals>
-                  <goal>exec</goal>
-                </goals>
-              </execution>
-            </executions>
-            <configuration>
-              <executable>${java.home}/bin/java</executable>
-              <arguments>
-                <argument>-cp</argument>
-                <argument>./target/dependency/*</argument>
-                <argument>org.opendaylight.controller.distribution.Sanity</argument>
-              </arguments>
-              <environmentVariables>
-                <JAVA_HOME>
-                  ${java.home}
-                </JAVA_HOME>
-              </environmentVariables>
-            </configuration>
-          </plugin>
-        </plugins>
-      </build>
-      <dependencies>
         <dependency>
-          <groupId>org.opendaylight.controller</groupId>
-          <artifactId>sanitytest</artifactId>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
         </dependency>
-      </dependencies>
-    </profile>
-  </profiles>
-
-  <artifactId>distribution.opendaylight</artifactId>
-  <version>0.1.2-SNAPSHOT</version>
-  <packaging>pom</packaging>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>forwarding.staticrouting</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>clustering.services</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>clustering.services-implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>configuration</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>configuration.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>routing.dijkstra_implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>arphandler</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>hosttracker</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>hosttracker.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>containermanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>containermanager.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>appauth</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>switchmanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>switchmanager.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>statisticsmanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>statisticsmanager.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>topologymanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>usermanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>usermanager.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>connectionmanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>connectionmanager.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>security</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>forwardingrulesmanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>forwardingrulesmanager.implementation</artifactId>
-    </dependency>
-
-    <!-- SAL bundles -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal.implementation</artifactId>
-    </dependency>
-
-  <!-- SAL Extension bundles -->
-
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal.connection</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal.connection.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal.networkconfiguration</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>sal.networkconfiguration.implementation</artifactId>
-    </dependency>
-
-    <!--  Web bundles -->
-
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>flows.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>devices.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>troubleshoot.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>topology.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>osgi-brandfragment.web</artifactId>
-    </dependency>
-
-    <!--  Neutron -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>networkconfig.neutron</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>networkconfig.neutron.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>networkconfig.neutron.northbound</artifactId>
-    </dependency>
-
-    <!-- Northbound bundles -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>commons.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>bundlescanner</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>bundlescanner.implementation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>topology.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>forwarding.staticrouting.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>statistics.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>flowprogrammer.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>hosttracker.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>subnets.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>switchmanager.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>containermanager.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>networkconfig.bridgedomain.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>httpservice-bridge</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jolokia</groupId>
-      <artifactId>jolokia-osgi</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>jolokia-bridge</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>connectionmanager.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>usermanager.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>controllermanager.northbound</artifactId>
-    </dependency>
-    <!-- Debug and logging -->
-
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>logging.bridge</artifactId>
-    </dependency>
 
-    <!-- Southbound bundles -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>protocol_plugins.openflow</artifactId>
-    </dependency>
-
-    <!-- samples -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>samples.loadbalancer</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>samples.loadbalancer.northbound</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>samples.simpleforwarding</artifactId>
-    </dependency>
-
-    <!-- Third party depedencies -->
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>jcl-over-slf4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>log4j-over-slf4j</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>ch.qos.logback</groupId>
-      <artifactId>logback-classic</artifactId>
-    </dependency>
-
-    <dependency>
-        <groupId>com.fasterxml.jackson.core</groupId>
-        <artifactId>jackson-databind</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
 
-    <dependency>
-       <groupId>com.fasterxml.jackson.core</groupId>
-       <artifactId>jackson-annotations</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
 
-    <dependency>
-       <groupId>com.fasterxml.jackson.core</groupId>
-       <artifactId>jackson-core</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>com.fasterxml.jackson.jaxrs</groupId>
-      <artifactId>jackson-jaxrs-json-provider</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-json-provider</artifactId>
+        </dependency>
 
-      <dependency>
-         <groupId>com.fasterxml.jackson.jaxrs</groupId>
-         <artifactId>jackson-jaxrs-base</artifactId>
-      </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.jaxrs</groupId>
+            <artifactId>jackson-jaxrs-base</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>com.fasterxml.jackson.module</groupId>
-      <artifactId>jackson-module-jaxb-annotations</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.module</groupId>
+            <artifactId>jackson-module-jaxb-annotations</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.codehaus.jettison</groupId>
-      <artifactId>jettison</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.guava</groupId>
-      <artifactId>guava</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.javassist</groupId>
-      <artifactId>javassist</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-io</groupId>
-      <artifactId>commons-io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-codec</groupId>
-      <artifactId>commons-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-fileupload</groupId>
-      <artifactId>commons-fileupload</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>commons-net</groupId>
-      <artifactId>commons-net</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>javax.servlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>javax.servlet.jsp</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.ds</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi.services</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.osgi</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.apache.felix.gogo.command</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.apache.felix.gogo.runtime</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.apache.felix.gogo.shell</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.cm</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.console</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>equinoxSDK381</groupId>
-      <artifactId>org.eclipse.equinox.launcher</artifactId>
-    </dependency>
-    <!-- Gemini Web -->
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.extender</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.gemini.web.tomcat</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.io</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.math</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.osgi</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>geminiweb</groupId>
-      <artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.google.code.gson</groupId>
-      <artifactId>gson</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.spec.javax.transaction</groupId>
-      <artifactId>jboss-transaction-api_1.1_spec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.fileinstall</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.commons</groupId>
-      <artifactId>commons-lang3</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>virgomirror</groupId>
-      <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>eclipselink</groupId>
-      <artifactId>javax.persistence</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.activation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.annotation</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.ejb</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.el</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.mail.glassfish</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.xml.rpc</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina.ha</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.catalina.tribes</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.coyote</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.el</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.jasper</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.juli.extras</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.tomcat.api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>org.apache.tomcat.util</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.servlet.jsp.jstl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>orbit</groupId>
-      <artifactId>javax.servlet.jsp.jstl.impl</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>eclipselink</groupId>
-      <artifactId>javax.resource</artifactId>
-    </dependency>
-    <!-- Add Pax Exam -->
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.asm</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.aop</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.context</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.context.support</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.beans</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.expression</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.aopalliance</groupId>
-      <artifactId>com.springsource.org.aopalliance</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.web.servlet</artifactId>
-    </dependency>
-    <!-- Spring security -->
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-config</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-web</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework.security</groupId>
-      <artifactId>spring-security-taglibs</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.springframework</groupId>
-      <artifactId>org.springframework.transaction</artifactId>
-    </dependency>
-    <!-- Visual VM hook -->
-    <dependency>
-      <groupId>org.ow2.chameleon.management</groupId>
-      <artifactId>chameleon-mbeans</artifactId>
-    </dependency>
-    <!-- Jersey for JAXRS -->
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-server</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>com.sun.jersey</groupId>
-      <artifactId>jersey-client</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.codehaus.jettison</groupId>
+            <artifactId>jettison</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.javassist</groupId>
+            <artifactId>javassist</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-net</groupId>
+            <artifactId>commons-net</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>javax.servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>javax.servlet.jsp</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.equinox.ds</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.equinox.util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.osgi.services</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.osgi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.apache.felix.gogo.command</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.apache.felix.gogo.runtime</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.apache.felix.gogo.shell</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.equinox.cm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.equinox.console</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>equinoxSDK381</groupId>
+            <artifactId>org.eclipse.equinox.launcher</artifactId>
+        </dependency>
+        <!-- Gemini Web -->
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.gemini.web.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.gemini.web.extender</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.gemini.web.tomcat</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.io</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.math</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.osgi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>geminiweb</groupId>
+            <artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.dependencymanager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.spec.javax.transaction</groupId>
+            <artifactId>jboss-transaction-api_1.1_spec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.fileinstall</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>virgomirror</groupId>
+            <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eclipselink</groupId>
+            <artifactId>javax.persistence</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.activation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.ejb</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.el</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.mail.glassfish</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.xml.rpc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.catalina</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.catalina.ha</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.catalina.tribes</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.coyote</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.el</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.jasper</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.juli.extras</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.tomcat.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>org.apache.tomcat.util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.servlet.jsp.jstl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>orbit</groupId>
+            <artifactId>javax.servlet.jsp.jstl.impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>eclipselink</groupId>
+            <artifactId>javax.resource</artifactId>
+        </dependency>
+        <!-- Add Pax Exam -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.asm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.context.support</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.expression</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.aopalliance</groupId>
+            <artifactId>com.springsource.org.aopalliance</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.web.servlet</artifactId>
+        </dependency>
+        <!-- Spring security -->
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-taglibs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>org.springframework.transaction</artifactId>
+        </dependency>
+        <!-- Visual VM hook -->
+        <dependency>
+            <groupId>org.ow2.chameleon.management</groupId>
+            <artifactId>chameleon-mbeans</artifactId>
+        </dependency>
+        <!-- Jersey for JAXRS -->
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-server</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.jersey</groupId>
+            <artifactId>jersey-client</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.ow2.asm</groupId>
-      <artifactId>asm-all</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>org.eclipse.persistence.moxy</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>org.eclipse.persistence.core</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.eclipse.persistence</groupId>
-      <artifactId>org.eclipse.persistence.antlr</artifactId>
-    </dependency>
+        <dependency>
+            <groupId>org.ow2.asm</groupId>
+            <artifactId>asm-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.moxy</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.persistence</groupId>
+            <artifactId>org.eclipse.persistence.antlr</artifactId>
+        </dependency>
 
-    <dependency>
-      <groupId>org.eclipse.equinox.http</groupId>
-      <artifactId>servlet</artifactId>
-    </dependency>
-    <!-- felix webconsole -->
-    <dependency>
-      <groupId>org.apache.felix</groupId>
-      <artifactId>org.apache.felix.webconsole</artifactId>
-      <classifier>all</classifier>
-    </dependency>
+        <dependency>
+            <groupId>org.eclipse.equinox.http</groupId>
+            <artifactId>servlet</artifactId>
+        </dependency>
+        <!-- felix webconsole -->
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.webconsole</artifactId>
+            <classifier>all</classifier>
+        </dependency>
 
-    <!-- Third parties from opendaylight released -->
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>net.sf.jung2</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>org.openflow.openflowj</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>com.sun.jersey.jersey-servlet</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller.thirdparty</groupId>
-      <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
-    </dependency>
+        <!-- Third parties from opendaylight released -->
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>net.sf.jung2</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>org.openflow.openflowj</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>com.sun.jersey.jersey-servlet</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller.thirdparty</groupId>
+            <artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
+        </dependency>
 
-    <!--Netty-->
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-handler</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-codec</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-buffer</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-transport</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-common</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>io.netty</groupId>
-      <artifactId>netty-codec-http</artifactId>
-    </dependency>
+        <!--Netty-->
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-handler</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-buffer</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-codec-http</artifactId>
+        </dependency>
 
-    <!-- testing dependencies I'm pretty sure we should trim -->
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>clustering.test</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>commons.httpclient</artifactId>
-    </dependency>
-  </dependencies>
+        <!-- testing dependencies I'm pretty sure we should trim -->
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>clustering.test</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>commons.httpclient</artifactId>
+        </dependency>
+    </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>buildnumber-maven-plugin</artifactId>
-        <version>1.2</version>
-        <executions>
-          <execution>
-            <phase>validate</phase>
-            <goals>
-              <goal>create</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <doCheck>false</doCheck>
-          <doUpdate>false</doUpdate>
-          <revisionOnScmFailure>VersionUnknown</revisionOnScmFailure>
-        </configuration>
-      </plugin>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <version>2.3</version>
-        <executions>
-          <execution>
-            <id>distro-assembly</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-            <configuration>
-              <descriptors>
-                <descriptor>src/assemble/bin.xml</descriptor>
-              </descriptors>
-              <finalName>${project.artifactId}</finalName>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>buildnumber-maven-plugin</artifactId>
+                <version>1.2</version>
+                <executions>
+                    <execution>
+                        <phase>validate</phase>
+                        <goals>
+                            <goal>create</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <doCheck>false</doCheck>
+                    <doUpdate>false</doUpdate>
+                    <revisionOnScmFailure>VersionUnknown</revisionOnScmFailure>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>2.3</version>
+                <executions>
+                    <execution>
+                        <id>distro-assembly</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/assemble/bin.xml</descriptor>
+                            </descriptors>
+                            <finalName>${project.artifactId}</finalName>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
 
-        <!--Make checkstyle ignore initial xml configuration files by overriding its configuration from parent-->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-checkstyle-plugin</artifactId>
-        <version>${checkstyle.version}</version>
-        <configuration>
-            <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/configuration\/initial\/</excludes>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+            <!--Make checkstyle ignore initial xml configuration files by overriding its configuration from parent-->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>${checkstyle.version}</version>
+                <configuration>
+                    <excludes>**\/target\/,**\/bin\/,**\/target-ide\/,**\/configuration\/initial\/</excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
 </project>
index 99f8df358eaab4075aebecfd69e7349e79c5755d..4598bac593269d026bdcf32dd295ecaf5eb2af37 100644 (file)
@@ -8,7 +8,7 @@ osgi.bundles=\
     reference\:file\:../lib/slf4j-api-1.7.2.jar@1:start,\
     reference\:file\:../lib/logback-classic-1.0.9.jar@1:start,\
     reference\:file\:../lib/logback-core-1.0.9.jar@1:start,\
-    reference\:file\:../lib/logging.bridge-0.4.1-SNAPSHOT@1:start,\
+    reference\:file\:../lib/logging.bridge-0.4.2-SNAPSHOT@1:start,\
     reference\:file\:../lib/jersey-core-1.17.jar@2:start,\
     reference\:file\:../lib/jersey-server-1.17.jar@2:start
 
@@ -46,12 +46,10 @@ netconf.config.persister.2.storageAdapterClass=org.opendaylight.controller.confi
 netconf.config.persister.2.properties.fileStorage=configuration/current/controller.currentconfig.xml
 netconf.config.persister.2.properties.numberOfBackups=1
 
-yangstore.blacklist=.*controller.model.*
-
 # Set Default start level for framework
 osgi.bundles.defaultStartLevel=4
 # Extra packages to import from the boot class loader
-org.osgi.framework.system.packages.extra=sun.reflect,sun.reflect.misc,sun.misc
+org.osgi.framework.system.packages.extra=sun.reflect,sun.reflect.misc,sun.misc,sun.nio.ch
 # This is not Eclipse App
 eclipse.ignoreApp=true
 # Don't shutdown equinox if the eclipse App has ended,
index 3ad08ca207b4a49a125274969f1f07f14d43990e..0841485cb179d0a1517658d9ade15ab7fd668f5f 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.sal.action.Controller;
 import org.opendaylight.controller.sal.action.Drop;
 import org.opendaylight.controller.sal.action.Enqueue;
 import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
 import org.opendaylight.controller.sal.action.HwPath;
 import org.opendaylight.controller.sal.action.Loopback;
 import org.opendaylight.controller.sal.action.Output;
@@ -1019,6 +1020,12 @@ public class FlowConfig extends ConfigurationObject implements Serializable {
                     continue;
                 }
 
+                sstr = Pattern.compile(ActionType.FLOOD_ALL.toString()).matcher(actiongrp);
+                if (sstr.matches()) {
+                    actionList.add(new FloodAll());
+                    continue;
+                }
+
                 sstr = Pattern.compile(ActionType.SW_PATH.toString()).matcher(actiongrp);
                 if (sstr.matches()) {
                     actionList.add(new SwPath());
index 734a392bc121f7b33a20408908a3281193aec2aa..ce49b599e18f90833f1850bc23bfb74b457aabaf 100644 (file)
@@ -105,7 +105,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     static final String ACTIVE_HOST_CACHE = "hosttracker.ActiveHosts";
     static final String INACTIVE_HOST_CACHE = "hosttracker.InactiveHosts";
     private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
-    protected final Set<IHostFinder> hostFinder = new CopyOnWriteArraySet<IHostFinder>();;
+    protected final Set<IHostFinder> hostFinders = new CopyOnWriteArraySet<IHostFinder>();
     protected ConcurrentMap<IHostId, HostNodeConnector> hostsDB;
     /*
      * Following is a list of hosts which have been requested by NB APIs to be
@@ -256,16 +256,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     }
 
     public void setArpHandler(IHostFinder hostFinder) {
-        if (this.hostFinder != null) {
-            this.hostFinder.add(hostFinder);
-        }
+        this.hostFinders.add(hostFinder);
     }
 
     public void unsetArpHandler(IHostFinder hostFinder) {
-        if (this.hostFinder != null) {
-            logger.debug("Arp Handler Service removed!");
-            this.hostFinder.remove(hostFinder);
-        }
+        logger.debug("Arp Handler Service removed!");
+        this.hostFinders.remove(hostFinder);
     }
 
     public void setTopologyManager(ITopologyManager s) {
@@ -352,8 +348,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
          * already handles the null return
          */
 
-        if (hostFinder == null) {
-            logger.debug("Exiting hostFind, null hostFinder");
+        if (hostFinders.isEmpty()) {
+            logger.debug("No available host finders, exiting hostFind()");
             return null;
         }
 
@@ -369,7 +365,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...", id);
 
         /* host is not found, initiate a discovery */
-        for (IHostFinder hf : hostFinder) {
+        for (IHostFinder hf : hostFinders) {
             InetAddress addr = decodeIPFromId(id);
             hf.find(addr);
         }
@@ -936,12 +932,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
                 ARPPending arphost;
                 arphost = entry.getValue();
-                if (hostFinder == null) {
-                    logger.warn("ARPHandler Services are not available on subnet addition");
+                if (hostFinders.isEmpty()) {
+                    logger.debug("ARPHandler Services are not available on subnet addition");
                     continue;
                 }
                 logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", decodeIPFromId(arphost.getHostId()));
-                for (IHostFinder hf : hostFinder) {
+                for (IHostFinder hf : hostFinders) {
                     hf.find(decodeIPFromId(arphost.getHostId()));
                 }
             }
@@ -977,11 +973,11 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                          * next one. Before sending the ARP, check if ARPHandler
                          * is available or not
                          */
-                        if (hostFinder == null) {
+                        if (hostFinders.isEmpty()) {
                             logger.warn("ARPHandler Services are not available for Outstanding ARPs");
                             continue;
                         }
-                        for (IHostFinder hf : hostFinder) {
+                        for (IHostFinder hf : hostFinders) {
                             hf.find(decodeIPFromId(arphost.getHostId()));
                         }
                         arphost.sent_count++;
@@ -1063,7 +1059,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                                             HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
                         }
                         host.setArpSendCountDown(arp_cntdown);
-                        if (hostFinder == null) {
+                        if (hostFinders.isEmpty()) {
                             /*
                              * If hostfinder is not available, then can't send
                              * the probe. However, continue the age out the
@@ -1073,7 +1069,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                             logger.trace("ARPHandler is not avaialable, can't send the probe");
                             continue;
                         }
-                        for (IHostFinder hf : hostFinder) {
+                        for (IHostFinder hf : hostFinders) {
                             hf.probe(host);
                         }
                     }
@@ -1417,7 +1413,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         for (Entry<IHostId, ARPPending> entry : failedARPReqList.entrySet()) {
             arphost = entry.getValue();
             logger.trace("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostId());
-            if (hostFinder == null) {
+            if (hostFinders.isEmpty()) {
                 logger.warn("ARPHandler is not available at interface  up");
                 logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
                         nodeConnector);
@@ -1430,7 +1426,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 byte[] dataLayerAddress = NetUtils.getBroadcastMACAddr();
                 host = new HostNodeConnector(dataLayerAddress, decodeIPFromId(arphost.getHostId()), nodeConnector,
                         (short) 0);
-                for (IHostFinder hf : hostFinder) {
+                for (IHostFinder hf : hostFinders) {
                     hf.probe(host);
                 }
             } catch (ConstructionException e) {
index e6cfee15e1501de716e43fa4a1ff80f0138e0434..fe0b516a8bea6ee60b35c735e4df5df804aef381 100644 (file)
@@ -5,7 +5,7 @@
     <parent>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>sal-parent</artifactId>
-        <version>1.0-SNAPSHOT</version>
+        <version>1.1-SNAPSHOT</version>
         <relativePath>../..</relativePath>
     </parent>
     <scm>
@@ -24,7 +24,6 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <version>${bundle.plugin.version}</version>
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
@@ -35,7 +34,6 @@
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>${yangtools.version}</version>
                 <executions>
                     <execution>
                         <goals>
         <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-common-util</artifactId>
-            <version>1.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-api</artifactId>
-            <version>0.2.3-SNAPSHOT</version>
         </dependency>
 
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>sal</artifactId>
-            <version>0.7.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>clustering.services</artifactId>
-            <version>0.5.0-SNAPSHOT</version>
         </dependency>
         <dependency>
             <groupId>junit</groupId>
index b4f71764d3e0804d6e12f22e737ae203ba0a8ddb..74e7d1afe74910bcc55a3a1e1a3b9c52a546060c 100644 (file)
                 </exclusion>
             </exclusions>
         </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>${netconf.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <version>${config.version}</version>
-        </dependency>
 
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
index 4d0465cba7b5ee768cca028a1fb56ce948f43550..362a3496574237a4b48aba49dff16fa859231e67 100644 (file)
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 7668a3165ed0f6e9713626a8b1c50a5d8006497d..6f1ef5e5bb9c81c5359d2e6a55accc9287877bde 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.md.inventory.manager
 
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorUpdated
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowNodeConnector
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnectorBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode
index 7914de0f66339d4dcf1b524ec30776d46f1eded4..e7ac38cba136959a29d198cc92a1c1d7416c6b48 100644 (file)
@@ -21,6 +21,14 @@ module netconf-node-inventory {
         leaf-list current-capability {
             type string;
         }
+
+        container pass-through {
+            when "../connected = true";
+            description
+                "When the underlying node is connected, its NETCONF context
+                is available verbatim under this container through the
+                mount extension.";
+        }
     }
     
     augment /inv:nodes/inv:node {
@@ -28,4 +36,4 @@ module netconf-node-inventory {
         
         uses netconf-node-fields;
     }
-}
\ No newline at end of file
+}
index 1ea0a3e132c65bc25d33dd0adfb542502954807a..4c8a74c62bf91a7cc30aadd1c3f07d2ce2520561 100644 (file)
@@ -60,7 +60,7 @@
                                         org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                                     </codeGeneratorClass>
                                     <outputBaseDir>
-                                        target/generated-sources/sal
+                                        ${salGeneratorPath}
                                     </outputBaseDir>
                                 </generator>
                                 <generator>
index d05e8b0e61ed90876a430c6163fd66ea634111fd..a45cadab7ce76359f0dcbbba7a9612df04042f2b 100644 (file)
@@ -36,7 +36,7 @@
         <module>sal-binding-broker</module>
 
         <module>sal-binding-util</module>
-        <module>sal-binding-dom-it</module>
+
 
         <!-- Samples -->
         <module>samples</module>
@@ -79,6 +79,7 @@
             </activation>
             <modules>
                 <module>sal-binding-it</module>
+                <module>sal-binding-dom-it</module>
                 <!--module>clustered-data-store/integrationtest</module -->
                 <!--module>zeromq-routingtable/integrationtest</module -->
                 <!--module>sal-remoterpc-connector/integrationtest</module -->
     </profiles>
 
     <properties>
+        <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 
         <!-- Plugin Versions -->
index f90031b2054a12794b22cfc2cf330d3d5f4934d5..00129b98415f5e1b9811d437c51ddf1a17689291 100644 (file)
   </scm>
 
     <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>concepts</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-common</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common</artifactId>
+            <artifactId>sal-common-api</artifactId>
         </dependency>
-
         <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common-api</artifactId>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
index db20a13991f8356acf88b3212c4722356aa70fc1..5b700703bc0b522357f42ec2580e9b64e94c924e 100644 (file)
@@ -11,7 +11,7 @@ import org.opendaylight.controller.md.sal.common.api.routing.RoutedRegistration;
 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider.ProviderFunctionality;
 import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.BaseIdentity;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
@@ -19,20 +19,20 @@ import org.osgi.framework.BundleContext;
 
 /**
  * Binding-aware core of the SAL layer responsible for wiring the SAL consumers.
- * 
+ *
  * The responsibility of the broker is to maintain registration of SAL
  * functionality {@link Consumer}s and {@link Provider}s, store provider and
  * consumer specific context and functionality registration via
  * {@link ConsumerContext} and provide access to infrastructure services, which
  * removes direct dependencies between providers and consumers.
- * 
+ *
  * The Binding-aware broker is also responsible for translation from Java
- * classes modeling the functionality and data to binding-indpenedent form which
+ * classes modeling the functionality and data to binding-independent form which
  * is used in SAL Core.
- * 
- * 
+ *
+ *
  * <h3>Infrastructure services</h3> Some examples of infrastructure services:
- * 
+ *
  * <ul>
  * <li>YANG Module service - see {@link ConsumerContext#getRpcService(Class)},
  * {@link ProviderContext}
@@ -42,34 +42,34 @@ import org.osgi.framework.BundleContext;
  * <li>Data Store access and modification - see {@link DataBrokerService} and
  * {@link DataProviderService}
  * </ul>
- * 
+ *
  * The services are exposed via session.
- * 
+ *
  * <h3>Session-based access</h3>
- * 
+ *
  * The providers and consumers needs to register in order to use the
  * binding-independent SAL layer and to expose functionality via SAL layer.
- * 
+ *
  * For more information about session-based access see {@link ConsumerContext}
  * and {@link ProviderContext}
- * 
- * 
- * 
+ *
+ *
+ *
  */
 public interface BindingAwareBroker {
     /**
      * Registers the {@link BindingAwareConsumer}, which will use the SAL layer.
-     * 
+     *
      * <p>
      * Note that consumer could register additional functionality at later point
      * by using service and functionality specific APIs.
-     * 
+     *
      * <p>
      * The consumer is required to use returned session for all communication
      * with broker or one of the broker services. The session is announced to
      * the consumer by invoking
      * {@link Consumer#onSessionInitiated(ConsumerContext)}.
-     * 
+     *
      * @param cons
      *            Consumer to be registered.
      * @return a session specific to consumer registration
@@ -82,24 +82,24 @@ public interface BindingAwareBroker {
 
     /**
      * Registers the {@link BindingAwareProvider}, which will use the SAL layer.
-     * 
+     *
      * <p>
      * During the registration, the broker obtains the initial functionality
      * from consumer, using the
      * {@link BindingAwareProvider#getImplementations()}, and register that
      * functionality into system and concrete infrastructure services.
-     * 
+     *
      * <p>
      * Note that provider could register additional functionality at later point
      * by using service and functionality specific APIs.
-     * 
+     *
      * <p>
      * The consumer is <b>required to use</b> returned session for all
      * communication with broker or one of the broker services. The session is
      * announced to the consumer by invoking
      * {@link BindingAwareProvider#onSessionInitiated(ProviderContext)}.
-     * 
-     * 
+     *
+     *
      * @param prov
      *            Provider to be registered.
      * @return a session unique to the provider registration.
@@ -112,26 +112,26 @@ public interface BindingAwareBroker {
 
     /**
      * {@link BindingAwareConsumer} specific access to the SAL functionality.
-     * 
+     *
      * <p>
      * ConsumerSession is {@link BindingAwareConsumer}-specific access to the
      * SAL functionality and infrastructure services.
-     * 
+     *
      * <p>
      * The session serves to store SAL context (e.g. registration of
      * functionality) for the consumer and provides access to the SAL
      * infrastructure services and other functionality provided by
      * {@link Provider}s.
-     * 
-     * 
-     * 
+     *
+     *
+     *
      */
     public interface ConsumerContext extends RpcConsumerRegistry {
 
         /**
          * Returns a session specific instance (implementation) of requested
          * binding-aware infrastructural service
-         * 
+         *
          * @param service
          *            Broker service
          * @return Session specific implementation of service
@@ -143,19 +143,19 @@ public interface BindingAwareBroker {
 
     /**
      * {@link BindingAwareProvider} specific access to the SAL functionality.
-     * 
+     *
      * <p>
      * ProviderSession is {@link BindingAwareProvider}-specific access to the
      * SAL functionality and infrastructure services, which also allows for
      * exposing the provider's functionality to the other
      * {@link BindingAwareConsumer}s.
-     * 
+     *
      * <p>
      * The session serves to store SAL context (e.g. registration of
      * functionality) for the providers and exposes access to the SAL
      * infrastructure services, dynamic functionality registration and any other
      * functionality provided by other {@link BindingAwareConsumer}s.
-     * 
+     *
      */
     public interface ProviderContext extends ConsumerContext, RpcProviderRegistry {
 
@@ -166,7 +166,7 @@ public interface BindingAwareBroker {
         void unregisterFunctionality(ProviderFunctionality functionality);
     }
 
-    public interface RpcRegistration<T extends RpcService> extends Registration<T> {
+    public interface RpcRegistration<T extends RpcService> extends ObjectRegistration<T> {
 
         Class<T> getServiceType();
     }
@@ -177,9 +177,9 @@ public interface BindingAwareBroker {
         /**
          * Register particular instance identifier to be processed by this
          * RpcService
-         * 
-         * Deprecated in favor of {@link RoutedRegistration#registerPath(Object, Object)}. 
-         * 
+         *
+         * Deprecated in favor of {@link RoutedRegistration#registerPath(Object, Object)}.
+         *
          * @param context
          * @param instance
          */
@@ -189,9 +189,9 @@ public interface BindingAwareBroker {
         /**
          * Unregister particular instance identifier to be processed by this
          * RpcService
-         * 
-         * Deprecated in favor of {@link RoutedRegistration#unregisterPath(Object, Object)}. 
-         * 
+         *
+         * Deprecated in favor of {@link RoutedRegistration#unregisterPath(Object, Object)}.
+         *
          * @param context
          * @param instance
          */
index b3309b7a12b5af7bc15c310bc06c367d51a7772b..dd454c66207f5012f83f5f8426ec33b0dc6c2ff3 100644 (file)
@@ -11,7 +11,21 @@ import java.util.EventListener;
 
 import org.opendaylight.yangtools.yang.binding.Notification;
 
+/**
+ * Interface implemented by objects interested in some sort of Notification. This
+ * class acts as a base interface for specific listeners which usually are a type
+ * capture of this interface.
+ *
+ * @param <T> Notification type
+ */
 public interface NotificationListener<T extends Notification> extends EventListener {
-
+       /**
+        * Invoked to deliver the notification. Note that this method may be invoked
+        * from a shared thread pool, so implementations SHOULD NOT perform CPU-intensive
+        * operations and they definitely MUST NOT invoke any potentially blocking
+        * operations.
+        *
+        * @param notification Notification being delivered.
+        */
     void onNotification(T notification);
 }
index 08029dc52fa2c35fe1ea0f4b7994ef6eecf3fbe2..b94695b83d437e31194e1e862da479b787ba8d80 100644 (file)
@@ -15,24 +15,6 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 public interface NotificationProviderService extends NotificationService, NotificationPublishService<Notification> {
-
-
-    /**
-     * Deprecated. Use {@link #publish(Notification)}.
-     *
-     * @param notification
-     */
-    @Deprecated
-    void notify(Notification notification);
-
-    /**
-     * Deprecated. Use {@link #publish(Notification,ExecutorService)}.
-     *
-     * @param notification
-     */
-    @Deprecated
-    void notify(Notification notification, ExecutorService service);
-
     /**
      * Publishes a notification.
      *
index 24ca2a3de7e13073b0e61e2be930ebabf04d9436..6e8bda56d89e84e5fe0a7920ebcdfd07c2c5b84e 100644 (file)
@@ -11,39 +11,6 @@ import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
 public interface NotificationService extends BindingAwareService {
-    /**
-     *
-     * Deprecated: use {@link #addNotificationListener(Class, NotificationListener)} istead.
-     *
-     * @param listener
-     */
-    @Deprecated
-    <T extends Notification> void addNotificationListener(Class<T> notificationType, NotificationListener<T> listener);
-
-    /**
-     *
-     * Deprecated: use {@link #addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener)} istead.
-     *
-     * @param listener
-     */
-    @Deprecated
-    void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener);
-
-    /**
-     * Deprecated: use {@link Registration#close()} istead.
-     * @param listener
-     */
-    @Deprecated
-    void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener);
-
-    /**
-     * Deprecated: use {@link Registration#close()} istead.
-     * @param listener
-     */
-    @Deprecated
-    <T extends Notification> void removeNotificationListener(Class<T> notificationType, NotificationListener<T> listener);
-
-
     /**
      * Register a generic listener for specified notification type only.
      *
@@ -54,7 +21,6 @@ public interface NotificationService extends BindingAwareService {
     <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
             Class<T> notificationType, NotificationListener<T> listener);
 
-
     /**
      * Register a listener which implements generated notification interfaces derived from
      * {@link org.opendaylight.yangtools.yang.binding.NotificationListener}.
index 69a2108065b7710a658a496486eac9c1f22bc9f7..f71d69b860d5127ee0f01be5c409a319e36cfd6e 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 public interface RpcConsumerRegistry extends BindingAwareService {
     /**
      * Returns a session specific instance (implementation) of requested
-     * YANG module implentation / service provided by consumer.
+     * YANG module implementation / service provided by consumer.
      * 
      * @return Session specific implementation of service
      */
index c64e24c9c232d2aab54847713c7f5f1c7aa236dd..cdf55844b3d94d680a7a21ad052deb9a7aa73ac4 100644 (file)
@@ -25,7 +25,7 @@ public interface RpcProviderRegistry extends //
         RpcConsumerRegistry, //
         RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
     /**
-     * Registers an global RpcService implementation.
+     * Registers a global RpcService implementation.
      *
      * @param type
      * @param implementation
@@ -36,16 +36,15 @@ public interface RpcProviderRegistry extends //
 
     /**
      *
-     * Register an Routed RpcService where routing is determined on annotated
+     * Register a Routed RpcService where routing is determined on annotated
      * (in YANG model) context-reference and value of annotated leaf.
      *
      * @param type
      *            Type of RpcService, use generated interface class, not your
-     *            implementation clas
+     *            implementation class
      * @param implementation
      *            Implementation of RpcService
-     * @return Registration object for routed Rpc which could be used to close
-     *         an
+     * @return Registration object for routed Rpc which could be used to unregister
      *
      * @throws IllegalStateException
      */
index d7cb926775955084d696686611989aa1d2619266..da6d46d499317d647673cfb2b7ef5d60e43b2eae 100644 (file)
@@ -22,21 +22,21 @@ import com.google.common.base.Preconditions;
 
 /**
  * Synchronized wrapper for DataModificationTransaction.
- * 
+ *
  * To get instance of synchronized wrapper use {@link #from(DataModificationTransaction)}
  *
  */
 public final class SynchronizedTransaction implements DataModificationTransaction,Delegator<DataModificationTransaction> {
 
     private final DataModificationTransaction delegate;
-    
+
     private SynchronizedTransaction(DataModificationTransaction delegate) {
         this.delegate = delegate;
     }
 
     /**
      * Returns synchronized wrapper on supplied transaction.
-     * 
+     *
      * @param transaction Transaction for which synchronized wrapper should be created.
      * @return Synchronized wrapper over transaction.
      */
@@ -73,11 +73,6 @@ public final class SynchronizedTransaction implements DataModificationTransactio
         return delegate.getUpdatedOperationalData();
     }
 
-    @Deprecated
-    public synchronized void putRuntimeData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
-        delegate.putRuntimeData(path, data);
-    }
-
     @Override
     public synchronized Object getIdentifier() {
         return delegate.getIdentifier();
@@ -108,11 +103,6 @@ public final class SynchronizedTransaction implements DataModificationTransactio
         return delegate.getUpdatedConfigurationData();
     }
 
-    @Deprecated
-    public synchronized void removeRuntimeData(InstanceIdentifier<? extends DataObject> path) {
-        delegate.removeRuntimeData(path);
-    }
-
     @Override
     public synchronized void removeOperationalData(InstanceIdentifier<? extends DataObject> path) {
         delegate.removeOperationalData(path);
index 81fe39c62e0c927cbe43110fabe76af640b71874..0042998cd19ac7166849322b89883dba02a831b7 100644 (file)
@@ -19,7 +19,7 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 /**
  * RpcRouter is responsible for selecting RpcService based on provided routing
  * context identifier {@link RpcRoutingTable#getContextIdentifier()} and path in
- * overal data tree (@link {@link InstanceIdentifier}.
+ * overall data tree (@link {@link InstanceIdentifier}.
  *
  *
  * @author Tony Tkacik <ttkacik@cisco.com>
index ad4a1ee200501ceaa5d5647a5f507afbd19e61e2..dea455bfa1a53e3f7c02175c99905747098a9620 100644 (file)
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
+
+
                                 <generator>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
                             org.opendaylight.controller.sal.binding.codegen.*,
                             <!--org.opendaylight.controller.sal.binding.dom.*,-->
                             org.opendaylight.controller.sal.binding.osgi.*,
+                            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.binding.impl.rev131028
                         </Private-Package>
                     </instructions>
                 </configuration>
index bf82302e548404cb4969cb01046dfae5b726c330..fe2681f1f768ab6c1f607550d2c637cda1297d4e 100644 (file)
@@ -49,43 +49,10 @@ class NotificationBrokerImpl implements NotificationProviderService, AutoCloseab
         this.executor = executor;\r
     }\r
 \r
-    @Deprecated\r
-    override <T extends Notification> addNotificationListener(Class<T> notificationType,\r
-        NotificationListener<T> listener) {\r
-        listeners.put(notificationType, listener)\r
-    }\r
-\r
-    @Deprecated\r
-    override <T extends Notification> removeNotificationListener(Class<T> notificationType,\r
-        NotificationListener<T> listener) {\r
-        listeners.remove(notificationType, listener)\r
-    }\r
-\r
-    override notify(Notification notification) {\r
-        publish(notification)\r
-    }\r
-\r
     def getNotificationTypes(Notification notification) {\r
         notification.class.interfaces.filter[it != Notification && Notification.isAssignableFrom(it)]\r
     }\r
 \r
-    @Deprecated\r
-    override addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {\r
-        throw new UnsupportedOperationException("Deprecated method. Use registerNotificationListener instead.");\r
-\r
-    }\r
-\r
-    @Deprecated\r
-    override removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {\r
-        throw new UnsupportedOperationException(\r
-            "Deprecated method. Use RegisterNotificationListener returned value to close registration.")\r
-    }\r
-\r
-    @Deprecated\r
-    override notify(Notification notification, ExecutorService service) {\r
-        publish(notification, service)\r
-    }\r
-\r
     override publish(Notification notification) {\r
         publish(notification, executor)\r
     }\r
index e98d5b9942c86afb9b76e006662fe02cdf6147c2..e0c7d260b5309c2242045821a1d827ae8931c6f1 100644 (file)
@@ -7,15 +7,6 @@
  */
 package org.opendaylight.controller.sal.binding.impl;
 
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.EventListener;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.WeakHashMap;
-
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
 import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
@@ -37,12 +28,22 @@ import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.EventListener;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import static com.google.common.base.Preconditions.checkState;
+
 public class RpcProviderRegistryImpl implements //
         RpcProviderRegistry, //
         RouteChangePublisher<RpcContextIdentifier, InstanceIdentifier<?>> {
 
     private RuntimeCodeGenerator rpcFactory = SingletonHolder.RPC_GENERATOR_IMPL;
 
+    // publicProxies is a cache of proxy objects where each value in the map corresponds to a specific RpcService
     private final Map<Class<? extends RpcService>, RpcService> publicProxies = new WeakHashMap<>();
     private final Map<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = new WeakHashMap<>();
     private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
index a58df8435b8f85d5b54f718cae4f4ff27d088af7..145dc37552329335fcb4e6198fe70ff302f7f560 100644 (file)
@@ -36,7 +36,7 @@
                                         org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                                     </codeGeneratorClass>
                                     <outputBaseDir>
-                                        target/generated-sources/sal
+                                        ${salGeneratorPath}
                                     </outputBaseDir>
                                 </generator>
                                 <generator>
index 213e4f47f759026215fb7824dc214eb092c7416d..520935ca9052f89d1cc6ce1b9a6363764c4e91e8 100644 (file)
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>config-netconf-connector</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>yang-store-impl</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>logback-config</artifactId>
index e8a52d069d72825c1cf71a6e9511abc70e900edd..0a71ef5315ebde5338fbe32ab73f1934b2260f01 100644 (file)
@@ -7,15 +7,15 @@
  */
 package org.opendaylight.controller.test.sal.binding.it;
 
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.options.DefaultCompositeOption;
+import org.ops4j.pax.exam.util.PathUtils;
+
 import static org.ops4j.pax.exam.CoreOptions.frameworkProperty;
 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.options.DefaultCompositeOption;
-import org.ops4j.pax.exam.util.PathUtils;
-
 public class TestHelper {
 
     public static final String CONTROLLER = "org.opendaylight.controller";
@@ -50,8 +50,6 @@ public class TestHelper {
                 mavenBundle("commons-io", "commons-io").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "config-manager").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "yang-jmx-generator").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "yang-store-api").versionAsInProject(), //
-                mavenBundle(CONTROLLER, "yang-store-impl").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "logback-config").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "config-persister-api").versionAsInProject(), //
                 mavenBundle(CONTROLLER, "netconf-api").versionAsInProject(), //
@@ -129,7 +127,6 @@ public class TestHelper {
                 systemProperty("netconf.config.persister.1.properties.fileStorage")
                         .value(PathUtils.getBaseDir() + "/src/test/resources/controller.xml"), //
                 systemProperty("netconf.config.persister.1.properties.numberOfBackups").value("1") //
-                //systemProperty("yangstore.blacklist").value(".*controller.model.*") //
 
         );
 
index 9ac94e7b8904a3148128ca0f01f6b7d6a72fa5d0..019fc0eb73949a55163c8ddd7b9dcc2bee065037 100644 (file)
@@ -25,6 +25,7 @@ import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAn
 import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
 import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemPackages;
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
 
 @RunWith(PaxExam.class)
@@ -70,6 +71,7 @@ public abstract class AbstractTest {
                 mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
                 systemProperty("osgi.bundles.defaultStartLevel").value("4"),
+                systemPackages("sun.nio.ch"),
 
                 mdSalCoreBundles(),
 
index 64c1ad3ab4035e173858dfacbae6536567aece93..7d7e56dae0ac824d4cacf84f8750a893de549283 100644 (file)
@@ -71,32 +71,6 @@ public abstract class AbstractBindingSalConsumerInstance<D extends DataBrokerSer
         return getRpcRegistryChecked().getRpcService(module);
     }
 
-    @Override
-    @Deprecated
-    public <T extends Notification> void addNotificationListener(Class<T> notificationType,
-            NotificationListener<T> listener) {
-        getNotificationBrokerChecked().addNotificationListener(notificationType, listener);
-    }
-
-    @Override
-    @Deprecated
-    public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
-        getNotificationBrokerChecked().addNotificationListener(listener);
-    }
-
-    @Override
-    @Deprecated
-    public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
-        getNotificationBrokerChecked().removeNotificationListener(listener);
-    }
-
-    @Override
-    @Deprecated
-    public <T extends Notification> void removeNotificationListener(Class<T> notificationType,
-            NotificationListener<T> listener) {
-        getNotificationBrokerChecked().removeNotificationListener(notificationType, listener);
-    }
-
     @Override
     public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
             Class<T> notificationType, NotificationListener<T> listener) {
index efa02e0b301303d9a3444771f15afe4df64d1ec0..8f367de6c8976c687600a941b491aff4fcbfeb2f 100644 (file)
@@ -71,18 +71,6 @@ public abstract class AbstractBindingSalProviderInstance<D extends DataProviderS
         return getRpcRegistryChecked().addRoutedRpcImplementation(type, implementation);
     }
 
-    @Override
-    @Deprecated
-    public void notify(Notification notification) {
-        getNotificationBrokerChecked().notify(notification);
-    }
-
-    @Override
-    @Deprecated
-    public void notify(Notification notification, ExecutorService service) {
-        getNotificationBrokerChecked().notify(notification, service);
-    }
-
     @Override
     public void publish(Notification notification) {
         getNotificationBrokerChecked().publish(notification);
index 8a2571c727c5e89dbaf8a764fda5bdf4b6199dec..126fe8d39eebb2c745ba1a85bf34a2dffca55df1 100644 (file)
   </scm>
 
     <dependencies>
-        <dependency>
-            <groupId>org.opendaylight.controller</groupId>
-            <artifactId>sal-common</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-common</artifactId>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>concepts</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
     </dependencies>
     <packaging>bundle</packaging>
 </project>
index 30f4fc03cb18b13e0d518c7b237f10e471a190f6..22e95197bb4c2fb9c3886492cf7635cacf18c7d2 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.md.sal.common.api.data;
 
-import org.opendaylight.controller.sal.common.DataStoreIdentifier;
 import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 /**
index f6662c388aa36e0092cf0ec8b5f262dcf981d163..22c5fa0c1d25eb4a71e19b2b271a5a777dada2e3 100644 (file)
@@ -14,7 +14,6 @@ import org.opendaylight.yangtools.concepts.Path;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 
 public interface DataModification<P extends Path<P>, D> extends DataChange<P, D>, DataReader<P, D> {
-
     /**
      * Returns transaction identifier
      *
@@ -24,16 +23,6 @@ public interface DataModification<P extends Path<P>, D> extends DataChange<P, D>
 
     TransactionStatus getStatus();
 
-    /**
-     *
-     * @deprecated Use {@link #putOperationalData(Object, Object)} instead.
-     *
-     * @param path
-     * @param data
-     */
-    @Deprecated
-    void putRuntimeData(P path, D data);
-
     /**
      * Store a piece of data at specified path. This acts as a merge operation,
      * which is to say that any pre-existing data which is not explicitly
@@ -76,14 +65,6 @@ public interface DataModification<P extends Path<P>, D> extends DataChange<P, D>
      */
     void putConfigurationData(P path, D data);
 
-    /**
-     * @deprecated Use {@link #removeOperationalData(Object)}
-     *
-     * @param path
-     */
-    @Deprecated
-    void removeRuntimeData(P path);
-
     void removeOperationalData(P path);
 
     void removeConfigurationData(P path);
@@ -112,5 +93,4 @@ public interface DataModification<P extends Path<P>, D> extends DataChange<P, D>
      *         {@link TransactionStatus#FAILED} is reached.
      */
     Future<RpcResult<TransactionStatus>> commit();
-
 }
index 4b6a0185ab81ecc1bdaf2799de15b1a6af33ff7b..3ceeb7e44db980855d4afad4b05d1489b0135f96 100644 (file)
@@ -41,7 +41,7 @@ public abstract class AbstractDataModification<P extends Path<P>, D> implements
     private final Map<P, D> unmodifiable_operationalUpdate;
     private final Set<P> unmodifiable_configurationRemove;
     private final Set<P> unmodifiable_OperationalRemove;
-    private DataReader<P, D> reader;
+    private final DataReader<P, D> reader;
 
     public AbstractDataModification(DataReader<P, D> reader) {
         this.reader = reader;
@@ -87,11 +87,6 @@ public abstract class AbstractDataModification<P extends Path<P>, D> implements
         operationalUpdate.put(path, mergeOperationalData(path,original,data));
     }
 
-    @Override
-    public final void putRuntimeData(P path, D data) {
-        putOperationalData(path, data);
-    }
-
     @Override
     public final void removeOperationalData(P path) {
         checkMutable();
@@ -100,11 +95,6 @@ public abstract class AbstractDataModification<P extends Path<P>, D> implements
         operationalRemove.put(path, path);
     }
 
-    @Override
-    public final void removeRuntimeData(P path) {
-        removeOperationalData(path);
-    }
-
     @Override
     public final void removeConfigurationData(P path) {
         checkMutable();
@@ -194,11 +184,11 @@ public abstract class AbstractDataModification<P extends Path<P>, D> implements
         }
         return null;
     }
-    
+
     protected D mergeOperationalData(P path,D stored, D modified) {
         return modified;
     }
-    
+
     protected D mergeConfigurationData(P path,D stored, D modified) {
         return modified;
     }
diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractRegistration.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/AbstractRegistration.java
deleted file mode 100644 (file)
index bb8594f..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014 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.md.sal.common.impl;
-
-import org.opendaylight.yangtools.concepts.Registration;
-
-public abstract class AbstractRegistration<T> implements Registration<T> {
-
-
-    private final T instance;
-
-    public AbstractRegistration(T instance) {
-        super();
-        this.instance = instance;
-    }
-
-    @Override
-    public final T getInstance() {
-        return instance;
-    }
-
-}
index 4ffb87d5d3939e39662833a3ef8b64954ae30965..22c458a507975027136ddf66ad45986ca00d7c1d 100644 (file)
@@ -8,9 +8,10 @@
 package org.opendaylight.controller.md.sal.common.impl;
 
 import org.opendaylight.controller.md.sal.common.api.routing.RoutedRegistration;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
 import org.opendaylight.yangtools.concepts.Path;
 
-public abstract class AbstractRoutedRegistration<C, P extends Path<P>, S> extends AbstractRegistration<S> implements
+public abstract class AbstractRoutedRegistration<C, P extends Path<P>, S> extends AbstractObjectRegistration<S> implements
         RoutedRegistration<C, P, S> {
 
     public AbstractRoutedRegistration(S instance) {
index ed186dcf314fd0ea075ad81bc3b3e19fb942a48b..82ce44c5e994835ff5e484c951639defca407227 100644 (file)
@@ -406,7 +406,6 @@ public abstract class AbstractDataBroker<P extends Path<P>, D extends Object, DC
 
     final Future<RpcResult<TransactionStatus>> commit(final AbstractDataTransaction<P, D> transaction) {
         Preconditions.checkNotNull(transaction);
-        transaction.changeStatus(TransactionStatus.SUBMITED);
         final TwoPhaseCommit<P, D, DCL> task = new TwoPhaseCommit<P, D, DCL>(transaction, this);
 
         this.getSubmittedTransactionsCount().getAndIncrement();
index c73a62779921d74837d96eb9c06a3f274f06cf1b..b030e6cb5f84b8da49d1780ab51ec2e7ab425ede 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.controller.md.sal.common.impl.service;
 
 import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
 
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.md.sal.common.impl.AbstractDataModification;
@@ -16,33 +17,41 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@SuppressWarnings("all")
+import com.google.common.base.Preconditions;
+
 public abstract class AbstractDataTransaction<P extends Path<P>, D extends Object> extends
         AbstractDataModification<P, D> {
     private final static Logger LOG = LoggerFactory.getLogger(AbstractDataTransaction.class);
 
     private final Object identifier;
+    private final long allocationTime;
+    private long readyTime = 0;
+    private long completeTime = 0;
 
-    @Override
-    public Object getIdentifier() {
-        return this.identifier;
-    }
-
-    private TransactionStatus status;
+    private TransactionStatus status = TransactionStatus.NEW;
 
     private final AbstractDataBroker<P, D, ? extends Object> broker;
 
     protected AbstractDataTransaction(final Object identifier,
             final AbstractDataBroker<P, D, ? extends Object> dataBroker) {
         super(dataBroker);
-        this.identifier = identifier;
-        this.broker = dataBroker;
-        this.status = TransactionStatus.NEW;
-        AbstractDataTransaction.LOG.debug("Transaction {} Allocated.", identifier);
+        this.identifier = Preconditions.checkNotNull(identifier);
+        this.broker = Preconditions.checkNotNull(dataBroker);
+        this.allocationTime = System.nanoTime();
+        LOG.debug("Transaction {} Allocated.", identifier);
+    }
+
+    @Override
+    public Object getIdentifier() {
+        return this.identifier;
     }
 
     @Override
     public Future<RpcResult<TransactionStatus>> commit() {
+        readyTime = System.nanoTime();
+        LOG.debug("Transaction {} Ready after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(readyTime - allocationTime));
+        changeStatus(TransactionStatus.SUBMITED);
+
         return this.broker.commit(this);
     }
 
@@ -64,8 +73,6 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D extends Objec
         return this.broker.readOperationalData(path);
     }
 
-
-
     @Override
     public int hashCode() {
         final int prime = 31;
@@ -82,7 +89,7 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D extends Objec
             return false;
         if (getClass() != obj.getClass())
             return false;
-        AbstractDataTransaction other = (AbstractDataTransaction) obj;
+        AbstractDataTransaction<?, ?> other = (AbstractDataTransaction<?, ?>) obj;
         if (identifier == null) {
             if (other.identifier != null)
                 return false;
@@ -98,10 +105,20 @@ public abstract class AbstractDataTransaction<P extends Path<P>, D extends Objec
 
     protected abstract void onStatusChange(final TransactionStatus status);
 
-    public void changeStatus(final TransactionStatus status) {
-        Object _identifier = this.getIdentifier();
-        AbstractDataTransaction.LOG
-                .debug("Transaction {} transitioned from {} to {}", _identifier, this.status, status);
+    public void succeeded() {
+        this.completeTime = System.nanoTime();
+        LOG.debug("Transaction {} Committed after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(completeTime - readyTime));
+        changeStatus(TransactionStatus.COMMITED);
+    }
+
+    public void failed() {
+        this.completeTime = System.nanoTime();
+        LOG.debug("Transaction {} Failed after {}ms.", identifier, TimeUnit.NANOSECONDS.toMillis(completeTime - readyTime));
+        changeStatus(TransactionStatus.FAILED);
+    }
+
+    private void changeStatus(final TransactionStatus status) {
+        LOG.debug("Transaction {} transitioned from {} to {}", getIdentifier(), this.status, status);
         this.status = status;
         this.onStatusChange(status);
     }
index e201f8835b84182a9f22e9c712a2f8cc0073836f..a51dc64816d0822778ff1b690bd10fdd19268afa 100644 (file)
@@ -64,7 +64,7 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
         // The transaction has no effects, let's just shortcut it
         if (changedPaths.isEmpty()) {
             dataBroker.getFinishedTransactionsCount().getAndIncrement();
-            transaction.changeStatus(TransactionStatus.COMMITED);
+            transaction.succeeded();
 
             log.trace("Transaction: {} Finished successfully (no effects).", transactionId);
 
@@ -98,7 +98,7 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
         } catch (Exception e) {
             log.error("Transaction: {} Request Commit failed", transactionId, e);
             dataBroker.getFailedTransactionsCount().getAndIncrement();
-            this.transaction.changeStatus(TransactionStatus.FAILED);
+            this.transaction.failed();
             return this.rollback(handlerTransactions, e);
 
         }
@@ -112,13 +112,13 @@ public class TwoPhaseCommit<P extends Path<P>, D extends Object, DCL extends Dat
         } catch (Exception e) {
             log.error("Transaction: {} Finish Commit failed", transactionId, e);
             dataBroker.getFailedTransactionsCount().getAndIncrement();
-            transaction.changeStatus(TransactionStatus.FAILED);
+            transaction.failed();
             return this.rollback(handlerTransactions, e);
         }
 
 
         dataBroker.getFinishedTransactionsCount().getAndIncrement();
-        transaction.changeStatus(TransactionStatus.COMMITED);
+        transaction.succeeded();
 
         log.trace("Transaction: {} Finished successfully.", transactionId);
 
index 9eadce3ed7cb0d35885f3239637ee0478b150002..15932d56cedf1df6cc76ca35a323bcd28cdc8992 100644 (file)
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
                                 <generator>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
index 6af06255c7ef3adbbfd526404babf70b4b285a6b..72df8cb55348cb08fec5a4bad8d35daa125e2ecf 100644 (file)
@@ -16,7 +16,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.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -237,7 +237,7 @@ public interface Broker {
         ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
     }
 
-    public interface RpcRegistration extends Registration<RpcImplementation> {
+    public interface RpcRegistration extends ObjectRegistration<RpcImplementation> {
         QName getType();
 
         @Override
index 18c854646cca6aa08596a84ddaeba77959129219..5698b969771bd4296cbcb8d85ebbd03fcbca59ae 100644 (file)
@@ -8,8 +8,6 @@
 
 package org.opendaylight.controller.sal.core.api.mount;
 
-import java.util.concurrent.Future;
-
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.core.api.notify.NotificationService;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -17,11 +15,29 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Interface representing a single mount instance and represents a way for
+ * clients to access underlying data, RPCs and notifications.
+ */
 public interface MountInstance extends //
         NotificationService, //
         DataBrokerService {
 
-    Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
+    /**
+     * Invoke an RPC on the system underlying the mount instance.
+     *
+     * @param type RPC type
+     * @param input RPC input arguments
+     * @return Future representing execution of the RPC.
+     */
+    ListenableFuture<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input);
 
+    /**
+     * Get {@link SchemaContext} of the system underlying the mount instance.
+     *
+     * @return A schema context.
+     */
     SchemaContext getSchemaContext();
 }
index c4c7889f579526a8626a59ab6952ddd6bc151a95..1185c4528cee3e60bbc7bba70ab3beddc5eac021 100644 (file)
@@ -16,18 +16,18 @@ public interface MountProvisionService extends MountService {
 
     @Override
     public MountProvisionInstance getMountPoint(InstanceIdentifier path);
-    
+
     MountProvisionInstance createMountPoint(InstanceIdentifier path);
-    
+
     MountProvisionInstance createOrGetMountPoint(InstanceIdentifier path);
-    
+
     ListenerRegistration<MountProvisionListener> registerProvisionListener(MountProvisionListener listener);
-    
-    public  interface MountProvisionListener extends EventListener {
-        
+
+    public interface MountProvisionListener extends EventListener {
+
         void onMountPointCreated(InstanceIdentifier path);
-        
+
         void onMountPointRemoved(InstanceIdentifier path);
-        
+
     }
 }
index 3180271c935311a64bb69a66b7264ab1ef72cb2a..6d1f17255c7defd4a0e61a890d0b6246b4b466a1 100644 (file)
@@ -10,8 +10,16 @@ package org.opendaylight.controller.sal.core.api.mount;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 
-
+/**
+ * Client-level interface for interacting with mount points. It provides access
+ * to {@link MountInstance} instances based on their path.
+ */
 public interface MountService extends BrokerService {
-
+    /**
+     * Obtain access to a mount instance registered at the specified path.
+     *
+     * @param path Path at which the instance is registered
+     * @return Reference to the instance, or null if no such instance exists.
+     */
     MountInstance getMountPoint(InstanceIdentifier path);
 }
index 652eab10a75e6e4091e934d5f226ba18d181b2fd..aa22b90f65478092374d53d06961e6c09f5fbcd7 100644 (file)
@@ -11,7 +11,6 @@ import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
-
 /**
  * Notification Publishing Service
  * 
@@ -25,12 +24,8 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
  * <li>For each subscriber {@link Broker} invokes
  * {@link NotificationListener#onNotification(CompositeNode)}
  * </ol>
- * 
- * 
- * 
  */
 public interface NotificationPublishService extends NotificationService {
-
     /**
      * Publishes a notification.
      * 
@@ -41,8 +36,5 @@ public interface NotificationPublishService extends NotificationService {
      * @param notification
      *            Notification to publish
      */
-    @Deprecated
-    void sendNotification(CompositeNode notification);
-
     void publish(CompositeNode notification);
 }
index 225281e7a400fa3aefb3c0d38c85b08c48b77daa..d192bea54036ff62d3680c8561e816b330fbebbb 100644 (file)
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
                                 <generator>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
                             org.opendaylight.controller.sal.dom.broker.util,
                             org.opendaylight.controller.config.yang.md.sal.dom.impl,
                             org.opendaylight.controller.config.yang.md.sal.dom.statistics,
-                            org.opendaylight.yangtools.yang.util
+                            org.opendaylight.yangtools.yang.util,
+                            org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*
                         </Private-Package>
                         <Import-Package>
                             *
index 5d93f4ee4d162b22a35c610d4f79b35e7cf66fb6..f9f977e3c24d67abe809ce2f3648df5f63960d83 100644 (file)
@@ -9,7 +9,6 @@ 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.RegistrationListener;
 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
@@ -41,14 +40,16 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+import com.google.common.util.concurrent.ListenableFuture;
+
 public class MountPointImpl implements MountProvisionInstance, SchemaContextProvider {
 
     private final SchemaAwareRpcBroker rpcs;
     private final DataBrokerImpl dataReader;
     private final NotificationRouter notificationRouter;
     private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
-    
-    
+
+
     private final InstanceIdentifier mountPath;
 
     private SchemaContext schemaContext;
@@ -89,11 +90,13 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
         return dataReader.readOperationalData(path);
     }
 
+    @Override
     public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerOperationalReader(
             InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
         return dataReader.registerOperationalReader(path, reader);
     }
 
+    @Override
     public Registration<DataReader<InstanceIdentifier, CompositeNode>> registerConfigurationReader(
             InstanceIdentifier path, DataReader<InstanceIdentifier, CompositeNode> reader) {
         return dataReader.registerConfigurationReader(path, reader);
@@ -115,22 +118,25 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
         return rpcs.addRpcImplementation(rpcType, implementation);
     }
 
+    @Override
     public Set<QName> getSupportedRpcs() {
         return rpcs.getSupportedRpcs();
     }
 
-    
+
+    @Override
     public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
         return rpcs.invokeRpc(rpc, input);
     }
 
+    @Override
     public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
         return rpcs.addRpcRegistrationListener(listener);
     }
 
 
     @Override
-    public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
+    public ListenableFuture<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
         return null;
     }
 
@@ -145,27 +151,22 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
         return dataReader.registerDataChangeListener(path, listener);
     }
 
-    @Override
-    public void sendNotification(CompositeNode notification) {
-        publish(notification);
-    }
-    
     @Override
     public Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registerCommitHandler(
             InstanceIdentifier path, DataCommitHandler<InstanceIdentifier, CompositeNode> commitHandler) {
         return dataReader.registerCommitHandler(path, commitHandler);
     }
-    
+
     @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
@@ -174,18 +175,20 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     public void removeValidator(DataStoreIdentifier store, DataValidator validator) {
         // NOOP
     }
-    
+
+    @Override
     public SchemaContext getSchemaContext() {
         return schemaContext;
     }
 
+    @Override
     public void setSchemaContext(SchemaContext schemaContext) {
         this.schemaContext = schemaContext;
     }
 
     class ReadWrapper implements DataReader<InstanceIdentifier, CompositeNode> {
-        
-        
+
+
         private InstanceIdentifier shortenPath(InstanceIdentifier path) {
             InstanceIdentifier ret = null;
             if(mountPath.contains(path)) {
@@ -194,7 +197,7 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
             }
             return ret;
         }
-        
+
         @Override
         public CompositeNode readConfigurationData(InstanceIdentifier path) {
             InstanceIdentifier newPath = shortenPath(path);
@@ -203,7 +206,7 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
             }
             return MountPointImpl.this.readConfigurationData(newPath);
         }
-        
+
         @Override
         public CompositeNode readOperationalData(InstanceIdentifier path) {
             InstanceIdentifier newPath = shortenPath(path);
index bbe017f009e445f2ab7e21e7d19b748d3f5365f0..b298a02a633cda2760347417266bb4d06e48dbca 100644 (file)
@@ -171,18 +171,13 @@ public class NotificationModule implements BrokerModule {
             NotificationPublishService {
 
         @Override
-        public void sendNotification(CompositeNode notification) {
+        public void publish(CompositeNode notification) {
             checkSessionState();
             if (notification == null)
                 throw new IllegalArgumentException(
                         "Notification must not be null.");
             NotificationModule.this.sendNotification(notification);
         }
-
-        @Override
-        public void publish(CompositeNode notification) {
-            sendNotification(notification);
-        }
     }
 
     @Override
index 50af3fbfc1f097662ae4f0a8f1e1084cb87aab96..7fba31114f6d53a2c491f91511109a32b6c8efec 100644 (file)
@@ -11,7 +11,7 @@ import java.util.Collection;
 
 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
 import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
 import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
@@ -25,12 +25,12 @@ import com.google.common.collect.Multimaps;
 public class NotificationRouterImpl implements NotificationRouter {
     private static Logger log = LoggerFactory.getLogger(NotificationRouterImpl.class);
 
-    private final Multimap<QName, Registration<NotificationListener>> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.<QName, Registration<NotificationListener>>create());
+    private final Multimap<QName, ListenerRegistration> listeners = Multimaps.synchronizedSetMultimap(HashMultimap.<QName, ListenerRegistration>create());
 //    private Registration<NotificationListener> defaultListener;
 
     private void sendNotification(CompositeNode notification) {
         final QName type = notification.getNodeType();
-        final Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
+        final Collection<ListenerRegistration> toNotify = listeners.get(type);
         log.trace("Publishing notification " + type);
 
         if ((toNotify == null) || toNotify.isEmpty()) {
@@ -38,7 +38,7 @@ public class NotificationRouterImpl implements NotificationRouter {
             return;
         }
 
-        for (Registration<NotificationListener> listener : toNotify) {
+        for (ListenerRegistration listener : toNotify) {
             try {
                 // FIXME: ensure that notification is immutable
                 listener.getInstance().onNotification(notification);
@@ -60,7 +60,7 @@ public class NotificationRouterImpl implements NotificationRouter {
         return ret;
     }
 
-    private class ListenerRegistration extends AbstractObjectRegistration<NotificationListener> {
+    private class ListenerRegistration extends AbstractListenerRegistration<NotificationListener> {
 
         final QName type;
 
index fc8ccd674614a355de65c54a3149b9ac56207067..e49a28d8e07217afb0bca0dfac26fc065842e9f8 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.controller.sal.dom.broker.impl;
 
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public interface SchemaContextProvider {
-
-    SchemaContext getSchemaContext();
+/**
+ * @deprecated Use org.opendaylight.yangtools.yang.model.api.SchemaContextProvider instead
+ */
+@Deprecated
+public interface SchemaContextProvider extends org.opendaylight.yangtools.yang.model.api.SchemaContextProvider{
 
 }
index 8a15d84f99b4f1936021ade251dc9a6bfc498c03..cd26c4ea5c51f1f8d0283d8fb40803954528e48b 100644 (file)
@@ -21,15 +21,13 @@ public class NotificationPublishServiceProxy extends AbstractBrokerServiceProxy<
         super(ref, delegate);
     }
 
-    public void sendNotification(CompositeNode notification) {
-        getDelegate().sendNotification(notification);
-    }
-
+    @Override
     public Registration<NotificationListener> addNotificationListener(QName notification, NotificationListener listener) {
         return addRegistration(getDelegate().addNotificationListener(notification, listener));
 
     }
 
+    @Override
     public void publish(CompositeNode notification) {
         getDelegate().publish(notification);
     }
index 33cd94d6a8ca6dccce75868190893a376f3608cb..777709b06ae122bf3333b7e6a2e9e3e7d84acc49 100644 (file)
             <version>${netconf.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-api</artifactId>
-            <version>${netconf.version}</version>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-client</artifactId>
             <type>test-jar</type>
             <version>${netconf.version}</version>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <scope>test</scope>
-            <version>${netconf.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <scope>test</scope>
-            <type>test-jar</type>
-            <version>${netconf.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>logback-config</artifactId>
                     </instructions>
                 </configuration>
             </plugin>
+
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
                         </goals>
                         <configuration>
                             <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
                                 <generator>
                                     <codeGeneratorClass>
                                         org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
                     </dependency>
                 </dependencies>
             </plugin>
+
             <plugin>
                 <groupId>org.codehaus.mojo</groupId>
                 <artifactId>build-helper-maven-plugin</artifactId>
index 090c56f67dd0c431f8df2b24ae4e123c5b35190c..15bd2e7a303f73caa644eed78e20330f27b6467a 100644 (file)
@@ -43,7 +43,7 @@
                                         org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                                     </codeGeneratorClass>
                                     <outputBaseDir>
-                                        target/generated-sources/
+                                        ${salGeneratorPath}
                                     </outputBaseDir>
                                 </generator>
                                 <generator>
index 9a8f14980dca58035e3961db7c331f55d1ffd0fd..415ae5aa052ef76a6a3379f1480875543004955f 100644 (file)
     <dependency>
       <groupId> ch.qos.logback</groupId>
       <artifactId>logback-classic</artifactId>
-      <version>1.0.9</version>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-annotations</artifactId>
-      <version>${jackson.version}</version>
     </dependency>
 
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-core</artifactId>
-      <version>${jackson.version}</version>
     </dependency>
 
     <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
-      <version>${jackson.version}</version>
     </dependency>
 
     <dependency>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
-                <version>${bundle.plugin.version}</version>
                 <extensions>true</extensions>
                 <configuration>
                     <instructions>
                         <Import-Package>
                             *,
-                            com.google.common.collect,
                             !org.codehaus.enunciate.jaxrs
                         </Import-Package>
                         <Export-Package>
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>${yangtools.version}</version>
                 <executions>
                     <execution>
                         <goals>
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>target/site/models</outputBaseDir>
+                                </generator>
+
                                 <generator>
                                     <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
                                     <outputBaseDir>target/site/models</outputBaseDir>
index 8813ee9613448a49e66370e2d163d0e13115189a..3e73f161c28df060f33e9f658b8eb4d60d30f5ac 100644 (file)
             <version>${netconf.version}</version>
             <scope>test</scope>
         </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>
index 0683c45ebc82b7997a02cdbbceb90658a391fe5b..067b7d96ec8c94f0af3bef597621c1c7d62586f7 100644 (file)
@@ -141,4 +141,11 @@ public interface RestconfService {
     @Path("/streams/stream/{identifier:.+}")
     public Response subscribeToStream(@Encoded @PathParam("identifier") String identifier, @Context UriInfo uriInfo);
 
+    @GET
+    @Path("/streams")
+    @Produces({Draft02.MediaTypes.API+XML, Draft02.MediaTypes.API+JSON,
+            MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML})
+    public StructuredData getAvailableStreams();
+
+
 }
index e09dc7ac017d143c65f45564beeb1783ed97a8be..8ebf28f35f1771ec778fc6e1a5b16088f6aafe16 100644 (file)
@@ -60,6 +60,8 @@ class RestconfImpl implements RestconfService {
     val static RESTCONF_MODULE_DRAFT02_RESTCONF_CONTAINER_SCHEMA_NODE = "restconf"
     val static RESTCONF_MODULE_DRAFT02_MODULES_CONTAINER_SCHEMA_NODE = "modules"
     val static RESTCONF_MODULE_DRAFT02_MODULE_LIST_SCHEMA_NODE = "module"
+    val static RESTCONF_MODULE_DRAFT02_STREAMS_CONTAINER_SCHEMA_NODE = "streams"
+    val static RESTCONF_MODULE_DRAFT02_STREAM_LIST_SCHEMA_NODE = "stream"
     val static RESTCONF_MODULE_DRAFT02_OPERATIONS_CONTAINER_SCHEMA_NODE = "operations"
     val static SAL_REMOTE_NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote"
     val static SAL_REMOTE_RPC_SUBSRCIBE = "create-data-change-event-subscription"
@@ -92,6 +94,17 @@ class RestconfImpl implements RestconfService {
         return new StructuredData(modulesNode, modulesSchemaNode, null)
     }
 
+    override getAvailableStreams(){
+        var Set<String> availableStreams = Notificator.getStreamNames();
+        val List<Node<?>> streamsAsData = new ArrayList
+        val streamSchemaNode = restconfModule.getSchemaNode(RESTCONF_MODULE_DRAFT02_STREAM_LIST_SCHEMA_NODE)
+        for (String streamName:availableStreams){
+            streamsAsData.add(streamName.toStreamCompositeNode(streamSchemaNode))
+        }
+        val streamsSchemaNode = restconfModule.getSchemaNode(RESTCONF_MODULE_DRAFT02_STREAMS_CONTAINER_SCHEMA_NODE)
+        val streamsNode = NodeFactory.createImmutableCompositeNode(streamsSchemaNode.QName, null, streamsAsData)
+        return new StructuredData(streamsNode, streamsSchemaNode, null)
+    }
     override getModules(String identifier) {
         var Set<Module> modules = null
         var MountInstance mountPoint = null
@@ -196,6 +209,25 @@ class RestconfImpl implements RestconfService {
         }
     }
 
+    private def CompositeNode toStreamCompositeNode(String streamName, DataSchemaNode streamSchemaNode) {
+        val List<Node<?>> streamNodeValues = new ArrayList
+        val nameSchemaNode = (streamSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("name").head
+        streamNodeValues.add(NodeFactory.createImmutableSimpleNode(nameSchemaNode.QName, null, streamName))
+
+        val descriptionSchemaNode = (streamSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("description").head
+        streamNodeValues.add(NodeFactory.createImmutableSimpleNode(descriptionSchemaNode.QName, null, "DESCRIPTION_PLACEHOLDER"))
+
+        val replaySupportSchemaNode = (streamSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("replay-support").head
+        streamNodeValues.add(NodeFactory.createImmutableSimpleNode(replaySupportSchemaNode.QName, null, true))
+
+        val replayLogCreationTimeSchemaNode = (streamSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("replay-log-creation-time").head
+        streamNodeValues.add(NodeFactory.createImmutableSimpleNode(replayLogCreationTimeSchemaNode.QName, null, ""))
+
+        val eventsSchemaNode = (streamSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("events").head
+        streamNodeValues.add(NodeFactory.createImmutableSimpleNode(eventsSchemaNode.QName, null, ""))
+
+        return NodeFactory.createImmutableCompositeNode(streamSchemaNode.QName, null, streamNodeValues)
+    }
     private def CompositeNode toModuleCompositeNode(Module module, DataSchemaNode moduleSchemaNode) {
         val List<Node<?>> moduleNodeValues = new ArrayList
         val nameSchemaNode = (moduleSchemaNode as DataNodeContainer).findInstanceDataChildrenByName("name").head
@@ -216,7 +248,12 @@ class RestconfImpl implements RestconfService {
         val restconfContainer = restconfGrouping.findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_RESTCONF_CONTAINER_SCHEMA_NODE).head
         if (schemaNodeName == RESTCONF_MODULE_DRAFT02_OPERATIONS_CONTAINER_SCHEMA_NODE) {
             return (restconfContainer as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_OPERATIONS_CONTAINER_SCHEMA_NODE).head
-        } else if (schemaNodeName == RESTCONF_MODULE_DRAFT02_MODULES_CONTAINER_SCHEMA_NODE) {
+        } else if (schemaNodeName == RESTCONF_MODULE_DRAFT02_STREAMS_CONTAINER_SCHEMA_NODE) {
+           return (restconfContainer as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_STREAMS_CONTAINER_SCHEMA_NODE).head
+        } else if (schemaNodeName == RESTCONF_MODULE_DRAFT02_STREAM_LIST_SCHEMA_NODE) {
+           val modules = (restconfContainer as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_STREAMS_CONTAINER_SCHEMA_NODE).head
+           return (modules as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_STREAM_LIST_SCHEMA_NODE).head
+        }else if (schemaNodeName == RESTCONF_MODULE_DRAFT02_MODULES_CONTAINER_SCHEMA_NODE) {
             return (restconfContainer as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_MODULES_CONTAINER_SCHEMA_NODE).head
         } else if (schemaNodeName == RESTCONF_MODULE_DRAFT02_MODULE_LIST_SCHEMA_NODE) {
             val modules = (restconfContainer as DataNodeContainer).findInstanceDataChildrenByName(RESTCONF_MODULE_DRAFT02_MODULES_CONTAINER_SCHEMA_NODE).head
index 36c9c67ffcd3281db279c858176291f4da571ef7..9c8351aa99fdecc737508a7b0487c95f39582495 100644 (file)
@@ -1,6 +1,7 @@
 package org.opendaylight.controller.sal.streams.listeners;
 
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -12,13 +13,21 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
  */
 public class Notificator {
 
-       private static Map<String, ListenerAdapter> listenersByStreamName = new ConcurrentHashMap<>();
+    private static Map<String, ListenerAdapter> listenersByStreamName = new ConcurrentHashMap<>();
        private static Map<InstanceIdentifier, ListenerAdapter> listenersByInstanceIdentifier = new ConcurrentHashMap<>();
        private static final Lock lock = new ReentrantLock();
 
        private Notificator() {
        }
 
+    /**
+     * Returns list of all stream names
+     */
+    public static Set<String> getStreamNames() {
+        return listenersByStreamName.keySet();
+    }
+
+
        /**
         * Gets {@link ListenerAdapter} specified by stream name.
         * 
@@ -132,7 +141,7 @@ public class Notificator {
        }
 
        /**
-        * Checks if listener has at least one subscriber. In case it has any, delete
+        * Checks if listener has at least one subscriber. In case it doesn't have any, delete
         * listener.
         * 
         * @param listener
index d7b4bd9d9e0754c2bfc71958a845820c39eab8f1..16400354205a68cbf6993760f9dfa3fee04ec37a 100644 (file)
@@ -1,16 +1,15 @@
 package org.opendaylight.controller.sal.streams.websockets;
 
-import org.opendaylight.controller.sal.streams.listeners.Notificator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import io.netty.bootstrap.ServerBootstrap;
 import io.netty.channel.Channel;
-import io.netty.channel.ChannelPipeline;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.channel.socket.nio.NioServerSocketChannel;
 
+import org.opendaylight.controller.sal.streams.listeners.Notificator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 /**
  * {@link WebSocketServer} is responsible to start and stop web socket server at
  * {@link #PORT}.
index 18b5ce490ff137f7da978052a09819a6a5b4e1d1..0492b3efd4f1b7a1696c1452a5d69ee9fec07c12 100644 (file)
@@ -124,7 +124,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
             if (nextEvent.isStartElement()) {
                 StartElement startElement = (StartElement) nextEvent;
                 if (startElement.getName().getLocalPart().equals("lf111")) {
-                    Iterator prefixes = startElement.getNamespaceContext().getPrefixes("augment:augment:module");
+                    Iterator<?> prefixes = startElement.getNamespaceContext().getPrefixes("augment:augment:module");
 
                     while (prefixes.hasNext() && aaModulePrefix == null) {
                         String prefix = (String) prefixes.next();
@@ -164,7 +164,7 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
             if (nextEvent.isStartElement()) {
                 StartElement startElement = (StartElement) nextEvent;
                 if (startElement.getName().getLocalPart().equals("lf111")) {
-                    Iterator prefixes = startElement.getNamespaceContext().getPrefixes("augment:module:leaf:list");
+                    Iterator<?> prefixes = startElement.getNamespaceContext().getPrefixes("augment:module:leaf:list");
 
                     while (prefixes.hasNext() && aModuleLfLstPrefix == null) {
                         String prefix = (String) prefixes.next();
@@ -198,14 +198,14 @@ public class CnSnToXmlAndJsonInstanceIdentifierTest extends YangAndXmlAndDataSch
 
         MutableSimpleNode<?> lf111 = NodeFactory.createMutableSimpleNode(TestUtils.buildQName("lf111", "augment:augment:module", "2014-01-17"),
                 lst11, instanceIdentifier,null,null);
-        
-        
+
+
         lst11.getChildren().add(lf111);
         lst11.init();
 
         cont1.getChildren().add(lst11);
         cont1.init();
-        
+
         cont.getChildren().add(cont1);
         cont.init();
 
index 5a2c964b8b15a8eb46c6fea2cc46e77c350cdcdf..2037fd4862f3c71f5f8a180f8c5509f7cbda23a4 100644 (file)
@@ -23,7 +23,6 @@ import java.io.UnsupportedEncodingException;
 import javax.ws.rs.client.Entity;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.UriInfo;
 
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
@@ -38,11 +37,11 @@ import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 
 public class MediaTypesTest extends JerseyTest {
-    
+
     private static RestconfService restconfService;
     private static String jsonData;
     private static String xmlData;
-    
+
     @BeforeClass
     public static void init() throws IOException {
         restconfService = mock(RestconfService.class);
@@ -51,7 +50,7 @@ public class MediaTypesTest extends JerseyTest {
         InputStream xmlStream = RestconfImplTest.class.getResourceAsStream("/parts/ietf-interfaces_interfaces.xml");
         xmlData = TestUtils.getDocumentInPrintableForm(TestUtils.loadDocumentFrom(xmlStream));
     }
-    
+
     @Override
     protected Application configure() {
         /* enable/disable Jersey logs to console */
@@ -65,7 +64,7 @@ public class MediaTypesTest extends JerseyTest {
                 JsonToCompositeNodeProvider.INSTANCE);
         return resourceConfig;
     }
-    
+
   @Test
   public void testPostOperationsWithInputDataMediaTypes() throws UnsupportedEncodingException {
       String uriPrefix = "/operations/";
@@ -84,14 +83,14 @@ public class MediaTypesTest extends JerseyTest {
       verify(restconfService, times(5)).invokeRpc(eq(uriPath), any(CompositeNode.class));
       post(uri, null, MediaType.TEXT_XML, xmlData);
       verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
-      
+
       // negative tests
       post(uri, MediaType.TEXT_PLAIN, MediaType.TEXT_XML, xmlData);
       verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
       post(uri, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, xmlData);
       verify(restconfService, times(6)).invokeRpc(eq(uriPath), any(CompositeNode.class));
   }
-  
+
     @Test
     public void testGetConfigMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/config/";
@@ -108,12 +107,12 @@ public class MediaTypesTest extends JerseyTest {
         verify(restconfService, times(4)).readConfigurationData(uriPath);
         get(uri, MediaType.TEXT_XML);
         verify(restconfService, times(5)).readConfigurationData(uriPath);
-        
+
         // negative tests
         get(uri, MediaType.TEXT_PLAIN);
         verify(restconfService, times(5)).readConfigurationData(uriPath);
     }
-    
+
     @Test
     public void testGetOperationalMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/operational/";
@@ -130,12 +129,12 @@ public class MediaTypesTest extends JerseyTest {
         verify(restconfService, times(4)).readOperationalData(uriPath);
         get(uri, MediaType.TEXT_XML);
         verify(restconfService, times(5)).readOperationalData(uriPath);
-        
+
         // negative tests
         get(uri, MediaType.TEXT_PLAIN);
         verify(restconfService, times(5)).readOperationalData(uriPath);
     }
-    
+
     @Test
     public void testPutConfigMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/config/";
@@ -155,7 +154,7 @@ public class MediaTypesTest extends JerseyTest {
         put(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
         verify(restconfService, times(6)).updateConfigurationData(eq(uriPath), any(CompositeNode.class));
     }
-    
+
     @Test
     public void testPostConfigWithPathMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/config/";
@@ -175,7 +174,7 @@ public class MediaTypesTest extends JerseyTest {
         post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
         verify(restconfService, times(6)).createConfigurationData(eq(uriPath), any(CompositeNode.class));
     }
-    
+
     @Test
     public void testPostConfigMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/config/";
@@ -194,7 +193,7 @@ public class MediaTypesTest extends JerseyTest {
         post(uri, "fooMediaType", MediaType.TEXT_XML, xmlData);
         verify(restconfService, times(6)).createConfigurationData(any(CompositeNode.class));
     }
-    
+
     @Test
     public void testDeleteConfigMediaTypes() throws UnsupportedEncodingException {
         String uriPrefix = "/config/";
@@ -204,18 +203,18 @@ public class MediaTypesTest extends JerseyTest {
         target(uri).request("fooMediaType").delete();
         verify(restconfService, times(1)).deleteConfigurationData(uriPath);
     }
-    
+
     private int get(String uri, String acceptMediaType) {
         return target(uri).request(acceptMediaType).get().getStatus();
     }
-    
+
     private int put(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
         if (acceptMediaType == null) {
             return target(uri).request().put(Entity.entity(data, contentTypeMediaType)).getStatus();
         }
         return target(uri).request(acceptMediaType).put(Entity.entity(data, contentTypeMediaType)).getStatus();
     }
-    
+
     private int post(String uri, String acceptMediaType, String contentTypeMediaType, String data) {
         if (acceptMediaType == null) {
             if (contentTypeMediaType == null || data == null) {
index 6f507f96e27faf82550e4bc92a842528b888c5c0..dff9d65db3f043b3b264ad50bb83687dbb9bba10 100644 (file)
@@ -7,12 +7,6 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import java.io.FileNotFoundException;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
@@ -21,11 +15,9 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
-
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.test.JerseyTest;
 import org.junit.BeforeClass;
@@ -45,6 +37,12 @@ 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.opendaylight.yangtools.yang.model.api.SchemaContext;
+import static junit.framework.Assert.assertNotNull;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class RestGetOperationTest extends JerseyTest {
 
@@ -164,6 +162,23 @@ public class RestGetOperationTest extends JerseyTest {
         response = target(uri).request("application/yang.api+xml").get();
         validateModulesResponseXml(response);
     }
+    // /streams/
+    @Test
+    public void getStreamsTest() throws UnsupportedEncodingException, FileNotFoundException {
+        ControllerContext.getInstance().setGlobalSchema(schemaContextModules);
+
+        String uri = "/streams";
+
+        Response response = target(uri).request("application/yang.api+json").get();
+        String responseBody = response.readEntity(String.class);
+        assertNotNull(responseBody);
+        assertTrue(responseBody.contains("streams"));
+
+        response = target(uri).request("application/yang.api+xml").get();
+        responseBody = response.readEntity(String.class);
+        assertNotNull(responseBody);
+        assertTrue(responseBody.contains("<streams xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"/>"));
+    }
 
     // /modules/module
     @Test
index 11264e7f860dcdd9c2820f7a8a89b056add4fca8..c6e2f1434371ed9fbd4e294ed7661d2acb5d3c38 100644 (file)
@@ -20,7 +20,6 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.net.URLEncoder;
 import java.text.ParseException;
 import java.util.Set;
 import java.util.concurrent.Future;
@@ -53,8 +52,6 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import com.google.common.base.Charsets;
-
 public class RestPostOperationTest extends JerseyTest {
 
     private static String xmlDataAbsolutePath;
index 359b68dc4c7dd000bcf0cefc385f69e714f80215..b681653d6b1a48b7020ac72d8960c86c07463ad0 100644 (file)
@@ -7,15 +7,8 @@
  */
 package org.opendaylight.controller.sal.restconf.impl.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
 import java.io.FileNotFoundException;
 import java.util.Set;
-
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
@@ -26,6 +19,11 @@ import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class RestconfImplTest {
 
index 3272ce56707eff0159efbab3d3106f281e188f1a..c08f329f0d81d694e8c4f97a04fd2dfe69c25468 100644 (file)
@@ -10,7 +10,6 @@ package org.opendaylight.controller.sal.restconf.broker.impl;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutorService;
 
 import org.opendaylight.controller.sal.binding.api.NotificationListener;
 import org.opendaylight.controller.sal.binding.api.NotificationService;
@@ -18,101 +17,46 @@ import org.opendaylight.controller.sal.restconf.broker.listeners.RemoteNotificat
 import org.opendaylight.controller.sal.restconf.broker.tools.RemoteStreamTools;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.QName;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.SalRemoteService;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
 import org.opendaylight.yangtools.restconf.client.api.RestconfClientContext;
 import org.opendaylight.yangtools.restconf.client.api.event.EventStreamInfo;
 import org.opendaylight.yangtools.yang.binding.Notification;
 
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-
 public class NotificationServiceImpl implements NotificationService {
     private final SalRemoteService salRemoteService;
     private final RestconfClientContext restconfClientContext;
 
-    private final Multimap<Class<? extends Notification>,NotificationListener<? extends Object>> listeners;
-    private ExecutorService _executor;
-
     public NotificationServiceImpl(RestconfClientContext restconfClienetContext){
         this.restconfClientContext = restconfClienetContext;
         this.salRemoteService = this.restconfClientContext.getRpcServiceContext(SalRemoteService.class).getRpcService();
-
-        HashMultimap<Class<? extends Notification>,NotificationListener<? extends Object>> _create = HashMultimap.<Class<? extends Notification>, NotificationListener<? extends Object>>create();
-        SetMultimap<Class<? extends Notification>,NotificationListener<? extends Object>> _synchronizedSetMultimap = Multimaps.<Class<? extends Notification>, NotificationListener<? extends Object>>synchronizedSetMultimap(_create);
-        this.listeners = _synchronizedSetMultimap;
-
-    }
-    public ExecutorService getExecutor() {
-        return this._executor;
-    }
-
-    public void setExecutor(final ExecutorService executor) {
-        this._executor = executor;
-    }
-
-    @Override
-    public <T extends Notification> void addNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
-        this.listeners.put(notificationType, listener);
-    }
-
-    @Override
-    public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
-        UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException("Deprecated method. Use registerNotificationListener instead.");
-        throw _unsupportedOperationException;
-    }
-
-    @Override
-    public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
-        UnsupportedOperationException _unsupportedOperationException = new UnsupportedOperationException(
-                "Deprecated method. Use RegisterNotificationListener returned value to close registration.");
-        throw _unsupportedOperationException;
     }
 
     @Override
-    public <T extends Notification> void removeNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
-        this.listeners.remove(notificationType, listener);
-    }
-
-    @Override
-    public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
+    public <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
         //TODO implementation using sal-remote
         List<QName> notifications = new ArrayList<QName>();
         notifications.add(new QName(notificationType.toString()));
         String notificationStreamName = RemoteStreamTools.createNotificationStream(salRemoteService, notifications);
         final Map<String,EventStreamInfo> desiredEventStream = RemoteStreamTools.createEventStream(restconfClientContext, notificationStreamName);
         RemoteNotificationListener remoteNotificationListener = new RemoteNotificationListener(listener);
-        ListenerRegistration<?> listenerRegistration = restconfClientContext.getEventStreamContext(desiredEventStream.get(desiredEventStream.get(notificationStreamName))).registerNotificationListener(remoteNotificationListener);
-        return new SalNotificationRegistration<T>(listenerRegistration);
+
+        final ListenerRegistration<?> listenerRegistration = restconfClientContext.getEventStreamContext(desiredEventStream.get(desiredEventStream.get(notificationStreamName)))
+                .registerNotificationListener(remoteNotificationListener);
+
+        return new AbstractListenerRegistration<NotificationListener<T>>(listener) {
+            @Override
+            protected void removeRegistration() {
+                listenerRegistration.close();
+            }
+        };
     }
 
     @Override
-    public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+    public ListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
         //TODO implementation using sal-remote
         String notificationStreamName = RemoteStreamTools.createNotificationStream(salRemoteService, null);
         final Map<String,EventStreamInfo> desiredEventStream = RemoteStreamTools.createEventStream(restconfClientContext, notificationStreamName);
         return restconfClientContext.getEventStreamContext(desiredEventStream.get(desiredEventStream.get(notificationStreamName))).registerNotificationListener(listener);
     }
-
-    private class SalNotificationRegistration<T extends Notification> implements Registration<NotificationListener<T>>{
-        private final Registration<?> registration;
-
-        public SalNotificationRegistration(ListenerRegistration<?> listenerRegistration){
-            this.registration = listenerRegistration;
-        }
-
-        @Override
-        public NotificationListener<T> getInstance() {
-            return this.getInstance();
-        }
-
-        @Override
-        public void close() throws Exception {
-            this.registration.close();
-        }
-    }
-
-
 }
index 7f9cc8f6c4fd3a4e2fae7fc126a20b0e95e51945..c2ff3b8cf6892155bb260a62b4357bb3d6b91737 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.controller.sal.restconf.broker.transactions;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Future;
+
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
@@ -30,11 +31,6 @@ public class RemoteDataModificationTransaction implements DataModificationTransa
         return null;
     }
 
-    @Override
-    public void putRuntimeData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
-
-    }
-
     @Override
     public void putOperationalData(InstanceIdentifier<? extends DataObject> path, DataObject data) {
 
@@ -45,11 +41,6 @@ public class RemoteDataModificationTransaction implements DataModificationTransa
 
     }
 
-    @Override
-    public void removeRuntimeData(InstanceIdentifier<? extends DataObject> path) {
-
-    }
-
     @Override
     public void removeOperationalData(InstanceIdentifier<? extends DataObject> path) {
 
index 07a7d41ee7734849e0eed91c3c9bce09001fb36f..67fc824a7b41d0784425920eb8dc7f6ae3e86bc4 100644 (file)
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
                             </codeGenerators>
                             <inspectDependencies>true</inspectDependencies>
                         </configuration>
                         <artifactId>yang-jmx-generator-plugin</artifactId>
                         <version>${config.version}</version>
                     </dependency>
+                    <dependency>
+                        <groupId>org.opendaylight.yangtools</groupId>
+                        <artifactId>maven-sal-api-gen-plugin</artifactId>
+                        <version>${yangtools.version}</version>
+                    </dependency>
                 </dependencies>
             </plugin>
 
index 38a4dd46617405c148022d4622a3b200b9182b80..000783bd07e545ee16ae5e306c20c8d72f4d6e35 100644 (file)
@@ -52,6 +52,7 @@ public class ToasterTest {
                 mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
                 mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
                 systemProperty("osgi.bundles.defaultStartLevel").value("4"),
+                systemPackages("sun.nio.ch"),
 
                 toasterBundles(),
                 mdSalCoreBundles(),
index 1a540fe9497fc51e4bb651fc7ea73f37bae69dc1..4e4cfeda2aaee2e9ec8e05e7e60e4c582824e53c 100644 (file)
                                         </namespaceToPackage1>
                                     </additionalConfiguration>
                                 </generator>
+                                <generator>
+                                    <codeGeneratorClass>
+                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+                                    </codeGeneratorClass>
+                                    <outputBaseDir>
+                                        ${salGeneratorPath}
+                                    </outputBaseDir>
+                                </generator>
                             </codeGenerators>
                             <inspectDependencies>true</inspectDependencies>
                         </configuration>
                         <artifactId>yang-jmx-generator-plugin</artifactId>
                         <version>${config.version}</version>
                     </dependency>
+                    <dependency>
+                        <groupId>org.opendaylight.yangtools</groupId>
+                        <artifactId>maven-sal-api-gen-plugin</artifactId>
+                        <version>${yangtools.version}</version>
+                    </dependency>
                 </dependencies>
             </plugin>
             <plugin>
index a484154edf1703819b9c7675ace6675b53992470..e1d69800cab5688ab46d7df75baefda1c4361998 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sample.toaster.provider;
 
 import java.util.Collections;
-
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -17,7 +16,6 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.opendaylight.controller.config.yang.config.toaster_provider.impl.ToasterProviderRuntimeMXBean;
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.controller.sal.common.util.Futures;
 import org.opendaylight.controller.sal.common.util.Rpcs;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
@@ -33,13 +31,15 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.util.concurrent.Futures;
+
 public class OpendaylightToaster implements ToasterData, ToasterService, ToasterProviderRuntimeMXBean {
 
     private static final Logger log = LoggerFactory.getLogger(OpendaylightToaster.class);
 
     private static final DisplayString toasterManufacturer = new DisplayString("Opendaylight");
     private static final DisplayString toasterModelNumber = new DisplayString("Model 1 - Binding Aware");
-    private ToasterStatus toasterStatus;
+    private final ToasterStatus toasterStatus;
 
     private NotificationProviderService notificationProvider;
     private final ExecutorService executor;
@@ -91,7 +91,7 @@ public class OpendaylightToaster implements ToasterData, ToasterService, Toaster
         currentTask.cancel(true);
         ToastDoneBuilder toastDone = new ToastDoneBuilder();
         toastDone.setToastStatus(ToastStatus.Cancelled);
-        notificationProvider.notify(toastDone.build());
+        notificationProvider.publish(toastDone.build());
     }
 
     public void setNotificationProvider(NotificationProviderService salService) {
@@ -125,7 +125,7 @@ public class OpendaylightToaster implements ToasterData, ToasterService, Toaster
 
             ToastDoneBuilder notifyBuilder = new ToastDoneBuilder();
             notifyBuilder.setToastStatus(ToastStatus.Done);
-            notificationProvider.notify(notifyBuilder.build());
+            notificationProvider.publish(notifyBuilder.build());
             log.trace("Toast Done");
             logToastInput(toastRequest);
             currentTask = null;
index ad6d814c1b106382a33a066e0572ae5bc4a6436b..59f8955d4b0bab2d41ac57bc134115d4c4f66842 100644 (file)
@@ -32,7 +32,7 @@
                                         org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
                                     </codeGeneratorClass>
                                     <outputBaseDir>
-                                        target/generated-sources/sal
+                                        ${salGeneratorPath}
                                     </outputBaseDir>
                                 </generator>
                             </codeGenerators>
index a9c1e054136d49f98f885b2b07575f2a33303aac..b829990bd3be3e26cb0b30407fbf7e6d9e5c4101 100644 (file)
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
         
         <dependency>
             <groupId>junit</groupId>
index 56b205216f2b8768fe66606808ec83c7906859e8..425a44946e064c97b44d27f42fdcdc8b1e2b9bc9 100644 (file)
@@ -11,6 +11,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.MultipartTransactionAware;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionAware;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
 
@@ -91,7 +92,12 @@ class MultipartMessageManager {
         txIdTotableIdMap.put(new TxIdEntry(id), Preconditions.checkNotNull(tableId));
     }
 
-    public Short isExpectedTableTransaction(TransactionAware transaction, Boolean more) {
+    public Short isExpectedTableTransaction(TransactionAware transaction) {
+        Boolean more = null;
+        if (transaction instanceof MultipartTransactionAware) {
+            more = ((MultipartTransactionAware)transaction).isMoreReplies();
+        }
+
         if (!isExpectedTransaction(transaction, more)) {
             return null;
         }
@@ -109,8 +115,8 @@ class MultipartMessageManager {
         txIdToRequestTypeMap.put(entry, getExpiryTime());
     }
 
-    public boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
-        TxIdEntry entry = new TxIdEntry(transaction.getTransactionId());
+    private boolean isExpectedTransaction(TransactionAware transaction, Boolean more) {
+        final TxIdEntry entry = new TxIdEntry(transaction.getTransactionId());
         if (more != null && more.booleanValue()) {
             return txIdToRequestTypeMap.containsKey(entry);
         } else {
@@ -118,6 +124,15 @@ class MultipartMessageManager {
         }
     }
 
+    public boolean isExpectedTransaction(TransactionAware transaction) {
+        Boolean more = null;
+        if (transaction instanceof MultipartTransactionAware) {
+            more = ((MultipartTransactionAware)transaction).isMoreReplies();
+        }
+
+        return isExpectedTransaction(transaction, more);
+    }
+
     private Long getExpiryTime() {
         return System.nanoTime() + lifetimeNanos;
     }
index 6796b4eb8723d02064d31a56bfa479c9412a4246..c4334ab9ff6ffdbd37a98f0c8580ab30c8b3e3f4 100644 (file)
@@ -137,50 +137,50 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
         return dps.beginTransaction();
     }
 
-    public synchronized void updateGroupDescStats(TransactionAware transaction, Boolean more, List<GroupDescStats> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateGroupDescStats(TransactionAware transaction, List<GroupDescStats> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             groupDescStats.updateStats(list);
         }
     }
 
-    public synchronized void updateGroupStats(TransactionAware transaction, Boolean more, List<GroupStats> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateGroupStats(TransactionAware transaction, List<GroupStats> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             groupStats.updateStats(list);
         }
     }
 
-    public synchronized void updateMeterConfigStats(TransactionAware transaction, Boolean more, List<MeterConfigStats> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateMeterConfigStats(TransactionAware transaction, List<MeterConfigStats> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             meterConfigStats.updateStats(list);
         }
     }
 
-    public synchronized void updateMeterStats(TransactionAware transaction, Boolean more, List<MeterStats> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateMeterStats(TransactionAware transaction, List<MeterStats> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             meterStats.updateStats(list);
         }
     }
 
-    public synchronized void updateQueueStats(TransactionAware transaction, Boolean more, List<QueueIdAndStatisticsMap> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateQueueStats(TransactionAware transaction, List<QueueIdAndStatisticsMap> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             queueStats.updateStats(list);
         }
     }
 
-    public synchronized void updateFlowTableStats(TransactionAware transaction, Boolean more, List<FlowTableAndStatisticsMap> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateFlowTableStats(TransactionAware transaction, List<FlowTableAndStatisticsMap> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             flowTableStats.updateStats(list);
         }
     }
 
-    public synchronized void updateNodeConnectorStats(TransactionAware transaction, Boolean more, List<NodeConnectorStatisticsAndPortNumberMap> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateNodeConnectorStats(TransactionAware transaction, List<NodeConnectorStatisticsAndPortNumberMap> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             nodeConnectorStats.updateStats(list);
         }
     }
 
-    public synchronized void updateAggregateFlowStats(TransactionAware transaction, Boolean more, AggregateFlowStatistics flowStats) {
-        final Short tableId = msgManager.isExpectedTableTransaction(transaction, more);
+    public synchronized void updateAggregateFlowStats(TransactionAware transaction, AggregateFlowStatistics flowStats) {
+        final Short tableId = msgManager.isExpectedTableTransaction(transaction);
         if (tableId != null) {
             final DataModificationTransaction trans = dps.beginTransaction();
             InstanceIdentifier<Table> tableRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, targetNodeKey)
@@ -203,8 +203,8 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
         }
     }
 
-    public synchronized void updateFlowStats(TransactionAware transaction, Boolean more, List<FlowAndStatisticsMapList> list) {
-        if (msgManager.isExpectedTransaction(transaction, more)) {
+    public synchronized void updateFlowStats(TransactionAware transaction, List<FlowAndStatisticsMapList> list) {
+        if (msgManager.isExpectedTransaction(transaction)) {
             flowStats.updateStats(list);
         }
     }
index bd9f96c875fe2faa6846eb5f2c4f1b076fa5827d..a06f7efdbb3559ae2b07abcbbd783d2de9618996 100644 (file)
@@ -57,7 +57,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onMeterConfigStatsUpdated(final MeterConfigStatsUpdated notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateMeterConfigStats(notification, notification.isMoreReplies(), notification.getMeterConfigStats());
+            handler.updateMeterConfigStats(notification, notification.getMeterConfigStats());
         }
     }
 
@@ -65,7 +65,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onMeterStatisticsUpdated(MeterStatisticsUpdated notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateMeterStats(notification, notification.isMoreReplies(), notification.getMeterStats());
+            handler.updateMeterStats(notification, notification.getMeterStats());
         }
     }
 
@@ -73,7 +73,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onGroupDescStatsUpdated(GroupDescStatsUpdated notification) {
         final NodeStatisticsHandler handler = statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateGroupDescStats(notification, notification.isMoreReplies(), notification.getGroupDescStats());
+            handler.updateGroupDescStats(notification, notification.getGroupDescStats());
         }
     }
 
@@ -81,7 +81,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onGroupStatisticsUpdated(GroupStatisticsUpdated notification) {
         final NodeStatisticsHandler handler = statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateGroupStats(notification, notification.isMoreReplies(), notification.getGroupStats());
+            handler.updateGroupStats(notification, notification.getGroupStats());
         }
     }
 
@@ -106,7 +106,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
         sucLogger.debug("Received flow stats update : {}",notification.toString());
         final NodeStatisticsHandler sna = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (sna != null) {
-            sna.updateFlowStats(notification, notification.isMoreReplies(), notification.getFlowAndStatisticsMapList());
+            sna.updateFlowStats(notification, notification.getFlowAndStatisticsMapList());
         }
     }
 
@@ -114,7 +114,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onAggregateFlowStatisticsUpdate(AggregateFlowStatisticsUpdate notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateAggregateFlowStats(notification, notification.isMoreReplies(), notification);
+            handler.updateAggregateFlowStats(notification, notification);
         }
     }
 
@@ -122,7 +122,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onNodeConnectorStatisticsUpdate(NodeConnectorStatisticsUpdate notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateNodeConnectorStats(notification, notification.isMoreReplies(), notification.getNodeConnectorStatisticsAndPortNumberMap());
+            handler.updateNodeConnectorStats(notification, notification.getNodeConnectorStatisticsAndPortNumberMap());
         }
     }
 
@@ -130,7 +130,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onFlowTableStatisticsUpdate(FlowTableStatisticsUpdate notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateFlowTableStats(notification, notification.isMoreReplies(), notification.getFlowTableAndStatisticsMap());
+            handler.updateFlowTableStats(notification, notification.getFlowTableAndStatisticsMap());
         }
     }
 
@@ -138,7 +138,7 @@ public class StatisticsListener implements OpendaylightGroupStatisticsListener,
     public void onQueueStatisticsUpdate(QueueStatisticsUpdate notification) {
         final NodeStatisticsHandler handler = this.statisticsManager.getStatisticsHandler(notification.getId());
         if (handler != null) {
-            handler.updateQueueStats(notification, notification.isMoreReplies(), notification.getQueueIdAndStatisticsMap());
+            handler.updateQueueStats(notification, notification.getQueueIdAndStatisticsMap());
         }
     }
 }
index 1c723eeccad10e998f601c7ea2d0fc8b7f4af4e4..a9fc739456b95740c3ab9c00313c31711e7ebba9 100644 (file)
         <dependency>
             <groupId>io.netty</groupId>
             <artifactId>netty-all</artifactId>
-            <version>4.0.10.Final</version>
+           <version>${netty.version}</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <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>
index 08aeea26783cb203ffaa69655097a3912175eec7..8400bc18353fc765da09cf6f84831085875fbb44 100644 (file)
@@ -213,8 +213,6 @@ public class ServiceProviderController {
                 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(),
index 525ab9e4fe1790ac438c73a822a583ad8bb38725..8035f420fb3797396f7abe7bec6753ed4eaa3c2d 100644 (file)
             <groupId>org.eclipse.xtend</groupId>
             <artifactId>org.eclipse.xtend.lib</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
     <build>
index f8993a09e7e7ed62d5ae2727df2a05f26db4e92b..b37b5babddf9161d87a3d7186aa06e713e965b94 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-util</artifactId>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-api</artifactId>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-mapping-api</artifactId>
             <artifactId>netconf-impl</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>mockito-configuration</artifactId>
                             javax.management.openmbean,
                             org.opendaylight.controller.config.api,
                             org.opendaylight.controller.config.api.jmx,
-                            org.opendaylight.controller.config.yang.store.api,
                             org.opendaylight.controller.config.yangjmxgenerator,
                             org.opendaylight.controller.config.yangjmxgenerator.attribute,
                             org.opendaylight.controller.netconf.api,
                             org.slf4j,
                             org.w3c.dom,
                             com.google.common.io,
-                            org.opendaylight.yangtools.yang.model.api.type
+                            org.opendaylight.yangtools.yang.model.api.type,
+                            org.opendaylight.yangtools.sal.binding.generator.spi,
+                            org.opendaylight.yangtools.sal.binding.yang.types
                         </Import-Package>
                         <Export-Package>
                         </Export-Package>
index bb19dc207ed3238156fd366f3c2ca837175ab204..01ced4cb9ab4c78408f76c59ff7e8b8fd35b8415 100644 (file)
@@ -20,7 +20,7 @@ import javax.management.ObjectName;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
index 73f9ecd6fa56a3a161bc7e9ca2795640e252e74c..f7fc029fcc8f363dd38dc6e8aaad565963654f6d 100644 (file)
@@ -17,7 +17,7 @@ import javax.management.ObjectName;
 
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
index 7cf6e17e9dddd163d47fadd76e7299ccc5148262..bf7f9f0f248e661080d48e16da93632b55f569ed 100644 (file)
@@ -16,7 +16,7 @@ import javax.management.ObjectName;
 
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorTag;
index 5b7c575e2fa637fbdda320eb911d464fcb69562c..a7b42889b6180aded5b123e86b3adae71ac4a5f3 100644 (file)
@@ -14,7 +14,7 @@ import javax.management.ObjectName;
 import javax.management.openmbean.OpenType;
 
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc;
index 5642cc7188788fd74a7aeccf7ca8ffa97abd009e..b39549ed5b73095f44194a30e15d5b6cdaa182ce 100644 (file)
@@ -8,19 +8,20 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Hashtable;
-
 import static com.google.common.base.Preconditions.checkState;
 
-public class Activator implements BundleActivator, YangStoreServiceTracker.YangStoreTrackerListener {
+public class Activator implements BundleActivator {
 
     private static final Logger logger = LoggerFactory.getLogger(Activator.class);
 
@@ -29,10 +30,43 @@ public class Activator implements BundleActivator, YangStoreServiceTracker.YangS
     private ConfigRegistryLookupThread configRegistryLookup = null;
 
     @Override
-    public void start(BundleContext context) throws Exception {
+    public void start(final BundleContext context) throws Exception {
         this.context = context;
-        YangStoreServiceTracker tracker = new YangStoreServiceTracker(context, this);
-        tracker.open();
+
+        ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread> customizer = new ServiceTrackerCustomizer<SchemaContextProvider, ConfigRegistryLookupThread>() {
+            @Override
+            public ConfigRegistryLookupThread addingService(ServiceReference<SchemaContextProvider> reference) {
+                logger.debug("Got addingService(SchemaContextProvider) event, starting ConfigRegistryLookupThread");
+                checkState(configRegistryLookup == null, "More than one onYangStoreAdded received");
+
+                SchemaContextProvider schemaContextProvider = reference.getBundle().getBundleContext().getService(reference);
+
+                YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(schemaContextProvider);
+                configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
+                configRegistryLookup.start();
+                return configRegistryLookup;
+            }
+
+            @Override
+            public void modifiedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
+                logger.debug("Got modifiedService(SchemaContextProvider) event");
+                configRegistryLookup.yangStoreService.refresh();
+
+            }
+
+            @Override
+            public void removedService(ServiceReference<SchemaContextProvider> reference, ConfigRegistryLookupThread configRegistryLookup) {
+                configRegistryLookup.interrupt();
+                if (osgiRegistration != null) {
+                    osgiRegistration.unregister();
+                }
+                osgiRegistration = null;
+                Activator.this.configRegistryLookup = null;
+            }
+        };
+
+        ServiceTracker<SchemaContextProvider, ConfigRegistryLookupThread> listenerTracker = new ServiceTracker<>(context, SchemaContextProvider.class, customizer);
+        listenerTracker.open();
     }
 
     @Override
@@ -42,27 +76,10 @@ public class Activator implements BundleActivator, YangStoreServiceTracker.YangS
         }
     }
 
-    @Override
-    public synchronized void onYangStoreAdded(YangStoreService yangStoreService) {
-        checkState(configRegistryLookup  == null, "More than one onYangStoreAdded received");
-        configRegistryLookup = new ConfigRegistryLookupThread(yangStoreService);
-        configRegistryLookup.start();
-    }
-
-    @Override
-    public synchronized void onYangStoreRemoved() {
-        configRegistryLookup.interrupt();
-        if (osgiRegistration != null) {
-            osgiRegistration.unregister();
-        }
-        osgiRegistration = null;
-        configRegistryLookup = null;
-    }
-
     private class ConfigRegistryLookupThread extends Thread {
-        private final YangStoreService yangStoreService;
+        private final YangStoreServiceImpl yangStoreService;
 
-        private ConfigRegistryLookupThread(YangStoreService yangStoreService) {
+        private ConfigRegistryLookupThread(YangStoreServiceImpl yangStoreService) {
             super("config-registry-lookup");
             this.yangStoreService = yangStoreService;
         }
@@ -71,8 +88,7 @@ public class Activator implements BundleActivator, YangStoreServiceTracker.YangS
         public void run() {
             NetconfOperationServiceFactoryImpl factory = new NetconfOperationServiceFactoryImpl(yangStoreService);
             logger.debug("Registering into OSGi");
-            osgiRegistration = context.registerService(new String[]{NetconfOperationServiceFactory.class.getName()}, factory,
-                    new Hashtable<String, Object>());
+            osgiRegistration = context.registerService(NetconfOperationServiceFactory.class, factory, null);
         }
     }
 }
index 77c58501cd42942e8bb55793d18408f6a31c3441..09966b8c3bd6c74f29ed93f20cd12e6654ee9a04 100644 (file)
@@ -11,7 +11,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 import com.google.common.base.Optional;
 import com.google.common.collect.Sets;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Commit;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.DiscardChanges;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.Validate;
index 034b39a8066b0fbf631c4159558efdd15a362a2a..4ca71ae2886a143d7322ed67be3a97b6f8a6cfb3 100644 (file)
@@ -9,8 +9,6 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
index 444500d5ddd496413e242676eb1f5e16081e6381..95659ddf914837d32d10c0a4f36525fc03b09764 100644 (file)
@@ -8,16 +8,12 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
 import org.opendaylight.controller.config.api.LookupRegistry;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
@@ -26,10 +22,10 @@ import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * Manages life cycle of {@link YangStoreSnapshot}.
@@ -155,7 +151,7 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
         private final String moduleNamespace;
 
         public YangStoreCapability(Module module, String moduleContent) {
-            super(getAsString(module));
+            super(toCapabilityURI(module));
             this.content = moduleContent;
             this.moduleName = module.getName();
             this.moduleNamespace = module.getNamespace().toString();
@@ -167,14 +163,9 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
             return Optional.of(content);
         }
 
-        private static String getAsString(Module module) {
-            final StringBuffer capabilityContent = new StringBuffer();
-            capabilityContent.append(module.getNamespace());
-            capabilityContent.append("?module=");
-            capabilityContent.append(module.getName());
-            capabilityContent.append("&revision=");
-            capabilityContent.append(Util.writeDate(module.getRevision()));
-            return capabilityContent.toString();
+        private static String toCapabilityURI(Module module) {
+            return String.valueOf(module.getNamespace()) + "?module="
+                    + module.getName() + "&revision=" + Util.writeDate(module.getRevision());
         }
 
         @Override
@@ -5,7 +5,7 @@
  * 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.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 public class YangStoreException extends Exception {
 
@@ -5,7 +5,7 @@
  * 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.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 /**
  * Yang store OSGi service
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceImpl.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceImpl.java
new file mode 100644 (file)
index 0000000..1102f34
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.netconf.confignetconfconnector.osgi;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+import javax.annotation.concurrent.GuardedBy;
+
+public class YangStoreServiceImpl implements YangStoreService {
+    private final SchemaContextProvider service;
+    @GuardedBy("this")
+    private YangStoreSnapshotImpl cache = null;
+
+    public YangStoreServiceImpl(SchemaContextProvider service) {
+        this.service = service;
+    }
+
+    @Override
+    public synchronized YangStoreSnapshotImpl getYangStoreSnapshot() throws YangStoreException {
+        if (cache == null) {
+            cache = new YangStoreSnapshotImpl(service.getSchemaContext());
+        }
+        return cache;
+    }
+
+    /**
+     * Called when schema context changes, invalidates cache.
+     */
+    public synchronized void refresh() {
+        cache = null;
+    }
+}
diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceTracker.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/osgi/YangStoreServiceTracker.java
deleted file mode 100644 (file)
index 3b1e89d..0000000
+++ /dev/null
@@ -1,41 +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.netconf.confignetconfconnector.osgi;
-
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-class YangStoreServiceTracker extends ServiceTracker<YangStoreService, YangStoreService> {
-    private final YangStoreTrackerListener listener;
-
-    YangStoreServiceTracker(BundleContext context, final YangStoreTrackerListener listener) {
-        super(context, YangStoreService.class, null);
-        this.listener = listener;
-    }
-
-    @Override
-    public synchronized YangStoreService addingService(final ServiceReference<YangStoreService> reference) {
-        final YangStoreService yangStoreService = super.addingService(reference);
-        listener.onYangStoreAdded(yangStoreService);
-        return yangStoreService;
-    }
-
-    @Override
-    public synchronized void removedService(final ServiceReference<YangStoreService> reference,
-            final YangStoreService service) {
-        listener.onYangStoreRemoved();
-    }
-
-    static interface YangStoreTrackerListener {
-        void onYangStoreAdded(YangStoreService yangStoreService);
-        void onYangStoreRemoved();
-    }
-}
@@ -5,11 +5,12 @@
  * 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.yang.store.api;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 
 import java.util.Map;
 import java.util.Set;
@@ -27,29 +28,13 @@ public interface YangStoreSnapshot extends AutoCloseable {
 
     Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries();
 
-    /**
-     * Get number of parsed ModuleMXBeanEntry instances.
-     */
-    int countModuleMXBeanEntries();
-
     /**
      * Get all modules discovered when this snapshot was created.
      * @return all modules discovered. If one module exists with two different revisions, return both.
      */
     Set<Module> getModules();
 
-    /**
-     * Get all modules together with their yang sources.
-     */
-    Map<Module, String> getModulesToSources();
-
-    /**
-     * Retrieve source of module as it appeared during creation of this snapshot.
-     * @param module
-     * @return yang source of given module
-     * @throws java.lang.IllegalArgumentException if module does not belong to this snapshot
-     */
-    String getModuleSource(Module module);
+    String getModuleSource(ModuleIdentifier moduleIdentifier);
 
     @Override
     void close();
@@ -5,12 +5,10 @@
  * 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.yang.store.impl;
 
-import com.google.common.collect.Lists;
+package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
+
 import com.google.common.collect.Maps;
-import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.controller.config.yangjmxgenerator.PackageTranslator;
 import org.opendaylight.controller.config.yangjmxgenerator.ServiceInterfaceEntry;
@@ -20,69 +18,62 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
+
+public class YangStoreSnapshotImpl implements YangStoreSnapshot {
+    private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
+
+
+    private final Map<String /* Namespace from yang file */,
+            Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
+
 
-public class MbeParser {
-    private static final Logger logger = LoggerFactory.getLogger(MbeParser.class);
+    private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
 
-    public YangStoreSnapshotImpl parseYangFiles(Collection<? extends InputStream> allInput) throws YangStoreException {
-        YangParserImpl parser = YangParserWrapper.getYangParserInstance();
+    private final SchemaContext schemaContext;
 
-        Map<InputStream, Module> allYangModules = YangParserWrapper.parseYangFiles(parser, allInput);
 
-        SchemaContext resolveSchemaContext = YangParserWrapper.getSchemaContextFromModules(parser, allYangModules);
+    public YangStoreSnapshotImpl(SchemaContext resolveSchemaContext) {
         logger.trace("Resolved modules:{}", resolveSchemaContext.getModules());
+        this.schemaContext = resolveSchemaContext;
         // JMX generator
 
         Map<String, String> namespaceToPackageMapping = Maps.newHashMap();
-        PackageTranslator packageTranslator = new PackageTranslator(
-                namespaceToPackageMapping);
-
+        PackageTranslator packageTranslator = new PackageTranslator(namespaceToPackageMapping);
         Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
-
         Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
         // create SIE structure qNamesToSIEs
         for (Module module : resolveSchemaContext.getModules()) {
             String packageName = packageTranslator.getPackageName(module);
             Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry
-                    .create(module, packageName,knownSEITracker);
-
-            for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries
-                    .entrySet()) {
-
+                    .create(module, packageName, knownSEITracker);
+            for (Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries.entrySet()) {
                 // merge value into qNamesToSIEs
                 if (qNamesToSIEs.containsKey(sieEntry.getKey()) == false) {
                     qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue());
                 } else {
-                    throw new IllegalStateException(
-                            "Cannot add two SIE with same qname "
+                    throw new IllegalStateException("Cannot add two SIE with same qname "
                                     + sieEntry.getValue());
                 }
             }
         }
 
         Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap = Maps.newHashMap();
-        Map<Module, String> modulesToSources = new HashMap<>();
-        Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>>
-                qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
+
+        Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
 
 
-        for (Entry<InputStream, Module> moduleEntry : allYangModules.entrySet()) {
-            Module module = moduleEntry.getValue();
+        for (Module module : schemaContext.getModules()) {
             String packageName = packageTranslator.getPackageName(module);
             TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper(
                     new TypeProviderImpl(resolveSchemaContext));
-            String yangAsString = reReadInputStream(moduleEntry);
 
             QName qName = new QName(module.getNamespace(), module.getRevision(), module.getName());
 
@@ -90,43 +81,36 @@ public class MbeParser {
                     Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext,
                             typeProviderWrapper, packageName));
             moduleMXBeanEntryMap.put(module.getNamespace().toString(), namesToMBEs);
-            modulesToSources.put(module, yangAsString);
+
             qNamesToIdentitiesToModuleMXBeanEntries.put(qName, namesToMBEs);
         }
+        this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
+        this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
 
-        return new YangStoreSnapshotImpl(moduleMXBeanEntryMap, modulesToSources, qNamesToIdentitiesToModuleMXBeanEntries);
     }
 
-    private String reReadInputStream(Entry<InputStream, Module> moduleEntry) {
-        String yangAsString;
-        try {
-            moduleEntry.getKey().reset();
-            yangAsString = IOUtils.toString(moduleEntry.getKey());
-        } catch (IOException e) {
-            throw new IllegalStateException("Cannot reread " + moduleEntry.getValue(), e);
-        }
-        return yangAsString;
+    @Override
+    public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
+        return moduleMXBeanEntryMap;
     }
 
-    @Deprecated
-    public Map<Module, String> parseYangFilesToString(Collection<? extends InputStream> allYangs) {
-
-        logger.error("Using deprecated method that will be removed soon", new UnsupportedOperationException("Deprecated"));
-        YangParserImpl parser = YangParserWrapper.getYangParserInstance();
+    @Override
+    public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
+        return qNamesToIdentitiesToModuleMXBeanEntries;
+    }
 
-        Map<InputStream, Module> allYangModules = parser
-                .parseYangModelsFromStreamsMapped(Lists.newArrayList(allYangs));
-        Map<Module, String> retVal = new HashMap<>();
+    @Override
+    public Set<Module> getModules() {
+        return schemaContext.getModules();
+    }
 
-        for (Entry<InputStream, Module> entry : allYangModules.entrySet()) {
-            try {
-                retVal.put(entry.getValue(), IOUtils.toString(entry.getKey()));
-            } catch (IOException e) {
-                throw new IllegalStateException(
-                        "Can not create string from yang file.");
-            }
-        }
-        return retVal;
+    @Override
+    public String getModuleSource(org.opendaylight.yangtools.yang.model.api.ModuleIdentifier moduleIdentifier) {
+        return schemaContext.getModuleSource(moduleIdentifier).get();
     }
 
+    @Override
+    public void close() {
+
+    }
 }
index fc8ddc01bdfb2da52ef0aa6cd0bd28f519878377..d7f352af36a750e37fcccf9ec2fcc470e893910e 100644 (file)
@@ -11,22 +11,18 @@ package org.opendaylight.controller.netconf.confignetconfconnector.util;
 import com.google.common.base.Preconditions;
 
 import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.Date;
 
-public final class Util {
+import static org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil.getRevisionFormat;
 
-    /**
-     * Used for date <-> xml serialization
-     */
-    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+public final class Util {
 
     public static String writeDate(final Date date) {
-        return dateFormat.format(date);
+        return getRevisionFormat().format(date);
     }
 
     public static Date readDate(final String s) throws ParseException {
-        return dateFormat.parse(s);
+        return getRevisionFormat().parse(s);
     }
 
     public static void checkType(final Object value, final Class<?> clazz) {
index 41d91819a695c7fab1d92c996f76add8afa8e26d..b52328f6313f534f522778b8614c22ea1246f76f 100644 (file)
@@ -8,33 +8,11 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import org.apache.commons.lang3.StringUtils;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -49,8 +27,6 @@ import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnota
 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yang.store.impl.MbeParser;
 import org.opendaylight.controller.config.yang.test.impl.ComplexDtoBInner;
 import org.opendaylight.controller.config.yang.test.impl.ComplexList;
 import org.opendaylight.controller.config.yang.test.impl.Deep;
@@ -72,6 +48,8 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.get.Get;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig.GetConfig;
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultCloseSession;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
@@ -88,6 +66,7 @@ import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -96,11 +75,32 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 
 public class NetconfMappingTest extends AbstractConfigTest {
@@ -590,7 +590,16 @@ public class NetconfMappingTest extends AbstractConfigTest {
         final List<InputStream> yangDependencies = getYangs();
 
         final Map<String, Map<String, ModuleMXBeanEntry>> mBeanEntries = Maps.newHashMap();
-        mBeanEntries.putAll(new MbeParser().parseYangFiles(yangDependencies).getModuleMXBeanEntryMap());
+
+        YangParserImpl yangParser = new YangParserImpl();
+        final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(yangDependencies).values()));
+        YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(new SchemaContextProvider() {
+            @Override
+            public SchemaContext getSchemaContext() {
+                return schemaContext ;
+            }
+        });
+        mBeanEntries.putAll(yangStoreService.getYangStoreSnapshot().getModuleMXBeanEntryMap());
 
         return mBeanEntries;
     }
index b70a66f5efc7f8eb1a4d779bcb51ca2123d33227..ae5a9930d2a3c3d66aaf29a56f626adb3f44c04d 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
index 13f8cad968460d97a2f5ca7073d31745bc4a428f..a063f5786a8f4796d95023849fbc6243e873fa01 100644 (file)
@@ -14,7 +14,6 @@ import org.junit.Assert;
 import org.junit.Test;
 import org.junit.matchers.JUnitMatchers;
 import org.opendaylight.controller.config.api.LookupRegistry;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
 import org.opendaylight.yangtools.yang.common.QName;
 
index 85fff89777e9caf5c8a10aab4f5c09a57c15dc0d..76a0bd9908ac571a911f7309c33eb91a42ef87cd 100644 (file)
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-api</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>xmlunit</groupId>
             <artifactId>xmlunit</artifactId>
index a81bbd62a02a83a5d34fb850d01d9f1f90aa4882..7134f5c580b601aee088fe2e2a510f83f4afcd02 100644 (file)
@@ -8,9 +8,8 @@
 
 package org.opendaylight.controller.netconf.impl.mapping.operations;
 
-import java.util.HashMap;
-import java.util.Map;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
 import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
@@ -22,8 +21,8 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.Map;
 
 public final class DefaultGetSchema extends AbstractLastNetconfOperation {
     public static final String GET_SCHEMA = "get-schema";
index 43854374a0347d3449b69071452c7eb7f481ea41..07da7f990a974df6dcfe8e1a62ddb68ae4d8987f 100644 (file)
@@ -8,36 +8,17 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-
-import java.io.DataOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.management.ManagementFactory;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import javax.management.ObjectName;
-
+import com.google.common.base.Optional;
+import com.google.common.collect.Sets;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
 import org.apache.commons.io.IOUtils;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.client.NetconfClient;
@@ -57,13 +38,22 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import com.google.common.base.Optional;
-import com.google.common.collect.Sets;
+import java.io.DataOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.management.ManagementFactory;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
 
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.util.HashedWheelTimer;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.MockitoAnnotations.initMocks;
 
 public class ConcurrentClientsTest {
 
@@ -71,11 +61,6 @@ public class ConcurrentClientsTest {
     private EventLoopGroup nettyGroup;
     private NetconfClientDispatcher netconfClientDispatcher;
 
-    @Mock
-    private YangStoreService yangStoreService;
-    @Mock
-    private ConfigRegistryJMXClient jmxClient;
-
     private final InetSocketAddress netconfAddress = new InetSocketAddress("127.0.0.1", 8303);
 
     static final Logger logger = LoggerFactory.getLogger(ConcurrentClientsTest.class);
@@ -90,18 +75,7 @@ public class ConcurrentClientsTest {
 
     @Before
     public void setUp() throws Exception {
-        { // init mocks
-            MockitoAnnotations.initMocks(this);
-            final YangStoreSnapshot yStore = mock(YangStoreSnapshot.class);
-            doReturn(yStore).when(this.yangStoreService).getYangStoreSnapshot();
-            doReturn(Collections.emptyMap()).when(yStore).getModuleMXBeanEntryMap();
-
-            final ConfigTransactionJMXClient mockedTCl = mock(ConfigTransactionJMXClient.class);
-            doReturn(mockedTCl).when(this.jmxClient).getConfigTransactionClient(any(ObjectName.class));
-
-            doReturn(Collections.emptySet()).when(jmxClient).lookupConfigBeans();
-        }
-
+        initMocks(this);
         nettyGroup = new NioEventLoopGroup();
         NetconfHelloMessageAdditionalHeader additionalHeader = new NetconfHelloMessageAdditionalHeader("uname", "10.10.10.1", "830", "tcp", "client");
         netconfClientDispatcher = new NetconfClientDispatcher( nettyGroup, nettyGroup, additionalHeader, 5000);
index 57067f47ecded6b0d9e6bd745b0b0de3df344d3d..aab939e8d90933dedc0dfb496d6db1ada9e48217 100644 (file)
             <artifactId>config-util</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-api</artifactId>
-            <scope>test</scope>
-        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>netconf-api</artifactId>
             <version>${config.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>yang-store-impl</artifactId>
-            <scope>test</scope>
-            <type>test-jar</type>
-        </dependency>
         <dependency>
             <groupId>org.opendaylight.controller</groupId>
             <artifactId>logback-config</artifactId>
@@ -5,24 +5,30 @@
  * 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.yang.store.impl;
+package org.opendaylight.controller.netconf.it;
 
 import org.apache.commons.io.IOUtils;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.api.YangStoreService;
-import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreServiceImpl;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreSnapshot;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
 
 import static org.junit.Assert.assertNotNull;
 
 public class HardcodedYangStoreService implements YangStoreService {
 
-    private final Collection<ByteArrayInputStream> byteArrayInputStreams;
+    private final List<InputStream> byteArrayInputStreams;
 
     public HardcodedYangStoreService(
             Collection<? extends InputStream> inputStreams)
@@ -46,6 +52,15 @@ public class HardcodedYangStoreService implements YangStoreService {
                 throw new RuntimeException(e);
             }
         }
-        return new MbeParser().parseYangFiles(byteArrayInputStreams);
+
+        YangParserImpl yangParser = new YangParserImpl();
+        final SchemaContext schemaContext = yangParser.resolveSchemaContext(new HashSet<>(yangParser.parseYangModelsFromStreamsMapped(byteArrayInputStreams).values()));
+        YangStoreServiceImpl yangStoreService = new YangStoreServiceImpl(new SchemaContextProvider() {
+            @Override
+            public SchemaContext getSchemaContext() {
+                return schemaContext ;
+            }
+        });
+        return yangStoreService.getYangStoreSnapshot();
     }
 }
index 1035c9f9fe3afd9c8a0bda0e3b3709ff2800df1d..19007cd0371b6ad5198db5ab8681a8ffff1a7f3c 100644 (file)
@@ -7,27 +7,9 @@
  */
 package org.opendaylight.controller.netconf.it;
 
-import static junit.framework.Assert.assertEquals;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import io.netty.channel.ChannelFuture;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.Notification;
-import javax.management.NotificationListener;
-
 import org.apache.commons.lang3.StringUtils;
 import org.junit.After;
 import org.junit.Assert;
@@ -40,8 +22,7 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
 import org.opendaylight.controller.config.persist.api.Persister;
 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.netconf.confignetconfconnector.osgi.YangStoreException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.jmx.CommitJMXNotification;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
@@ -64,8 +45,24 @@ import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.w3c.dom.Element;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+import javax.management.InstanceNotFoundException;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import static junit.framework.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
 
 public class NetconfConfigPersisterITTest extends AbstractNetconfConfigTest {
 
index 44775fdf9316fdc582b5df3a3f5313f9b0b94b55..6989bf512fb702f2b6a3b32b15f803134b27c654 100644 (file)
@@ -14,8 +14,7 @@ import org.junit.Before;
 import org.junit.Test;
 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.netconf.confignetconfconnector.osgi.YangStoreException;
 import org.opendaylight.controller.netconf.client.NetconfClient;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.confignetconfconnector.osgi.NetconfOperationServiceFactoryImpl;
index fce3f70e73b346bc94e2fb306bdf64d7c25aff3d..677d0dff8ca5092c8e3d726864689bf2580462b9 100644 (file)
@@ -42,8 +42,7 @@ import org.junit.Test;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.spi.ModuleFactory;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.store.api.YangStoreException;
-import org.opendaylight.controller.config.yang.store.impl.HardcodedYangStoreService;
+import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreException;
 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.NetconfTestImplModuleMXBean;
index 7a840be02af697f1cd73dad423c8b610b2a664da..4af66532a18ec2d8a8fc067f61a777905f4011a2 100644 (file)
@@ -30,8 +30,7 @@ import org.junit.matchers.JUnitMatchers;
 import org.mockito.Mock;
 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.netconf.confignetconfconnector.osgi.YangStoreException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfManagementSession;
 import org.opendaylight.controller.netconf.client.NetconfClient;
index 4e536c43bd4d3b792d7f7abcc6283bf5cdc3cf90..ee971a65ddc882bd11e7c0593f1b3f0168bcce99 100644 (file)
@@ -7,20 +7,8 @@
  */
 package org.opendaylight.controller.netconf.it.pax;
 
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-
-import javax.inject.Inject;
-import javax.xml.parsers.ParserConfigurationException;
-
 import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
 import io.netty.channel.nio.NioEventLoopGroup;
 import org.junit.Assert;
 import org.junit.Test;
@@ -39,16 +27,30 @@ import org.ops4j.pax.exam.util.Filter;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
+import javax.inject.Inject;
+import javax.xml.parsers.ParserConfigurationException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
+import static org.junit.Assert.fail;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.flowCapableModelBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.junitAndMockitoBundles;
+import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.systemPackages;
+import static org.ops4j.pax.exam.CoreOptions.systemProperty;
+
 @RunWith(PaxExam.class)
 public class IdentityRefNetconfTest {
 
-    public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 5000;
+    public static final int CLIENT_CONNECTION_TIMEOUT_MILLIS = 15000;
 
     // Wait for controller to start
     @Inject
@@ -61,6 +63,7 @@ public class IdentityRefNetconfTest {
                 systemProperty("osgi.console").value("2401"),
                 systemProperty("osgi.bundles.defaultStartLevel").value("4"),
                 systemProperty("pax.exam.osgi.unresolved.fail").value("true"),
+                systemPackages("sun.nio.ch"),
 
                 testingModules(),
                 loggingModules(),
@@ -84,31 +87,37 @@ public class IdentityRefNetconfTest {
 
     private static final InetSocketAddress tcpAddress = new InetSocketAddress("127.0.0.1", 18383);
 
+
     @Test
     public void testIdRef() throws Exception {
-        Preconditions.checkNotNull(broker, "Controller not initialized");
-
-        NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
-        NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup,
-                CLIENT_CONNECTION_TIMEOUT_MILLIS);
-
-        NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
-        NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
-        NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
-
-        try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) {
-            sendMessage(edit, netconfClient);
-            sendMessage(commit, netconfClient);
-            sendMessage(getConfig, netconfClient, "id-test",
-                    "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
-                    "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
-                    "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
-                    "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
-        }
+        try {
+            Preconditions.checkNotNull(broker, "Controller not initialized");
+
+            NioEventLoopGroup nettyThreadgroup = new NioEventLoopGroup();
+            NetconfClientDispatcher clientDispatcher = new NetconfClientDispatcher(nettyThreadgroup, nettyThreadgroup,
+                    CLIENT_CONNECTION_TIMEOUT_MILLIS);
+
+            NetconfMessage edit = xmlFileToNetconfMessage("netconfMessages/editConfig_identities.xml");
+            NetconfMessage commit = xmlFileToNetconfMessage("netconfMessages/commit.xml");
+            NetconfMessage getConfig = xmlFileToNetconfMessage("netconfMessages/getConfig.xml");
+
+            try (NetconfClient netconfClient = new NetconfClient("client", tcpAddress, CLIENT_CONNECTION_TIMEOUT_MILLIS, clientDispatcher)) {
+                sendMessage(edit, netconfClient);
+                sendMessage(commit, netconfClient);
+                sendMessage(getConfig, netconfClient, "id-test",
+                        "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</afi>",
+                        "<afi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</afi>",
+                        "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity2</safi>",
+                        "<safi xmlns:prefix=\"urn:opendaylight:params:xml:ns:yang:controller:config:test:types\">prefix:test-identity1</safi>");
+            }
 
-        clientDispatcher.close();
+            clientDispatcher.close();
+        } catch (Exception e) {
+            fail(Throwables.getStackTraceAsString(e));
+        }
     }
 
+
     private void sendMessage(NetconfMessage edit, NetconfClient netconfClient, String... containingResponse)
             throws ExecutionException, InterruptedException, TimeoutException {
         NetconfMessage response = netconfClient.sendRequest(edit).get();
index 204bf1d13194800e8a9347e97e97c2959ce9417f..e07c7ed6ac901156aa2d6c23a75114bd523584da 100644 (file)
@@ -109,8 +109,8 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                 netconf_ssh_output.setDaemon(false);
                                 netconf_ssh_output.start();
 
-                            } catch (Throwable t){
-                                logger.error("SSH bridge couldn't create echo socket",t.getMessage(),t);
+                            } catch (Exception t) {
+                                logger.error("SSH bridge could not create echo socket: {}", t.getMessage(), t);
 
                                 try {
                                     if (netconf_ssh_input!=null){
@@ -129,7 +129,6 @@ public class SocketThread implements Runnable, ServerAuthenticationCallback, Ser
                                     Thread.currentThread().interrupt();
                                     logger.error("netconf_ssh_output join error ",e);
                                 }
-
                             }
                         } else {
                             try {
index ae75657e5a71876b00146b313ed75f6585928bd0..586366f41a63659bc8b75fd8ccbf12df97ae34bd 100644 (file)
@@ -47,7 +47,6 @@
         <osgi.version>5.0.0</osgi.version>
         <maven.bundle.version>2.4.0</maven.bundle.version>
         <slf4j.version>1.7.2</slf4j.version>
-        <netconf.netty.version>4.0.10.Final</netconf.netty.version>
         <salGeneratorPath>${project.build.directory}/generated-sources/sal</salGeneratorPath>
     </properties>
 
                 <artifactId>config-util</artifactId>
                 <version>${config.version}</version>
             </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>yang-store-api</artifactId>
-                <version>${config.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>yang-store-impl</artifactId>
-                <version>${config.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>${project.groupId}</groupId>
-                <artifactId>yang-store-impl</artifactId>
-                <version>${config.version}</version>
-                <type>test-jar</type>
-            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>yang-test</artifactId>
index 821ac92021683e8d0cccdd6409b28f09add1ad0d..f539f1ca69c4cbf08b6c6cf8abc90cdfcc45d465 100644 (file)
@@ -7,7 +7,6 @@
     <relativePath>../../../commons/opendaylight</relativePath>
   </parent>
   <properties>
-    <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
     <enunciate.version>1.26.2</enunciate.version>
   </properties>
   <scm>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
index 27588b8bee907b8015df57daa5140d77d935dd8a..b25e99e420e677f87e1ccbc1f11c1a1ac36b83d4 100644 (file)
@@ -7,7 +7,6 @@
     <relativePath>../../commons/opendaylight</relativePath>
   </parent>
   <properties>
-    <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
     <enunciate.version>1.26.2</enunciate.version>
   </properties>
   <scm>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>
index dab69917d1d85a30843af8acb723ca6b94785f3a..75da310b2b63b9f967afdbc354fba1ee3871dfa3 100644 (file)
@@ -152,6 +152,9 @@ public class NeutronSubnet_IPAllocationPool implements Serializable {
                 if (i != gIP) {
                     p.setPoolStart(poolStart);
                     poolStarted = true;
+                } else {
+                    //FIX for bug 533
+                    p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i+1));
                 }
             }
             if (i == eIP) {
diff --git a/opendaylight/northbound/archetype-app-northbound/pom.xml b/opendaylight/northbound/archetype-app-northbound/pom.xml
new file mode 100644 (file)
index 0000000..558bf41
--- /dev/null
@@ -0,0 +1,30 @@
+<?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>
+
+  <groupId>org.opendaylight.controller</groupId>
+  <artifactId>app-northbound</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>maven-archetype</packaging>
+
+  <name>app-northbound</name>
+
+  <build>
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.archetype</groupId>
+        <artifactId>archetype-packaging</artifactId>
+        <version>2.2</version>
+      </extension>
+    </extensions>
+
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-archetype-plugin</artifactId>
+          <version>2.2</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/opendaylight/northbound/archetype-app-northbound/src/main/resources/META-INF/maven/archetype-metadata.xml b/opendaylight/northbound/archetype-app-northbound/src/main/resources/META-INF/maven/archetype-metadata.xml
new file mode 100644 (file)
index 0000000..3c9223d
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<archetype-descriptor xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0 http://maven.apache.org/xsd/archetype-descriptor-1.0.0.xsd" name="app"
+    xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype-descriptor/1.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <fileSets>
+    <fileSet filtered="true" packaged="true" encoding="UTF-8">
+      <directory>src/main/java</directory>
+      <includes>
+        <include>**/*.java</include>
+      </includes>
+    </fileSet>
+    <fileSet filtered="true" encoding="UTF-8">
+      <directory>src/main/resources</directory>
+      <includes>
+        <include>**/*.xml</include>
+      </includes>
+    </fileSet>
+    <fileSet encoding="UTF-8">
+      <directory>.settings</directory>
+      <includes>
+        <include>**/*.prefs</include>
+      </includes>
+    </fileSet>
+    <fileSet filtered="true" encoding="UTF-8">
+      <directory></directory>
+      <includes>
+        <include>.classpath</include>
+        <include>.project</include>
+      </includes>
+    </fileSet>
+  </fileSets>
+</archetype-descriptor>
diff --git a/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/pom.xml b/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/pom.xml
new file mode 100644 (file)
index 0000000..da1bd41
--- /dev/null
@@ -0,0 +1,63 @@
+#set( $dollar = '$' )
+<?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>commons.opendaylight</artifactId>
+    <version>1.4.1-SNAPSHOT</version>
+    <relativePath>../../commons/opendaylight</relativePath>
+  </parent>
+
+  <artifactId>${artifactId}</artifactId>
+
+  <groupId>${groupId}</groupId>
+  <packaging>bundle</packaging>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>${bundle.plugin.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Export-Package></Export-Package>
+            <Import-Package>org.opendaylight.controller.northbound.commons,
+              com.sun.jersey.spi.container.servlet,
+              com.fasterxml.jackson.annotation,
+              javax.ws.rs,
+              javax.ws.rs.core,
+              javax.xml.bind,
+              javax.xml.bind.annotation,
+              org.slf4j,
+              org.apache.catalina.filters,
+              com.fasterxml.jackson.jaxrs.base,
+              com.fasterxml.jackson.jaxrs.json,
+              !org.codehaus.enunciate.jaxrs</Import-Package>
+            <Web-ContextPath>/northbound/${artifactId}</Web-ContextPath>
+            <Jaxrs-Resources>,${dollar}{classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
+          </instructions>
+          <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <version>${version}</version>
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.enunciate</groupId>
+      <artifactId>enunciate-core-annotations</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>commons.northbound</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/java/Northbound.java b/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/java/Northbound.java
new file mode 100644 (file)
index 0000000..788dec8
--- /dev/null
@@ -0,0 +1,70 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+package ${package};
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.SecurityContext;
+
+import org.codehaus.enunciate.jaxrs.StatusCodes;
+import org.codehaus.enunciate.jaxrs.TypeHint;
+
+/**
+ * Northbound REST API
+ *
+ * <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.
+ */
+
+@Path("/")
+public class Northbound {
+
+    private String username;
+
+    @Context
+    public void setSecurityContext(SecurityContext context) {
+        if (context != null && context.getUserPrincipal() != null) {
+            username = context.getUserPrincipal().getName();
+        }
+    }
+
+    /**
+     *
+     * Sample REST API call
+     *
+     * @return A response string
+     *
+     *         <pre>
+     * Example:
+     *
+     * Request URL:
+     * http://localhost:8080/northbound/${artifactId}/api
+     *
+     * Response body in XML:
+     * &lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?&gt;
+     * Sample Northbound API
+     *
+     * Response body in JSON:
+     * Sample Northbound API
+     * </pre>
+     */
+    @Path("/api")
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+    @TypeHint(String.class)
+    @StatusCodes()
+    public String getWidget() {
+        String result = "Sample Northbound API - ${artifactId}";
+        return result;
+    }
+
+}
diff --git a/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/resources/WEB-INF/web.xml b/opendaylight/northbound/archetype-app-northbound/src/main/resources/archetype-resources/src/main/resources/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..a1d8376
--- /dev/null
@@ -0,0 +1,92 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+  version="3.0">
+  <servlet>
+    <servlet-name>JAXRS${artifactId}</servlet-name>
+    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>javax.ws.rs.Application</param-name>
+      <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>JAXRS${artifactId}</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>CorsFilter</filter-name>
+    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
+    <init-param>
+      <param-name>cors.allowed.origins</param-name>
+      <param-value>*</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.allowed.methods</param-name>
+      <param-value>GET,POST,HEAD,OPTIONS,PUT,DELETE</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.allowed.headers</param-name>
+      <param-value>Content-Type,X-Requested-With,accept,authorization, origin,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.exposed.headers</param-name>
+      <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.support.credentials</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>cors.preflight.maxage</param-name>
+      <param-value>10</param-value>
+    </init-param>
+  </filter>
+  <filter-mapping>
+    <filter-name>CorsFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <security-constraint>
+    <web-resource-collection>
+      <web-resource-name>${artifactId}</web-resource-name>
+      <url-pattern>/*</url-pattern>
+      <http-method>POST</http-method>
+      <http-method>GET</http-method>
+      <http-method>PUT</http-method>
+      <http-method>PATCH</http-method>
+      <http-method>DELETE</http-method>
+      <http-method>HEAD</http-method>
+    </web-resource-collection>
+    <auth-constraint>
+      <role-name>System-Admin</role-name>
+      <role-name>Network-Admin</role-name>
+      <role-name>Network-Operator</role-name>
+      <role-name>Container-User</role-name>
+    </auth-constraint>
+  </security-constraint>
+
+  <security-role>
+    <role-name>System-Admin</role-name>
+  </security-role>
+  <security-role>
+    <role-name>Network-Admin</role-name>
+  </security-role>
+  <security-role>
+    <role-name>Network-Operator</role-name>
+  </security-role>
+  <security-role>
+    <role-name>Container-User</role-name>
+  </security-role>
+
+  <login-config>
+    <auth-method>BASIC</auth-method>
+    <realm-name>opendaylight</realm-name>
+  </login-config>
+</web-app>
diff --git a/opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/archetype.properties b/opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/archetype.properties
new file mode 100644 (file)
index 0000000..40d9d65
--- /dev/null
@@ -0,0 +1,5 @@
+#Fri Mar 07 21:17:20 CST 2014
+package=it.pkg
+version=0.1-SNAPSHOT
+groupId=archetype.it
+artifactId=basic
diff --git a/opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/goal.txt b/opendaylight/northbound/archetype-app-northbound/src/test/resources/projects/basic/goal.txt
new file mode 100644 (file)
index 0000000..e69de29
index 47bb3ffd7c72df59e0804527412a5a897dc922db..4393b79f6446463074b869918651c273ff6cfa2a 100644 (file)
@@ -12,14 +12,13 @@ import java.util.Dictionary;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+
 import javax.ws.rs.core.Application;
 import javax.ws.rs.ext.ContextResolver;
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
 import org.opendaylight.controller.northbound.bundlescanner.IBundleScanService;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -30,12 +29,14 @@ import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+
 /**
  * Instance of javax.ws.rs.core.Application used to return the classes
  * that will be instantiated for JAXRS processing. This hooks onto the
  * bundle scanner service to provide JAXB classes to JAX-RS for prorcessing.
  */
-@SuppressWarnings("unchecked")
 public class NorthboundApplication extends Application {
     public static final String JAXRS_RESOURCES_MANIFEST_NAME = "Jaxrs-Resources";
     public static final String JAXRS_EXCLUDES_MANIFEST_NAME = "Jaxrs-Exclude-Types";
@@ -97,7 +98,7 @@ public class NorthboundApplication extends Application {
     }
 
     private static final IBundleScanService lookupBundleScanner(BundleContext ctx) {
-        ServiceReference svcRef = ctx.getServiceReference(IBundleScanService.class);
+        ServiceReference<?> svcRef = ctx.getServiceReference(IBundleScanService.class);
         if (svcRef == null) {
             throw new ServiceException("Unable to lookup IBundleScanService");
         }
index 805f5be29601dcc8026d980b577e69af6758e7f1..9ef56e5dc440b612f5f70e0ec823fca3172aad2c 100644 (file)
@@ -114,6 +114,8 @@ public class BridgeDomainNorthbound {
            if (status.getCode().equals(StatusCode.SUCCESS)) {
                return Response.status(Response.Status.CREATED).build();
            }
+       } catch (Error e) {
+           throw e;
        } catch (Throwable t) {
            return Response.status(Response.Status.PRECONDITION_FAILED).build();
        }
@@ -161,7 +163,7 @@ public class BridgeDomainNorthbound {
           if (status.getCode().equals(StatusCode.SUCCESS)) {
               return Response.status(Response.Status.OK).build();
           }
-      } catch (Throwable t) {
+      } catch (Exception t) {
           return Response.status(Response.Status.PRECONDITION_FAILED).build();
       }
       throw new ResourceNotFoundException(status.getDescription());
@@ -215,7 +217,7 @@ public class BridgeDomainNorthbound {
            if (status.getCode().equals(StatusCode.SUCCESS)) {
                return Response.status(Response.Status.CREATED).build();
            }
-       } catch (Throwable t) {
+       } catch (Exception t) {
            return Response.status(Response.Status.PRECONDITION_FAILED).build();
        }
        throw new ResourceNotFoundException(status.getDescription());
@@ -264,7 +266,7 @@ public class BridgeDomainNorthbound {
            if (status.getCode().equals(StatusCode.SUCCESS)) {
                return Response.status(Response.Status.OK).build();
            }
-       } catch (Throwable t) {
+       } catch (Exception t) {
            return Response.status(Response.Status.PRECONDITION_FAILED).build();
        }
        throw new ResourceNotFoundException(status.getDescription());
index 7590a976b6fe6f2e0abcf35a1ca900a8967e3413..774a12547944e9b943dde61a31535d1efe150960 100644 (file)
@@ -7,7 +7,6 @@
         <relativePath>../../../commons/opendaylight</relativePath>
     </parent>
     <properties>
-        <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
         <enunciate.version>1.26.2</enunciate.version>
     </properties>
   <scm>
         <!-- OpenDayLight Released artifact -->
         <repository>
             <id>opendaylight-release</id>
-            <url>${nexusproxy}/repositories/opendaylight.release/</url>
+            <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
         </repository>
         <!-- OpenDayLight Snapshot artifact -->
         <snapshotRepository>
             <id>opendaylight-snapshot</id>
-            <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+            <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
         </snapshotRepository>
         <!-- Site deployment -->
         <site>
index aa60f9117405270725514dc740f564ad8e2ccd03..f27d30eaae620312a75a7da2d47fa878936f5ccd 100644 (file)
@@ -54,6 +54,12 @@ public class SecureMessageReadWriteService implements IMessageReadWrite {
                                     // switch
     private ByteBuffer peerNetData; // encrypted message from the switch
     private FileInputStream kfd = null, tfd = null;
+    private final String keyStoreFileDefault = "./configuration/tlsKeyStore";
+    private final String trustStoreFileDefault = "./configuration/tlsTrustStore";
+    private final String keyStorePasswordPropName = "controllerKeyStorePassword";
+    private final String trustStorePasswordPropName = "controllerTrustStorePassword";
+    private static String keyStorePassword = null;
+    private static String trustStorePassword = null;
 
     public SecureMessageReadWriteService(SocketChannel socket, Selector selector)
             throws Exception {
@@ -80,32 +86,44 @@ public class SecureMessageReadWriteService implements IMessageReadWrite {
      */
     private void createSecureChannel(SocketChannel socket) throws Exception {
         String keyStoreFile = System.getProperty("controllerKeyStore");
-        String keyStorePassword = System
-                .getProperty("controllerKeyStorePassword");
         String trustStoreFile = System.getProperty("controllerTrustStore");
-        String trustStorePassword = System
-                .getProperty("controllerTrustStorePassword");
+        String keyStorePasswordProp = System.getProperty(keyStorePasswordPropName);
+        String trustStorePasswordProp = System.getProperty(trustStorePasswordPropName);
 
         if (keyStoreFile != null) {
             keyStoreFile = keyStoreFile.trim();
+        } else {
+            keyStoreFile = keyStoreFileDefault;
         }
         if ((keyStoreFile == null) || keyStoreFile.isEmpty()) {
             throw new FileNotFoundException("TLS KeyStore file not found.");
         }
+
+        if ((keyStorePassword == null) || ((keyStorePasswordProp != null) && !keyStorePasswordProp.isEmpty())) {
+            keyStorePassword = keyStorePasswordProp;
+        }
         if (keyStorePassword != null) {
             keyStorePassword = keyStorePassword.trim();
+            System.setProperty(keyStorePasswordPropName, "");
         }
         if ((keyStorePassword == null) || keyStorePassword.isEmpty()) {
             throw new FileNotFoundException("TLS KeyStore Password not provided.");
         }
         if (trustStoreFile != null) {
             trustStoreFile = trustStoreFile.trim();
+        } else {
+            trustStoreFile = trustStoreFileDefault;
         }
         if ((trustStoreFile == null) || trustStoreFile.isEmpty()) {
             throw new FileNotFoundException("TLS TrustStore file not found");
         }
+
+        if ((trustStorePassword == null) || ((trustStorePasswordProp != null) && !trustStorePasswordProp.isEmpty())) {
+            trustStorePassword = trustStorePasswordProp;
+        }
         if (trustStorePassword != null) {
             trustStorePassword = trustStorePassword.trim();
+            System.setProperty(trustStorePasswordPropName, "");
         }
         if ((trustStorePassword == null) || trustStorePassword.isEmpty()) {
             throw new FileNotFoundException("TLS TrustStore Password not provided.");
index b29ce15f5621aa0c09b29bafdf080448b973b628..548bfb1f9fb26eb93ab4ca5bcd456d9bdc4082c3 100644 (file)
@@ -836,8 +836,10 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             moveToReadyListHi(dst);
         }
 
+        //checking only OF map, since production edge discovery always overwrites any existing edge
+        UpdateType ut = edgeMap.containsKey(dst) ? UpdateType.CHANGED : UpdateType.ADDED;
         // notify
-        updateEdge(edge, UpdateType.ADDED, props);
+        updateEdge(edge, ut, props);
         logger.trace("Add edge {}", edge);
     }
 
@@ -936,6 +938,7 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa
             return;
         }
 
+
         this.discoveryListener.notifyEdge(edge, type, props);
 
         NodeConnector src = edge.getTailNodeConnector(), dst = edge.getHeadNodeConnector();
index 0208cc7cdac4693a2ffafb42a06d54b0e11e6e71..f972ae6a6679b9b1d4cc55afe39a63b276d17ce0 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.controller.sal.core.UpdateType;
 
 /**
  * The class represents an Edge, the Edge's Property Set and its UpdateType.
+ * If update is on new properties added to an existing edge, appropriate type is CHANGED.
  */
 public class TopoEdgeUpdate {
     private Edge edge;
index dc341625af642395872a3e2860a9d0fcc6f1ce3b..6b303f09f11955a053f7bcf740bf9f647b5df2ce 100644 (file)
@@ -355,9 +355,7 @@ public abstract class NetUtils {
      */
     public static boolean isMulticastMACAddr(byte[] MACAddress) {
         if (MACAddress.length == MACAddrLengthInBytes && !isBroadcastMACAddr(MACAddress)) {
-            if (MACAddress[0] % 2 == 1) {
-                return true;
-            }
+            return (MACAddress[0] & 1) != 0;
         }
         return false;
     }
index a2b12782ac2986f24cfd6fbe8f295f5ef105712d..e5e0a0941b7db0ccb6b647b313096f64def5fa90 100644 (file)
@@ -468,4 +468,35 @@ public class NetUtilsTest {
         Assert.assertEquals(32768, NetUtils.getUnsignedShort((short) 0x8000));
         Assert.assertEquals(65535, NetUtils.getUnsignedShort((short) 0xffff));
     }
+
+    @Test
+    public void testMulticastMACAddr() {
+        byte[] empty = new byte[0];
+        Assert.assertFalse(NetUtils.isUnicastMACAddr(empty));
+        Assert.assertFalse(NetUtils.isMulticastMACAddr(empty));
+
+        byte[] bcast = {
+            (byte)0xff, (byte)0xff, (byte)0xff,
+            (byte)0xff, (byte)0xff, (byte)0xff,
+        };
+        Assert.assertFalse(NetUtils.isUnicastMACAddr(bcast));
+        Assert.assertFalse(NetUtils.isMulticastMACAddr(bcast));
+
+        byte[] firstOctet = {
+            (byte)0x00, (byte)0x20, (byte)0x80, (byte)0xfe,
+        };
+        for (int len = 1; len <= 10; len++) {
+            byte[] ba = new byte[len];
+            boolean valid = (len == 6);
+            for (byte first: firstOctet) {
+                ba[0] = first;
+                Assert.assertFalse(NetUtils.isMulticastMACAddr(ba));
+                Assert.assertEquals(valid, NetUtils.isUnicastMACAddr(ba));
+
+                ba[0] |= (byte)0x01;
+                Assert.assertEquals(valid, NetUtils.isMulticastMACAddr(ba));
+                Assert.assertFalse(NetUtils.isUnicastMACAddr(ba));
+            }
+        }
+    }
 }
index 1a71511ef5bd0435fea671c08d10998dd9e18a00..ed9374b6faf22fbbd491126fac3d63f6a3c19ceb 100644 (file)
@@ -13,9 +13,6 @@ import java.util.Dictionary;
 import java.util.Hashtable;
 
 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.forwardingrulesmanager.IForwardingRulesManager;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
@@ -30,6 +27,8 @@ import org.opendaylight.controller.samples.simpleforwarding.IBroadcastPortSelect
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class Activator extends ComponentActivatorAbstractBase {
     protected static final Logger logger = LoggerFactory
@@ -45,6 +44,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * instantiated in order to get an fully working implementation
      * Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { SimpleForwardingImpl.class,
                          SimpleBroadcastHandlerImpl.class };
@@ -64,12 +64,17 @@ public class Activator extends ComponentActivatorAbstractBase {
      * also optional per-container different behavior if needed, usually
      * should not be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(SimpleForwardingImpl.class)) {
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put("salListenerName", "simpleforwarding");
+
             // export the service
             c.setInterface(new String[] { IInventoryListener.class.getName(),
                     IfNewHostNotify.class.getName(),
-                    IListenRoutingUpdates.class.getName() }, null);
+                    IListenRoutingUpdates.class.getName(),
+                    IListenDataPacket.class.getName() }, props);
 
             c.add(createContainerServiceDependency(containerName).setService(
                     IClusterContainerServices.class).setCallbacks(
@@ -96,7 +101,11 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createContainerServiceDependency(containerName).setService(
                     IRouting.class).setCallbacks("setRouting", "unsetRouting")
                     .setRequired(false));
-        }else if (imp.equals(SimpleBroadcastHandlerImpl.class)) {
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IDataPacketService.class).setCallbacks("setDataPacketService",
+                   "unsetDataPacketService").setRequired(false));
+
+        } else if (imp.equals(SimpleBroadcastHandlerImpl.class)) {
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "simplebroadcasthandler");
 
index d2016b1f6337b6923662268ae7d8029d34ae85b0..e39ae6569350e69d47fcc20fa15e20c1caa400bb 100644 (file)
@@ -12,12 +12,12 @@ import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
-import org.opendaylight.controller.sal.packet.Ethernet;
-import org.opendaylight.controller.sal.packet.IDataPacketService;
-import org.opendaylight.controller.sal.packet.IListenDataPacket;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.IDataPacketService;
+import org.opendaylight.controller.sal.packet.IListenDataPacket;
 import org.opendaylight.controller.sal.packet.Packet;
 import org.opendaylight.controller.sal.packet.PacketResult;
 import org.opendaylight.controller.sal.packet.RawPacket;
@@ -54,7 +54,7 @@ public class SimpleBroadcastHandlerImpl implements IBroadcastHandler, IListenDat
     public PacketResult receiveDataPacket(RawPacket inPkt) {
         /*
          * note that this assumes that the protocol plugin will do appropriate
-         * filtering to ensure that this only receives packets for it's
+         * filtering to ensure that this only receives packets for its
          * container.
          */
 
@@ -216,6 +216,7 @@ public class SimpleBroadcastHandlerImpl implements IBroadcastHandler, IListenDat
         lock.writeLock().unlock();
     }
 
+    @Override
     public void setMode(BroadcastMode m) {
         lock.writeLock().lock();
         mode = m;
index 4b3363b832d72ebbd12215d7236bba43009f4af3..b9d8fee986131328ea00be70394eb66f61b246ce 100644 (file)
@@ -9,6 +9,7 @@
 
 package org.opendaylight.controller.samples.simpleforwarding.internal;
 
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.HashMap;
@@ -45,9 +46,17 @@ import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.packet.Ethernet;
+import org.opendaylight.controller.sal.packet.IDataPacketService;
+import org.opendaylight.controller.sal.packet.IListenDataPacket;
+import org.opendaylight.controller.sal.packet.IPv4;
+import org.opendaylight.controller.sal.packet.Packet;
+import org.opendaylight.controller.sal.packet.PacketResult;
+import org.opendaylight.controller.sal.packet.RawPacket;
 import org.opendaylight.controller.sal.routing.IListenRoutingUpdates;
 import org.opendaylight.controller.sal.routing.IRouting;
 import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.samples.simpleforwarding.HostNodePair;
@@ -70,11 +79,10 @@ import org.slf4j.LoggerFactory;
  * installs those rules using <tt>installPerHostRules()</tt>.
  */
 public class SimpleForwardingImpl implements IfNewHostNotify,
-        IListenRoutingUpdates, IInventoryListener {
-    private static Logger log = LoggerFactory
-            .getLogger(SimpleForwardingImpl.class);
+        IListenRoutingUpdates, IInventoryListener, IListenDataPacket {
+    private static Logger log = LoggerFactory.getLogger(SimpleForwardingImpl.class);
     private static short DEFAULT_IPSWITCH_PRIORITY = 1;
-    private static String FORWARDING_RULES_CACHE_NAME = "forwarding.ipswitch.rules";
+    static final String FORWARDING_RULES_CACHE_NAME = "forwarding.ipswitch.rules";
     private IfIptoHost hostTracker;
     private IForwardingRulesManager frm;
     private ITopologyManager topologyManager;
@@ -90,6 +98,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
     private Map<Node, List<FlowEntry>> tobePrunedPos = new HashMap<Node, List<FlowEntry>>();
     private IClusterContainerServices clusterContainerService = null;
     private ISwitchManager switchManager;
+    private IDataPacketService dataPacketService;
 
     /**
      * Return codes from the programming of the perHost rules in HW
@@ -97,8 +106,19 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
     public enum RulesProgrammingReturnCode {
         SUCCESS, FAILED_FEW_SWITCHES, FAILED_ALL_SWITCHES, FAILED_WRONG_PARAMS
     }
+    public void setDataPacketService(IDataPacketService s) {
+        log.debug("Setting dataPacketService");
+        this.dataPacketService = s;
+    }
+
+    public void unsetDataPacketService(IDataPacketService s) {
+        if (this.dataPacketService == s) {
+            this.dataPacketService = null;
+        }
+    }
 
     public void setRouting(IRouting routing) {
+        log.debug("Setting routing");
         this.routing = routing;
     }
 
@@ -108,10 +128,6 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
         }
     }
 
-    public ITopologyManager getTopologyManager() {
-        return topologyManager;
-    }
-
     public void setTopologyManager(ITopologyManager topologyManager) {
         log.debug("Setting topologyManager");
         this.topologyManager = topologyManager;
@@ -670,8 +686,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
      *
      * @return a return code that convey the programming status of the HW
      */
-    private RulesProgrammingReturnCode uninstallPerHostRules(
-            HostNodeConnector host) {
+    private RulesProgrammingReturnCode uninstallPerHostRules(HostNodeConnector host) {
         RulesProgrammingReturnCode retCode = RulesProgrammingReturnCode.SUCCESS;
         Map<NodeConnector, FlowEntry> pos;
         FlowEntry po;
@@ -768,16 +783,12 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
         for (Node swId : switches) {
             List<FlowEntry> pl = tobePrunedPos.get(swId);
             if (pl != null) {
-                log
-                        .debug(
-                                "Policies for Switch: {} in the list to be deleted: {}",
-                                swId, pl);
+                log.debug("Policies for Switch: {} in the list to be deleted: {}", swId, pl);
                 Iterator<FlowEntry> plIter = pl.iterator();
                 //for (Policy po: pl) {
                 while (plIter.hasNext()) {
                     FlowEntry po = plIter.next();
-                    log.error("Removing Policy, Switch: {} Policy: {}", swId,
-                            po);
+                    log.error("Removing Policy, Switch: {} Policy: {}", swId, po);
                     this.frm.uninstallFlowEntry(po);
                     plIter.remove();
                 }
@@ -962,4 +973,56 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
             this.switchManager = null;
         }
     }
+
+    @Override
+    public PacketResult receiveDataPacket(RawPacket inPkt) {
+        if (inPkt == null) {
+            return PacketResult.IGNORED;
+        }
+        log.trace("Received a frame of size: {}", inPkt.getPacketData().length);
+        Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt);
+        if (formattedPak instanceof Ethernet) {
+            Object nextPak = formattedPak.getPayload();
+            if (nextPak instanceof IPv4) {
+                log.trace("Handle punted IP packet: {}", formattedPak);
+                handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector());
+            }
+        }
+        return PacketResult.IGNORED;
+
+    }
+
+    private void handlePuntedIPPacket(IPv4 pkt, NodeConnector incomingNodeConnector) {
+        InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress());
+        if (dIP == null || hostTracker == null) {
+            log.debug("Invalid param(s) in handlePuntedIPPacket.. DestIP: {}. hostTracker: {}", dIP, hostTracker);
+            return;
+        }
+        HostNodeConnector destHost = hostTracker.hostFind(dIP);
+        if (destHost != null
+                && (routing == null ||
+                    routing.getRoute(incomingNodeConnector.getNode(), destHost.getnodeconnectorNode()) != null)) {
+
+            log.trace("Host {} is at {}", dIP, destHost.getnodeConnector());
+            HostNodePair key = new HostNodePair(destHost, incomingNodeConnector.getNode());
+
+            // If SimpleForwarding is aware of this host, it will try to install
+            // a path. Forward packet until it's done.
+            if (dataPacketService != null && this.rulesDB.containsKey(key)) {
+
+
+                /*
+                 * if we know where the host is and there's a path from where this
+                 * packet was punted to where the host is, then attempt best effort delivery to the host
+                 */
+                NodeConnector nc = destHost.getnodeConnector();
+                log.trace("Forwarding punted IP received at {} to {}", incomingNodeConnector, nc);
+                // re-encode the Ethernet packet (the parent of the IPv4 packet)
+                RawPacket rp = this.dataPacketService.encodeDataPacket(pkt.getParent());
+                rp.setOutgoingNodeConnector(nc);
+                this.dataPacketService.transmitDataPacket(rp);
+            }
+
+        }
+    }
 }
index 002e06c0bf4fb3b84d3de4e2f6982552ed86a8b3..0f11284e53a4bce1db970d66ccc1a86cf024dc67 100644 (file)
@@ -11,6 +11,7 @@ package org.opendaylight.controller.switchmanager.internal;
 
 import org.apache.felix.dm.Component;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.configuration.IConfigurationContainerAware;
 import org.opendaylight.controller.configuration.IConfigurationContainerService;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
@@ -100,12 +101,34 @@ public class Activator extends ComponentActivatorAbstractBase {
                     IConfigurationContainerService.class).setCallbacks(
                     "setConfigurationContainerService",
                     "unsetConfigurationContainerService").setRequired(true));
+            c.add(createServiceDependency()
+                    .setService(IControllerProperties.class)
+                    .setCallbacks("setControllerProperties", "unsetControllerProperties")
+                    .setRequired(true));
         }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected Object[] getGlobalImplementations() {
-        final Object[] res = { SwitchManagerCLI.class };
+        final Object[] res = { ControllerProperties.class, SwitchManagerCLI.class };
         return res;
     }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void configureGlobalInstance(Component c, Object imp) {
+        if (imp.equals(ControllerProperties.class)) {
+            c.setInterface(new String[] { IControllerProperties.class.getName() }, null);
+
+            c.add(createServiceDependency()
+                    .setService(IClusterGlobalServices.class)
+                    .setCallbacks("setClusterService", "unsetClusterService")
+                    .setRequired(true));
+        }
+    }
 }
diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/ControllerProperties.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/ControllerProperties.java
new file mode 100644 (file)
index 0000000..4b319b8
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * 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.switchmanager.internal;
+
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+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.IClusterGlobalServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.sal.core.MacAddress;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The class ControllerProperties
+ * provides implementation for the ControllerProperties API
+ */
+public class ControllerProperties implements IControllerProperties {
+
+    private IClusterGlobalServices clusterService = null;
+    private final Logger log = LoggerFactory
+            .getLogger(ControllerProperties.class);
+    private static final String controllerGlobalPropertiesCacheName = "switchmanager.controllerGlobalProperties";
+
+    private ConcurrentMap<String, Property> controllerGlobalProperties;
+
+    private void allocateCaches() {
+        if (this.clusterService == null) {
+            this.nonClusterObjectCreate();
+            log.warn("un-initialized clusterService, can't create cache");
+            return;
+        }
+        try {
+            this.clusterService.createCache(controllerGlobalPropertiesCacheName,
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+        } catch (CacheConfigException cce) {
+            log.error("\nCache configuration invalid - check cache mode");
+        } catch (CacheExistException ce) {
+            log.error("\nCache already exits - destroy and recreate if needed");
+        }
+    }
+
+    private void nonClusterObjectCreate() {
+        controllerGlobalProperties = new ConcurrentHashMap<String, Property>();
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    private void retrieveCaches() {
+        if (this.clusterService == null) {
+            log.warn("un-initialized clusterService, can't create cache");
+            return;
+        }
+        controllerGlobalProperties = (ConcurrentMap<String, Property>) this.clusterService
+                .getCache(controllerGlobalPropertiesCacheName);
+        if (controllerGlobalProperties == null) {
+            log.error("\nFailed to get cache for controllerGlobalProperties");
+        }
+    }
+
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     * @param c Component
+     */
+    void init(Component c) {
+        // Instantiate cluster synced variables
+        allocateCaches();
+        retrieveCaches();
+    }
+
+    private void initializeProperties() {
+        byte controllerMac[] = getHardwareMAC();
+        if (controllerMac != null) {
+            Property existing = controllerGlobalProperties.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
+            if (existing == null && log.isTraceEnabled()) {
+                log.trace("Setting controller MAC address in the cluster: {}", HexEncode.bytesToHexStringFormat(controllerMac));
+            }
+        }
+    }
+
+    private byte[] getHardwareMAC() {
+        Enumeration<NetworkInterface> nis;
+        byte[] macAddress = null;
+
+        try {
+            nis = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException e) {
+            log.error("Failed to acquire controller MAC: ", e);
+            return macAddress;
+        }
+
+        while (nis.hasMoreElements()) {
+            NetworkInterface ni = nis.nextElement();
+            try {
+                macAddress = ni.getHardwareAddress();
+            } catch (SocketException e) {
+                log.error("Failed to acquire controller MAC: ", e);
+            }
+            if (macAddress != null && macAddress.length != 0) {
+                break;
+            }
+        }
+        if (macAddress == null) {
+            log.warn("Failed to acquire controller MAC: No physical interface found");
+            // This happens when running controller on windows VM, for example
+            // TODO: Try parsing the OS command output
+            // For now provide a quick fix for the release
+            macAddress = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x0c, (byte) 0x60, (byte) 0x0D, (byte) 0x10 };
+            log.debug("Assigning custom MAC address to controller");
+        }
+        return macAddress;
+    }
+
+    /**
+     * 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() {
+        // initialize required properties if first node in the cluster
+        if(this.clusterService.amICoordinator()) {
+            initializeProperties();
+        }
+    }
+
+    /**
+     * Function called after registered the service in OSGi service registry.
+     */
+    void started() {
+        // nothing to do
+    }
+
+    /**
+     * Function called before services of the component are removed
+     * from OSGi service registry.
+     */
+    void stopping() {
+        // nothing to do
+    }
+
+    /**
+     * 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() {
+        // nothing to do
+    }
+
+    /**
+     * 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() {
+        // nothing to do
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Map<String, Property> getControllerProperties() {
+        return new HashMap<String, Property>(this.controllerGlobalProperties);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Property getControllerProperty(String propertyName) {
+        if (propertyName != null) {
+            return this.controllerGlobalProperties.get(propertyName);
+        }
+        return null;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Status setControllerProperty(Property property) {
+        if (property != null) {
+            this.controllerGlobalProperties.put(property.getName(), property);
+            return new Status(StatusCode.SUCCESS);
+        }
+        return new Status(StatusCode.BADREQUEST, "Invalid property provided when setting property");
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public Status removeControllerProperty(String propertyName) {
+        if (propertyName != null) {
+            this.controllerGlobalProperties.remove(propertyName);
+            return new Status(StatusCode.SUCCESS);
+        }
+        return new Status(StatusCode.BADREQUEST, "Invalid property provided when removing property");
+    }
+
+    /**
+     * setClusterService
+     * @param s
+     */
+    public void setClusterService(IClusterGlobalServices s) {
+        this.clusterService = s;
+    }
+
+    /**
+     * unsetClusterServices
+     * @param s
+     */
+    public void unsetClusterServices(IClusterGlobalServices s) {
+        if (this.clusterService == s) {
+            this.clusterService = null;
+        }
+    }
+
+}
diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/IControllerProperties.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/IControllerProperties.java
new file mode 100644 (file)
index 0000000..f9301e2
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * 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.switchmanager.internal;
+
+import java.util.Map;
+
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.utils.Status;
+
+/**
+ * The class ControllerProperties is a global store
+ * for controller properties. Use this api to store/retrieve properties
+ * that are container independent.
+ *
+ * This is visible only to switch manager. Hence its a part of
+ * switch manager internal bundle.
+ */
+public interface IControllerProperties {
+
+    /**
+     * Return all the global properties of the controller
+     *
+     * @return map of {@link org.opendaylight.controller.sal.core.Property} such
+     *         as {@link org.opendaylight.controller.sal.core.Description}
+     *         and/or {@link org.opendaylight.controller.sal.core.Tier} etc.
+     */
+    public Map<String, Property> getControllerProperties();
+
+    /**
+     * Return a specific property of the controller given the property name
+     *
+     * @param propertyName
+     *            the property name specified by
+     *            {@link org.opendaylight.controller.sal.core.Property} and its
+     *            extended classes
+     * @return {@link org.opendaylight.controller.sal.core.Property}
+     */
+    public Property getControllerProperty(String propertyName);
+
+    /**
+     * Set a specific property of the controller
+     *
+     * @param property
+     *            {@link org.opendaylight.controller.sal.core.Property}
+     * @return Status
+     */
+    public Status setControllerProperty(Property property);
+
+    /**
+     * Remove a property of a node
+     *
+     * @param propertyName
+     *            the property name specified by
+     *            {@link org.opendaylight.controller.sal.core.Property} and its
+     *            extended classes
+     * @return success or failed reason
+     */
+    public Status removeControllerProperty(String propertyName);
+
+}
index e457fecfedf9b75d5ec1f59f006d64775472e144..07252b06f78dfb2a80a4c88d112f6b3f41fd5422 100644 (file)
@@ -12,13 +12,10 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.EnumSet;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -56,7 +53,6 @@ import org.opendaylight.controller.sal.inventory.IInventoryService;
 import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
 import org.opendaylight.controller.sal.reader.NodeDescription;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
-import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.IObjectReader;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
@@ -102,6 +98,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     private ConcurrentMap<String, Property> controllerProps;
     private IInventoryService inventoryService;
     private IStatisticsManager statisticsManager;
+    private IControllerProperties controllerProperties;
     private IConfigurationContainerService configurationService;
     private final Set<ISwitchManagerAware> switchManagerAware = Collections
             .synchronizedSet(new HashSet<ISwitchManagerAware>());
@@ -171,13 +168,13 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         retrieveCaches();
 
         // Add controller MAC, if first node in the cluster
-        if (!controllerProps.containsKey(MacAddress.name)) {
-            byte controllerMac[] = getHardwareMAC();
+        if ((!controllerProps.containsKey(MacAddress.name)) && (controllerProperties != null)) {
+            Property controllerMac = controllerProperties.getControllerProperty(MacAddress.name);
             if (controllerMac != null) {
-                Property existing = controllerProps.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
+                Property existing = controllerProps.putIfAbsent(MacAddress.name, controllerMac);
                 if (existing == null && log.isTraceEnabled()) {
                     log.trace("Container {}: Setting controller MAC address in the cluster: {}", getContainerName(),
-                            HexEncode.bytesToHexStringFormat(controllerMac));
+                            controllerMac);
                 }
             }
         }
@@ -1405,36 +1402,6 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         return (propMap != null) ? propMap.get(propName) : null;
     }
 
-    private byte[] getHardwareMAC() {
-        Enumeration<NetworkInterface> nis;
-        byte[] macAddress = null;
-
-        try {
-            nis = NetworkInterface.getNetworkInterfaces();
-        } catch (SocketException e) {
-            log.error("Failed to acquire controller MAC: ", e);
-            return macAddress;
-        }
-
-        while (nis.hasMoreElements()) {
-            NetworkInterface ni = nis.nextElement();
-            try {
-                macAddress = ni.getHardwareAddress();
-            } catch (SocketException e) {
-                log.error("Failed to acquire controller MAC: ", e);
-            }
-            if (macAddress != null && macAddress.length != 0) {
-                break;
-            }
-        }
-        if (macAddress == null) {
-            log.warn("Failed to acquire controller MAC: No physical interface found");
-            // This happens when running controller on windows VM, for example
-            // Try parsing the OS command output
-        }
-        return macAddress;
-    }
-
     @Override
     public byte[] getControllerMAC() {
         MacAddress macProperty = (MacAddress)controllerProps.get(MacAddress.name);
@@ -1793,6 +1760,16 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         }
     }
 
+    public void setControllerProperties(IControllerProperties controllerProperties) {
+        log.trace("Got controller properties set request {}", controllerProperties);
+        this.controllerProperties = controllerProperties;
+    }
+
+    public void unsetControllerProperties(IControllerProperties controllerProperties) {
+        log.trace("Got controller properties UNset request");
+        this.controllerProperties = null;
+    }
+
     private void getInventories() {
         if (inventoryService == null) {
             log.trace("inventory service not avaiable");
index cc1a8b868d3d376c9eb4a66b5443707adbfbff31..ff1c026a344d74efa5aa1f1b57e05e60775cd1a4 100644 (file)
@@ -573,6 +573,13 @@ public class TopologyManagerImpl implements
         switch (type) {
         case ADDED:
 
+
+            if (this.edgesDB.containsKey(e)) {
+                // Avoid redundant updates (e.g. cluster switch-over) as notifications trigger expensive tasks
+                log.trace("Skipping redundant edge addition: {}", e);
+                return null;
+            }
+
             // Make sure the props are non-null or create a copy
             if (props == null) {
                 props = new HashSet<Property>();
@@ -580,19 +587,6 @@ public class TopologyManagerImpl implements
                 props = new HashSet<Property>(props);
             }
 
-            Set<Property> currentProps = this.edgesDB.get(e);
-            if (currentProps != null) {
-
-                if (currentProps.equals(props)) {
-                    // Avoid redundant updates as notifications trigger expensive tasks
-                    log.trace("Skipping redundant edge addition: {}", e);
-                    return null;
-                }
-
-                // In case of node switch-over to a different cluster controller,
-                // let's retain edge props (e.g. creation time)
-                props.addAll(currentProps);
-            }
 
             // Ensure that head node connector exists
             if (!headNodeConnectorExist(e)) {
@@ -654,10 +648,9 @@ public class TopologyManagerImpl implements
         case CHANGED:
             Set<Property> oldProps = this.edgesDB.get(e);
 
-            // When property changes lets make sure we can change it
+            // When property(s) changes lets make sure we can change it
             // all except the creation time stamp because that should
-            // be changed only when the edge is destroyed and created
-            // again
+            // be set only when the edge is created
             TimeStamp timeStamp = null;
             for (Property prop : oldProps) {
                 if (prop instanceof TimeStamp) {
index a118ccfbba70658fd4e2c817ea5a9e60bce7b500..e4bb790676379bfb508ea6b6eec4051a38286636 100644 (file)
@@ -23,7 +23,6 @@ import java.util.concurrent.ConcurrentMap;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
@@ -60,6 +59,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
 
@@ -145,21 +145,21 @@ public class Devices implements IDaylightWeb {
                     for (NodeConnector nodeConnector : nodeConnectorSet) {
                         String nodeConnectorNumberToStr = nodeConnector.getID().toString();
                         Name ncName = ((Name) switchManager.getNodeConnectorProp(nodeConnector, Name.NamePropName));
-                        Config portStatus = ((Config) switchManager.getNodeConnectorProp(nodeConnector,
+                        Config portConfig = ((Config) switchManager.getNodeConnectorProp(nodeConnector,
                                 Config.ConfigPropName));
                         State portState = ((State) switchManager.getNodeConnectorProp(nodeConnector,
                                 State.StatePropName));
                         String nodeConnectorName = (ncName != null) ? ncName.getValue() : "";
                         nodeConnectorName += " (" + nodeConnector.getID() + ")";
 
-                        if (portStatus != null) {
-                            if (portStatus.getValue() == Config.ADMIN_UP) {
-                                if (portState.getValue() == State.EDGE_UP) {
+                        if (portConfig != null) {
+                            if (portConfig.getValue() == Config.ADMIN_UP) {
+                                if (portState != null && portState.getValue() == State.EDGE_UP) {
                                     nodeConnectorName = "<span class='admin-up'>" + nodeConnectorName + "</span>";
-                                } else if (portState.getValue() == State.EDGE_DOWN) {
+                                } else if (portState == null || portState.getValue() == State.EDGE_DOWN) {
                                     nodeConnectorName = "<span class='edge-down'>" + nodeConnectorName + "</span>";
                                 }
-                            } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
+                            } else if (portConfig.getValue() == Config.ADMIN_DOWN) {
                                 nodeConnectorName = "<span class='admin-down'>" + nodeConnectorName + "</span>";
                             }
                         }
index 259ffde4b447e1d5d8c916ff96a26ee38198b3bf..4304d76b0d5630774ad98d0d121d31765bafd406 100644 (file)
@@ -14,11 +14,15 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 
 import javax.servlet.http.HttpServletRequest;
 
 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.sal.action.Action;
+import org.opendaylight.controller.sal.action.ActionType;
+import org.opendaylight.controller.sal.action.SupportedFlowActions;
 import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.core.Description;
@@ -212,7 +216,6 @@ public class Flows implements IDaylightWeb {
         return nodes;
     }
 
-
     @RequestMapping(value = "/flow", method = RequestMethod.POST)
     @ResponseBody
     public String actionFlow(@RequestParam(required = true) String action, @RequestParam(required = false) String body,
@@ -337,6 +340,84 @@ public class Flows implements IDaylightWeb {
         }
     }
 
+    @RequestMapping(value = "/valid-flows/{nodeId}")
+    @ResponseBody
+    public Object getValidActions(HttpServletRequest request, @RequestParam(required = false) String container,
+            @PathVariable("nodeId") String nodeId) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
+            return "Operation not authorized";
+        }
+
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName, this);
+        if (switchManager == null) {
+            return null;
+        }
+
+        Map<String, String> result = new TreeMap<String, String>();
+
+        Node node = Node.fromString(nodeId);
+        SupportedFlowActions supportedFlows = (SupportedFlowActions) switchManager.getNodeProp(node, "supportedFlowActions");
+        List<Class<? extends Action>> actions = supportedFlows.getActions();
+        for (Class<? extends Action> action : actions) {
+            String actionName = action.getSimpleName().toLowerCase();
+            if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Drop.class)) {
+                result.put(ActionType.DROP.toString(), "Drop");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Loopback.class)) {
+                result.put(ActionType.LOOPBACK.toString(), "Loopback");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Flood.class)) {
+                result.put(ActionType.FLOOD.toString(), "Flood");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.FloodAll.class)) {
+                result.put(ActionType.FLOOD_ALL.toString(), "Flood All");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Controller.class)) {
+                result.put(ActionType.CONTROLLER.toString(), "Controller");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SwPath.class)) {
+                result.put(ActionType.SW_PATH.toString(), "Software Path");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.HwPath.class)) {
+                result.put(ActionType.HW_PATH.toString(), "Hardware Path");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Output.class)) {
+                result.put(ActionType.OUTPUT.toString(), "Output");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.Enqueue.class)) {
+                result.put(ActionType.ENQUEUE.toString(), "Enqueue");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetDlSrc.class)) {
+                result.put(ActionType.SET_DL_SRC.toString(), "Set Datalayer Source Address");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetDlDst.class)) {
+                result.put(ActionType.SET_DL_DST.toString(), "Set Datalayer Destination Address");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetVlanId.class)) {
+                result.put(ActionType.SET_VLAN_ID.toString(), "Set VLAN ID");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetVlanPcp.class)) {
+                result.put(ActionType.SET_VLAN_PCP.toString(), "Set VLAN Priority");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetVlanCfi.class)) {
+                result.put(ActionType.SET_VLAN_CFI.toString(), "Set VLAN CFI");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.PopVlan.class)) {
+                result.put(ActionType.POP_VLAN.toString(), "Pop VLAN");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.PushVlan.class)) {
+                result.put(ActionType.PUSH_VLAN.toString(), "Push VLAN");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetDlType.class)) {
+                result.put(ActionType.SET_DL_TYPE.toString(), "Set EtherType");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetNwSrc.class)) {
+                result.put(ActionType.SET_NW_SRC.toString(), "Set Network Source Address");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetNwDst.class)) {
+                result.put(ActionType.SET_NW_DST.toString(), "Set Network Destination Address");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetNwTos.class)) {
+                result.put(ActionType.SET_NW_TOS.toString(), "Modify ToS Bits");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetTpSrc.class)) {
+                result.put(ActionType.SET_TP_SRC.toString(), "Modify Transport Source Port");
+            } else if (action.isAssignableFrom(org.opendaylight.controller.sal.action.SetTpDst.class)) {
+                result.put(ActionType.SET_TP_DST.toString(), "Modify Transport Destination Port");
+            }
+        }
+
+        return result;
+    }
+
+    private boolean actionCompare(String name, ActionType type) {
+        return name.equals(type.getId().toLowerCase());
+    }
+
     private String getNodeDesc(Node node, ISwitchManager switchManager) {
         Description desc = (Description) switchManager.getNodeProp(node, Description.propertyName);
         String description = (desc == null) ? "" : desc.getValue();
index ab8301bf73dd21fb842aeee16b3a80dc647039a2..61d77489769742c32b6b261f1ee32e274724ceb7 100644 (file)
@@ -11,1593 +11,1664 @@ one.f = {};
 
 // specify dashlets and layouts
 one.f.dashlet = {
-    flows : {
-        id : 'flows',
-        name : 'Flow Entries'
-    },
-    nodes : {
-        id : 'nodes',
-        name : 'Nodes'
-    },
-    detail : {
-        id : 'detail',
-        name : 'Flow Detail'
-    }
+  flows : {
+    id : 'flows',
+    name : 'Flow Entries'
+  },
+  nodes : {
+    id : 'nodes',
+    name : 'Nodes'
+  },
+  detail : {
+    id : 'detail',
+    name : 'Flow Detail'
+  }
 };
 
 one.f.menu = {
-    left : {
-        top : [
-            one.f.dashlet.flows
-        ],
-        bottom : [
-            one.f.dashlet.nodes
-        ]
-    },
-    right : {
-        top : [],
-        bottom : [
-            one.f.dashlet.detail
-        ]
-    }
+  left : {
+    top : [
+      one.f.dashlet.flows
+      ],
+    bottom : [
+      one.f.dashlet.nodes
+      ]
+  },
+  right : {
+    top : [],
+    bottom : [
+      one.f.dashlet.detail
+      ]
+  }
 };
 
 one.f.address = {
-    root : "/controller/web/flows",
-    flows : {
-        main : "/main",
-        flows : "/node-flows",
-        nodes : "/node-ports",
-        flow : "/flow",
-        modifyFlow : "/modifyFlow",
-        deleteFlows:"/flow/deleteFlows"
-    }
+  root : "/controller/web/flows",
+  flows : {
+    main : "/main",
+    flows : "/node-flows",
+    nodes : "/node-ports",
+    flow : "/flow",
+    modifyFlow : "/modifyFlow",
+    deleteFlows:"/flow/deleteFlows"
+  }
 }
 
 /** NODES **/
 one.f.nodes = {
-    id : {
-        dashlet: {
-            datagrid: "one_f_nodes_id_dashlet_datagrid"
-        }
-    },
-    registry : {},
-    dashlet : function($dashlet) {
-        var $h4 = one.lib.dashlet.header("Nodes");
-        $dashlet.append($h4);
-
-        one.f.nodes.ajax.dashlet(function(data) {
-            var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, {
-                searchable: true,
-                filterable: false,
-                pagination: true,
-                flexibleRowsPerPage: true
-                }, "table-striped table-condensed");
-            $dashlet.append($gridHTML);
-            var dataSource = one.f.nodes.data.nodesDataGrid(data);
-            $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource});
-        });
-    },
-    ajax : {
-        dashlet : function(callback) {
-            $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
-                callback(data);
-            });
-        }
-    },
-    data : {
-        nodesDataGrid: function(data) {
-            var gridData = [];
-            $.each(data, function(nodeName, flow) {
-                var nodeFlowObject = {};
-                nodeFlowObject["nodeName"] = nodeName;
-                nodeFlowObject["flows"] = flow;
-                nodeFlowObject["rowData"] = nodeName + flow + "-foobar";
-                gridData.push(nodeFlowObject);
-            });
+  id : {
+    dashlet: {
+      datagrid: "one_f_nodes_id_dashlet_datagrid"
+    }
+  },
+  registry : {},
+  dashlet : function($dashlet) {
+    var $h4 = one.lib.dashlet.header("Nodes");
+    $dashlet.append($h4);
 
-            var source = new StaticDataSource({
-                    columns: [
-                        {
-                            property: 'nodeName',
-                            label: 'Node',
-                            sortable: true
-                        },
-                        {
-                            property: 'flows',
-                            label: 'Flows',
-                            sortable: true
-                        }
-                    ],
-                    data: gridData,
-                    delay: 0
-                });
-            return source;
-        }
-    },
-    body : {
-        dashlet : function(body, callback) {
-            var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
-            var $table = one.lib.dashlet.table.table(attributes);
+    one.f.nodes.ajax.dashlet(function(data) {
+      var $gridHTML = one.lib.dashlet.datagrid.init(one.f.nodes.id.dashlet.datagrid, {
+        searchable: true,
+          filterable: false,
+          pagination: true,
+          flexibleRowsPerPage: true
+      }, "table-striped table-condensed");
+      $dashlet.append($gridHTML);
+      var dataSource = one.f.nodes.data.nodesDataGrid(data);
+      $("#" + one.f.nodes.id.dashlet.datagrid).datagrid({dataSource: dataSource});
+    });
+  },
+  ajax : {
+    dashlet : function(callback) {
+      $.getJSON(one.f.address.root+one.f.address.flows.flows, function(data) {
+        callback(data);
+      });
+    }
+  },
+  data : {
+    nodesDataGrid: function(data) {
+      var gridData = [];
+      $.each(data, function(nodeName, flow) {
+        var nodeFlowObject = {};
+        nodeFlowObject["nodeName"] = nodeName;
+        nodeFlowObject["flows"] = flow;
+        nodeFlowObject["rowData"] = nodeName + flow + "-foobar";
+        gridData.push(nodeFlowObject);
+      });
+
+      var source = new StaticDataSource({
+        columns: [
+      {
+        property: 'nodeName',
+          label: 'Node',
+          sortable: true
+      },
+          {
+            property: 'flows',
+          label: 'Flows',
+          sortable: true
+          }
+      ],
+          data: gridData,
+          delay: 0
+      });
+      return source;
+    }
+  },
+  body : {
+    dashlet : function(body, callback) {
+      var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed'];
+      var $table = one.lib.dashlet.table.table(attributes);
 
-            var headers = ['Node', 'Flows'];
-            var $thead = one.lib.dashlet.table.header(headers);
-            $table.append($thead);
+      var headers = ['Node', 'Flows'];
+      var $thead = one.lib.dashlet.table.header(headers);
+      $table.append($thead);
 
-            var $tbody = one.lib.dashlet.table.body(body);
-            $table.append($tbody);
+      var $tbody = one.lib.dashlet.table.body(body);
+      $table.append($tbody);
 
-            return $table;
-        }
+      return $table;
     }
+  }
 }
 
 /** FLOW DETAIL **/
 one.f.detail = {
-    id : {},
-    registry : {},
-    dashlet : function($dashlet, details) {
-        var $h4 = one.lib.dashlet.header("Flow Details");
-        $dashlet.append($h4);
-
-        // details
-        if (details == undefined) {
-            var $none = $(document.createElement('div'));
-            $none.addClass('none');
-            var $p = $(document.createElement('p'));
-            $p.text('Please select a flow');
-            $p.addClass('text-center').addClass('text-info');
+  id : {},
+  registry : {},
+  dashlet : function($dashlet, details) {
+    var $h4 = one.lib.dashlet.header("Flow Details");
+    $dashlet.append($h4);
 
-            $dashlet.append($none)
-                .append($p);
-        }
-    },
-    data : {
-        dashlet : function(data) {
-            var body = [];
-            var tr = {};
-            var entry = [];
-
-            entry.push(data['name']);
-            entry.push(data['node']);
-            entry.push(data['flow']['priority']);
-            entry.push(data['flow']['hardTimeout']);
-            entry.push(data['flow']['idleTimeout']);
-
-            tr.entry = entry;
-            body.push(tr);
-            return body;
-        },
-        description : function(data) {
-            var body = [];
-            var tr = {};
-            var entry = [];
-            entry.push(data['flow']['ingressPort']);
-            entry.push(data['flow']['etherType']);
-            entry.push(data['flow']['vlanId']);
-            entry.push(data['flow']['vlanPriority']);
-            entry.push(data['flow']['srcMac']);
-            entry.push(data['flow']['dstMac']);
-            entry.push(data['flow']['srcIp']);
-            entry.push(data['flow']['dstIp']);
-            entry.push(data['flow']['tosBits']);
-            entry.push(data['flow']['srcPort']);
-            entry.push(data['flow']['dstPort']);
-            entry.push(data['flow']['protocol']);
-            entry.push(data['flow']['cookie']);
-
-            tr.entry = entry;
-            body.push(tr);
-            return body;
-        },
-        actions : function(data) {
-            var body = [];
-            var tr = {};
-            var entry = [];
-            var actions = '';
-
-            $(data['flow']['actions']).each(function(index, value) {
-                var locEqualTo = value.indexOf("=");
-                if ( locEqualTo == -1 ) {
-                    actions += value + ', ';
-                } else {
-                    var action = value.substr(0,locEqualTo);
-                    if( action == "OUTPUT") {
-                        var portIds = value.substr(locEqualTo+1).split(",");
-                        actions += action + "=";
-                        var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.selectedNode]['ports'];
-                        for(var i =0; i < portIds.length ; i++) {
-                            var portName = allPorts[portIds[i]];
-                            actions += portName + ", ";
-                        }
-                    } else {
-                        actions += value + ', ';
-                    }
-                }
-            });
-            actions = actions.slice(0,-2);
-            entry.push(actions);
+    // details
+    if (details == undefined) {
+      var $none = $(document.createElement('div'));
+      $none.addClass('none');
+      var $p = $(document.createElement('p'));
+      $p.text('Please select a flow');
+      $p.addClass('text-center').addClass('text-info');
 
-            tr.entry = entry;
-            body.push(tr);
-            return body;
+      $dashlet.append($none)
+        .append($p);
+    }
+  },
+  data : {
+    dashlet : function(data) {
+      var body = [];
+      var tr = {};
+      var entry = [];
+
+      entry.push(data['name']);
+      entry.push(data['node']);
+      entry.push(data['flow']['priority']);
+      entry.push(data['flow']['hardTimeout']);
+      entry.push(data['flow']['idleTimeout']);
+
+      tr.entry = entry;
+      body.push(tr);
+      return body;
+    },
+    description : function(data) {
+      var body = [];
+      var tr = {};
+      var entry = [];
+      entry.push(data['flow']['ingressPort']);
+      entry.push(data['flow']['etherType']);
+      entry.push(data['flow']['vlanId']);
+      entry.push(data['flow']['vlanPriority']);
+      entry.push(data['flow']['srcMac']);
+      entry.push(data['flow']['dstMac']);
+      entry.push(data['flow']['srcIp']);
+      entry.push(data['flow']['dstIp']);
+      entry.push(data['flow']['tosBits']);
+      entry.push(data['flow']['srcPort']);
+      entry.push(data['flow']['dstPort']);
+      entry.push(data['flow']['protocol']);
+      entry.push(data['flow']['cookie']);
+
+      tr.entry = entry;
+      body.push(tr);
+      return body;
+    },
+    actions : function(data) {
+      var body = [];
+      var tr = {};
+      var entry = [];
+      var actions = '';
+
+      $(data['flow']['actions']).each(function(index, value) {
+        var locEqualTo = value.indexOf("=");
+        if ( locEqualTo == -1 ) {
+          actions += value + ', ';
+        } else {
+          var action = value.substr(0,locEqualTo);
+          if( action == "OUTPUT") {
+            var portIds = value.substr(locEqualTo+1).split(",");
+            actions += action + "=";
+            var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.selectedNode]['ports'];
+            for(var i =0; i < portIds.length ; i++) {
+              var portName = allPorts[portIds[i]];
+              actions += portName + ", ";
+            }
+          } else {
+            actions += value + ', ';
+          }
         }
+      });
+      actions = actions.slice(0,-2);
+      entry.push(actions);
+
+      tr.entry = entry;
+      body.push(tr);
+      return body;
+    }
+  },
+  body : {
+    dashlet : function(body) {
+      // create table
+      var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
+      var $thead = one.lib.dashlet.table.header(header);
+      var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
+      var $table = one.lib.dashlet.table.table(attributes);
+      $table.append($thead);
+
+      var $tbody = one.lib.dashlet.table.body(body);
+      $table.append($tbody);
+
+      return $table;
     },
-    body : {
-        dashlet : function(body) {
-            // create table
-            var header = ['Flow Name', 'Node', 'Priority', 'Hard Timeout', 'Idle Timeout'];
-            var $thead = one.lib.dashlet.table.header(header);
-            var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
-            var $table = one.lib.dashlet.table.table(attributes);
-            $table.append($thead);
-
-            var $tbody = one.lib.dashlet.table.body(body);
-            $table.append($tbody);
-
-            return $table;
-        },
-        description : function(body) {
-            var header = ['Input Port', 'Ethernet Type', 'VLAN ID', 'VLAN Priority', 'Source MAC', 'Dest MAC', 'Source IP', 'Dest IP', 'ToS', 'Source Port', 'Dest Port', 'Protocol', 'Cookie'];
-            var $thead = one.lib.dashlet.table.header(header);
-            var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
-            var $table = one.lib.dashlet.table.table(attributes);
-            $table.append($thead);
+    description : function(body) {
+      var header = ['Input Port', 'Ethernet Type', 'VLAN ID', 'VLAN Priority', 'Source MAC', 'Dest MAC', 'Source IP', 'Dest IP', 'ToS', 'Source Port', 'Dest Port', 'Protocol', 'Cookie'];
+      var $thead = one.lib.dashlet.table.header(header);
+      var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
+      var $table = one.lib.dashlet.table.table(attributes);
+      $table.append($thead);
 
-            var $tbody = one.lib.dashlet.table.body(body);
-            $table.append($tbody);
+      var $tbody = one.lib.dashlet.table.body(body);
+      $table.append($tbody);
 
-            return $table;
-        },
-        actions : function(body) {
-            var header = ['Actions'];
-            var $thead = one.lib.dashlet.table.header(header);
-            var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
-            var $table = one.lib.dashlet.table.table(attributes);
-            $table.append($thead);
+      return $table;
+    },
+    actions : function(body) {
+      var header = ['Actions'];
+      var $thead = one.lib.dashlet.table.header(header);
+      var attributes = ['table-striped', 'table-bordered', 'table-condensed'];
+      var $table = one.lib.dashlet.table.table(attributes);
+      $table.append($thead);
 
-            var $tbody = one.lib.dashlet.table.body(body);
-            $table.append($tbody);
+      var $tbody = one.lib.dashlet.table.body(body);
+      $table.append($tbody);
 
-            return $table;
-        }
+      return $table;
     }
+  }
 }
 
 /** FLOW ENTRIES **/
 one.f.flows = {
-    id : {
-        dashlet : {
-            add : "one_f_flows_id_dashlet_add",
-            removeMultiple : "one_f_flows_id_dashlet_removeMultiple",
-            remove : "one_f_flows_id_dashlet_remove",
-            toggle : "one_f_flows_id_dashlet_toggle",
-            edit : "one_f_flows_id_dashlet_edit",
-            datagrid : "one_f_flows_id_dashlet_datagrid",
-            selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows"
-        },
+  id : {
+    dashlet : {
+      add : "one_f_flows_id_dashlet_add",
+      removeMultiple : "one_f_flows_id_dashlet_removeMultiple",
+      remove : "one_f_flows_id_dashlet_remove",
+      toggle : "one_f_flows_id_dashlet_toggle",
+      edit : "one_f_flows_id_dashlet_edit",
+      datagrid : "one_f_flows_id_dashlet_datagrid",
+      selectAllFlows : "one_f_flows_id_dashlet_selectAllFlows"
+    },
+    modal : {
+      install : "one_f_flows_id_modal_install",
+      edit : "one_f_flows_id_modal_edit",
+      add : "one_f_flows_id_modal_add",
+      close : "one_f_flows_id_modal_close",
+      modal : "one_f_flows_id_modal_modal",
+      dialog : {
+        modal : "one_f_flows_id_modal_dialog_modal",
+        remove : "one_f_flows_id_modal_dialog_remove",
+        close : "one_f_flows_id_modal_dialog_close"
+      },
+      action : {
+        button : "one_f_flows_id_modal_action_button",
+        modal : "one_f_flows_id_modal_action_modal",
+        add : "one_f_flows_id_modal_action_add",
+        close : "one_f_flows_id_modal_action_close",
+        table : "one_f_flows_id_modal_action_table",
+        addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
+        setVlanId : "one_f_flows_id_modal_action_setVlanId",
+        setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
+        modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
+        modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
+        modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
+        modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
+        modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
+        modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
+        modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
         modal : {
-            install : "one_f_flows_id_modal_install",
-            edit : "one_f_flows_id_modal_edit",
-            add : "one_f_flows_id_modal_add",
-            close : "one_f_flows_id_modal_close",
-            modal : "one_f_flows_id_modal_modal",
-            dialog : {
-                modal : "one_f_flows_id_modal_dialog_modal",
-                remove : "one_f_flows_id_modal_dialog_remove",
-                close : "one_f_flows_id_modal_dialog_close"
-            },
-            action : {
-                button : "one_f_flows_id_modal_action_button",
-                modal : "one_f_flows_id_modal_action_modal",
-                add : "one_f_flows_id_modal_action_add",
-                close : "one_f_flows_id_modal_action_close",
-                table : "one_f_flows_id_modal_action_table",
-                addOutputPorts : "one_f_flows_id_modal_action_addOutputPorts",
-                setVlanId : "one_f_flows_id_modal_action_setVlanId",
-                setVlanPriority : "one_f_flows_id_modal_action_setVlanPriority",
-                modifyDatalayerSourceAddress : "one_f_flows_id_modal_action_modifyDatalayerSourceAddress",
-                modifyDatalayerDestinationAddress : "one_f_flows_id_modal_action_modifyDatalayerDestinationAddress",
-                modifyNetworkSourceAddress : "one_f_flows_modal_action_modifyNetworkSourceAddress",
-                modifyNetworkDestinationAddress : "one_f_flows_modal_action_modifyNetworkDestinationAddress",
-                modifyTosBits : "one_f_flows_modal_action_modifyTosBits",
-                modifyTransportSourcePort : "one_f_flows_modal_action_modifyTransportSourcePort",
-                modifyTransportDestinationPort : "one_f_flows_modal_action_modifyTransportDestinationPort",
-                modal : {
-                    modal : "one_f_flows_modal_action_modal_modal",
-                    remove : "one_f_flows_modal_action_modal_remove",
-                    cancel : "one_f_flows_modal_action_modal_cancel"
-                }
-            },
-            form : {
-                name : "one_f_flows_id_modal_form_name",
-                nodes : "one_f_flows_id_modal_form_nodes",
-                port : "one_f_flows_id_modal_form_port",
-                priority : "one_f_flows_id_modal_form_priority",
-                hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
-                idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
-                cookie : "one_f_flows_id_modal_form_cookie",
-                etherType : "one_f_flows_id_modal_form_etherType",
-                vlanId : "one_f_flows_id_modal_form_vlanId",
-                vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
-                srcMac : "one_f_flows_id_modal_form_srcMac",
-                dstMac : "one_f_flows_id_modal_form_dstMac",
-                srcIp : "one_f_flows_id_modal_form_srcIp",
-                dstIp : "one_f_flows_id_modal_form_dstIp",
-                tosBits : "one_f_flows_id_modal_form_tosBits",
-                srcPort : "one_f_flows_id_modal_form_srcPort",
-                dstPort : "one_f_flows_id_modal_form_dstPort",
-                protocol : "one_f_flows_id_modal_form_protocol"
-            }
+          modal : "one_f_flows_modal_action_modal_modal",
+          remove : "one_f_flows_modal_action_modal_remove",
+          cancel : "one_f_flows_modal_action_modal_cancel"
         }
-    },
-    registry : {},
-    dashlet : function($dashlet, callback) {
-
-        // load body
-        one.f.flows.ajax.dashlet(function(data) {
-
-            var $h4 = one.lib.dashlet.header("Flow Entries");
-
-            $dashlet.append($h4);
-            if (one.f.flows.registry.privilege === 'WRITE') {
-                var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
-                var $button = one.lib.dashlet.button.button(button);
-
-                $button.click(function() {
-                    var $modal = one.f.flows.modal.initialize();
-                    $modal.modal();
-                });
-                $dashlet.append($button);
-                var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini");
-                var $button = one.lib.dashlet.button.button(button);
-
-                $button.click(function() {
-                    var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked');
-                    if (checkedCheckBoxes.size() === 0) {
-                        return false;
-                    }
-                    
-                    var requestData = [];
-                    
-                    checkedCheckBoxes.each(function(index, value) {
-                        var flowEntry = {};
-                        flowEntry['name'] = checkedCheckBoxes[index].name;
-                        flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node");
-                        requestData.push(flowEntry);  
-                    });
-                    one.f.flows.modal.removeMultiple.dialog(requestData);
-                });
-                $dashlet.append($button);
+      },
+      form : {
+        name : "one_f_flows_id_modal_form_name",
+        nodes : "one_f_flows_id_modal_form_nodes",
+        port : "one_f_flows_id_modal_form_port",
+        priority : "one_f_flows_id_modal_form_priority",
+        hardTimeout : "one_f_flows_id_modal_form_hardTimeout",
+        idleTimeout : "one_f_flows_id_modal_form_idleTimeout",
+        cookie : "one_f_flows_id_modal_form_cookie",
+        etherType : "one_f_flows_id_modal_form_etherType",
+        vlanId : "one_f_flows_id_modal_form_vlanId",
+        vlanPriority : "one_f_flows_id_modal_form_vlanPriority",
+        srcMac : "one_f_flows_id_modal_form_srcMac",
+        dstMac : "one_f_flows_id_modal_form_dstMac",
+        srcIp : "one_f_flows_id_modal_form_srcIp",
+        dstIp : "one_f_flows_id_modal_form_dstIp",
+        tosBits : "one_f_flows_id_modal_form_tosBits",
+        srcPort : "one_f_flows_id_modal_form_srcPort",
+        dstPort : "one_f_flows_id_modal_form_dstPort",
+        protocol : "one_f_flows_id_modal_form_protocol",
+        action : 'one-f-flows-id-modal-form-action'
+      }
+    }
+  },
+  registry : {},
+  dashlet : function($dashlet, callback) {
+    // load body
+    one.f.flows.ajax.dashlet(function(data) {
+      var $h4 = one.lib.dashlet.header("Flow Entries");
+      $dashlet.append($h4);
+      if (one.f.flows.registry.privilege === 'WRITE') {
+        var button = one.lib.dashlet.button.single("Add Flow Entry", one.f.flows.id.dashlet.add, "btn-primary", "btn-mini");
+        var $button = one.lib.dashlet.button.button(button);
+
+        $button.click(function() {
+          var $modal = one.f.flows.modal.initialize();
+          $modal.modal();
+        });
+        $dashlet.append($button);
+        var button = one.lib.dashlet.button.single("Remove Flow Entry", one.f.flows.id.dashlet.removeMultiple, "btn-danger", "btn-mini");
+        var $button = one.lib.dashlet.button.button(button);
+
+        $button.click(function() {
+          var checkedCheckBoxes = $('.flowEntry[type=checkbox]:checked');
+          if (checkedCheckBoxes.size() === 0) {
+            return false;
+          }
 
-            }
+          var requestData = [];
 
-            var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, {
-                searchable: true,
-                filterable: false,
-                pagination: true,
-                flexibleRowsPerPage: true
-                }, "table-striped table-condensed");
-            $dashlet.append($gridHTML);
-            var dataSource = one.f.flows.data.flowsDataGrid(data);
-            $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
-                    $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() {
-                                $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked',
-                                        $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked'));
-                    });
-                    
-                    $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) {
-                    $tr = $(tr);
-                    $span = $("td span", $tr);
-                    var flowstatus = $span.data("flowstatus");
-                    if($span.data("installinhw") != null) {
-                        var installInHw = $span.data("installinhw").toString();
-                        if(installInHw == "true" && flowstatus == "Success") {
-                            $tr.addClass("success");
-                        } else {
-                            $tr.addClass("warning");
-                        }
-                    }
-                    // attach mouseover to show pointer cursor
-                    $tr.mouseover(function() {
-                        $(this).css("cursor", "pointer");
-                    });
-                    // attach click event
-                    $tr.click(function() {
-                        var $td = $($(this).find("td")[1]);
-                        var id = $td.text();
-                        var node = $td.find("span").data("nodeid");
-                        one.f.flows.detail(id, node);
-                    });
-                    $(".flowEntry").click(function(e){
-                                if (!$('.flowEntry[type=checkbox]:not(:checked)').length) {
-                            $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
-                                .prop("checked",
-                              true);
-                        } else {
-                            $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
-                                .prop("checked",
-                             false);
-                        }
-                        e.stopPropagation();
-                    });
-                });
-            });
-            
-            // details callback
-            if(callback != undefined) callback();
+          checkedCheckBoxes.each(function(index, value) {
+            var flowEntry = {};
+            flowEntry['name'] = checkedCheckBoxes[index].name;
+            flowEntry['node'] = checkedCheckBoxes[index].getAttribute("node");
+            requestData.push(flowEntry);  
+          });
+          one.f.flows.modal.removeMultiple.dialog(requestData);
         });
-    },
-    detail : function(id, node) {
-        // clear flow details
-        var $detailDashlet = one.main.dashlet.right.bottom;
-        $detailDashlet.empty();
-        var $h4 = one.lib.dashlet.header("Flow Overview");
-        $detailDashlet.append($h4);
-
-        // details
-        var flows = one.f.flows.registry.flows;
-        one.f.flows.registry['selectedId'] = id;
-        one.f.flows.registry['selectedNode'] = node;
-        var flow;
-        $(flows).each(function(index, value) {
-          if (value.name == id && value.nodeId == node) {
-            flow = value;
-          }
+        $dashlet.append($button);
+
+      }
+      var $gridHTML = one.lib.dashlet.datagrid.init(one.f.flows.id.dashlet.datagrid, {
+        searchable: true,
+          filterable: false,
+          pagination: true,
+          flexibleRowsPerPage: true
+      }, "table-striped table-condensed");
+      $dashlet.append($gridHTML);
+      var dataSource = one.f.flows.data.flowsDataGrid(data);
+      $("#" + one.f.flows.id.dashlet.datagrid).datagrid({dataSource: dataSource}).on("loaded", function() {
+        $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).click(function() {
+          $("#" + one.f.flows.id.dashlet.datagrid).find(':checkbox').prop('checked',
+            $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows).is(':checked'));
         });
-        if (one.f.flows.registry.privilege === 'WRITE') {
-            // remove button
-            var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
-            var $button = one.lib.dashlet.button.button(button);
-            $button.click(function() {
-                var $modal = one.f.flows.modal.dialog.initialize(id, node);
-                $modal.modal();
-            });
-            // edit button
-            var editButton = one.lib.dashlet.button.single("Edit Flow", one.f.flows.id.dashlet.edit, "btn-primary", "btn-mini");
-            var $editButton = one.lib.dashlet.button.button(editButton);
-            $editButton.click(function() {
-               var install = flow['flow']['installInHw'];
-                var $modal = one.f.flows.modal.initialize(true,install);
-                $modal.modal().on('shown',function(){
-                    var $port = $('#'+one.f.flows.id.modal.form.port);
-                    $('#'+one.f.flows.id.modal.form.nodes).trigger("change");
-                });
-            });
-            // toggle button
-            var toggle;
-            if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
-                toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
-            } else {
-                toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
-            }
-            var $toggle = one.lib.dashlet.button.button(toggle);
-            $toggle.click(function() {
-                one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
-                    if(data == "Success") {
-                        one.main.dashlet.right.bottom.empty();
-                        one.f.detail.dashlet(one.main.dashlet.right.bottom);
-                        one.main.dashlet.left.top.empty();
-                        one.f.flows.dashlet(one.main.dashlet.left.top, function() {
-                           // checks are backwards due to stale registry
-                           if(flow['flow']['installInHw'] == 'true') {
-                               one.lib.alert('Uninstalled Flow');
-                           } else {
-                               one.lib.alert('Installed Flow');
-                           }
-                           one.f.flows.detail(id, node)
-                        });
-                    } else {
-                        one.lib.alert('Cannot toggle flow: '+data);
-                    }
-                });
-            });
 
-            $detailDashlet.append($button).append($editButton).append($toggle);
-        }
-        // append details
-        var body = one.f.detail.data.dashlet(flow);
-        var $body = one.f.detail.body.dashlet(body);
-        $detailDashlet.append($body);
-        var body = one.f.detail.data.description(flow);
-        var $body = one.f.detail.body.description(body);
-        $detailDashlet.append($body);
-        var body = one.f.detail.data.actions(flow);
-        var $body = one.f.detail.body.actions(body);
-        $detailDashlet.append($body);
-    },
-    modal : {
-        dialog : {
-            initialize : function(id, node) {
-                var h3 = "Remove Flow";
-                var $p = one.f.flows.modal.dialog.body(id);
-                var footer = one.f.flows.modal.dialog.footer();
-                var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
-                $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
-                    $modal.modal('hide');
-                });
-                $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
-                    one.f.flows.modal.ajax.removeflow(id, node, function(data) {
-                        if (data == "Success") {
-                            $modal.modal('hide');
-                            one.main.dashlet.right.bottom.empty();
-                            one.f.detail.dashlet(one.main.dashlet.right.bottom);
-                            one.main.dashlet.left.top.empty();
-                            one.f.flows.dashlet(one.main.dashlet.left.top);
-                            one.lib.alert('Flow removed');
-                        } else {
-                            one.lib.alert('Cannot remove flow: '+data);
-                        }
-                    });
-                });
-                return $modal;
-            },
-            footer : function() {
-                var footer = [];
-
-                var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
-                var $removeButton = one.lib.dashlet.button.button(removeButton);
-                footer.push($removeButton);
-
-                var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
-                var $closeButton = one.lib.dashlet.button.button(closeButton);
-                footer.push($closeButton);
-
-                return footer;
-            },
-            body : function(id) {
-                var $p = $(document.createElement('p'));
-                $p.append('Remove flow '+id+'?');
-                return $p;
+        $("#" + one.f.flows.id.dashlet.datagrid).find("tbody tr").each(function(index, tr) {
+          $tr = $(tr);
+          $span = $("td span", $tr);
+          var flowstatus = $span.data("flowstatus");
+          if($span.data("installinhw") != null) {
+            var installInHw = $span.data("installinhw").toString();
+            if(installInHw == "true" && flowstatus == "Success") {
+              $tr.addClass("success");
+            } else {
+              $tr.addClass("warning");
             }
-        },
-        initialize : function(edit,install) {
-            var h3;
-            if(edit) {
-                h3 = "Edit Flow Entry";
-                var footer = one.f.flows.modal.footerEdit();
-
+          }
+          // attach mouseover to show pointer cursor
+          $tr.mouseover(function() {
+            $(this).css("cursor", "pointer");
+          });
+          // attach click event
+          $tr.click(function() {
+            var $td = $($(this).find("td")[1]);
+            var id = $td.text();
+            var node = $td.find("span").data("nodeid");
+            one.f.flows.detail(id, node);
+          });
+          $(".flowEntry").click(function(e){
+            if (!$('.flowEntry[type=checkbox]:not(:checked)').length) {
+              $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
+            .prop("checked",
+              true);
             } else {
-                h3 = "Add Flow Entry";
-                var footer = one.f.flows.modal.footer();
+              $("#"+one.f.flows.id.dashlet.datagrid.selectAllFlows)
+            .prop("checked",
+              false);
             }
-
-            var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
-
-            // bind close button
-            $('#'+one.f.flows.id.modal.close, $modal).click(function() {
-                $modal.modal('hide');
+            e.stopPropagation();
+          });
+        });
+      });
+
+      // details callback
+      if(callback != undefined) callback();
+    });
+  },
+  detail : function(id, node) {
+    // clear flow details
+    var $detailDashlet = one.main.dashlet.right.bottom;
+    $detailDashlet.empty();
+    var $h4 = one.lib.dashlet.header("Flow Overview");
+    $detailDashlet.append($h4);
+
+    // details
+    var flows = one.f.flows.registry.flows;
+    one.f.flows.registry['selectedId'] = id;
+    one.f.flows.registry['selectedNode'] = node;
+    var flow;
+    $(flows).each(function(index, value) {
+      if (value.name == id && value.nodeId == node) {
+        flow = value;
+      }
+    });
+    if (one.f.flows.registry.privilege === 'WRITE') {
+      // remove button
+      var button = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.dashlet.remove, "btn-danger", "btn-mini");
+      var $button = one.lib.dashlet.button.button(button);
+      $button.click(function() {
+        var $modal = one.f.flows.modal.dialog.initialize(id, node);
+        $modal.modal();
+      });
+      // edit button
+      var editButton = one.lib.dashlet.button.single("Edit Flow", one.f.flows.id.dashlet.edit, "btn-primary", "btn-mini");
+      var $editButton = one.lib.dashlet.button.button(editButton);
+      $editButton.click(function() {
+        var install = flow['flow']['installInHw'];
+        var $modal = one.f.flows.modal.initialize(true,install);
+        $modal.modal().on('shown',function(){
+          var $port = $('#'+one.f.flows.id.modal.form.port);
+          $('#'+one.f.flows.id.modal.form.nodes).trigger("change");
+        });
+      });
+      // toggle button
+      var toggle;
+      if (flow['flow']['installInHw'] == 'true' && flow['flow']['status'] == 'Success') {
+        toggle = one.lib.dashlet.button.single("Uninstall Flow", one.f.flows.id.dashlet.toggle, "btn-warning", "btn-mini");
+      } else {
+        toggle = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.dashlet.toggle, "btn-success", "btn-mini");
+      }
+      var $toggle = one.lib.dashlet.button.button(toggle);
+      $toggle.click(function() {
+        one.f.flows.modal.ajax.toggleflow(id, node, function(data) {
+          if(data == "Success") {
+            one.main.dashlet.right.bottom.empty();
+            one.f.detail.dashlet(one.main.dashlet.right.bottom);
+            one.main.dashlet.left.top.empty();
+            one.f.flows.dashlet(one.main.dashlet.left.top, function() {
+              // checks are backwards due to stale registry
+              if(flow['flow']['installInHw'] == 'true') {
+                one.lib.alert('Uninstalled Flow');
+              } else {
+                one.lib.alert('Installed Flow');
+              }
+              one.f.flows.detail(id, node)
             });
+          } else {
+            one.lib.alert('Cannot toggle flow: '+data);
+          }
+        });
+      });
 
-            if (edit) {
-                // bind edit flow button
-                $('#'+one.f.flows.id.modal.edit, $modal).click(function() {
-                    one.f.flows.modal.save($modal, install, true);
-                });
+      $detailDashlet.append($button).append($editButton).append($toggle);
+    }
+    // append details
+    var body = one.f.detail.data.dashlet(flow);
+    var $body = one.f.detail.body.dashlet(body);
+    $detailDashlet.append($body);
+    var body = one.f.detail.data.description(flow);
+    var $body = one.f.detail.body.description(body);
+    $detailDashlet.append($body);
+    var body = one.f.detail.data.actions(flow);
+    var $body = one.f.detail.body.actions(body);
+    $detailDashlet.append($body);
+  },
+  modal : {
+    dialog : {
+      initialize : function(id, node) {
+        var h3 = "Remove Flow";
+        var $p = one.f.flows.modal.dialog.body(id);
+        var footer = one.f.flows.modal.dialog.footer();
+        var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $p, footer);
+        $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
+          $modal.modal('hide');
+        });
+        $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(function() {
+          one.f.flows.modal.ajax.removeflow(id, node, function(data) {
+            if (data == "Success") {
+              $modal.modal('hide');
+              one.main.dashlet.right.bottom.empty();
+              one.f.detail.dashlet(one.main.dashlet.right.bottom);
+              one.main.dashlet.left.top.empty();
+              one.f.flows.dashlet(one.main.dashlet.left.top);
+              one.lib.alert('Flow removed');
             } else {
-                // bind add flow button
-                $('#'+one.f.flows.id.modal.add, $modal).click(function() {
-                    one.f.flows.modal.save($modal, 'false');
-                });
-
-                // bind install flow button
-                $('#'+one.f.flows.id.modal.install, $modal).click(function() {
-                    one.f.flows.modal.save($modal, 'true');
-                });
+              one.lib.alert('Cannot remove flow: '+data);
             }
+          });
+        });
+        return $modal;
+      },
+      footer : function() {
+        var footer = [];
+
+        var removeButton = one.lib.dashlet.button.single("Remove Flow", one.f.flows.id.modal.dialog.remove, "btn-danger", "");
+        var $removeButton = one.lib.dashlet.button.button(removeButton);
+        footer.push($removeButton);
+
+        var closeButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.dialog.close, "", "");
+        var $closeButton = one.lib.dashlet.button.button(closeButton);
+        footer.push($closeButton);
+
+        return footer;
+      },
+      body : function(id) {
+        var $p = $(document.createElement('p'));
+        $p.append('Remove flow '+id+'?');
+        return $p;
+      }
+    },
+    initialize : function(edit,install) {
+      var h3;
+      if(edit) {
+        h3 = "Edit Flow Entry";
+        var footer = one.f.flows.modal.footerEdit();
+
+      } else {
+        h3 = "Add Flow Entry";
+        var footer = one.f.flows.modal.footer();
+      }
+
+      var $modal = one.lib.modal.spawn(one.f.flows.id.modal.modal, h3, "", footer);
+
+      // bind close button
+      $('#'+one.f.flows.id.modal.close, $modal).click(function() {
+        $modal.modal('hide');
+      });
+
+      if (edit) {
+        // bind edit flow button
+        $('#'+one.f.flows.id.modal.edit, $modal).click(function() {
+          one.f.flows.modal.save($modal, install, true);
+        });
+      } else {
+        // bind add flow button
+        $('#'+one.f.flows.id.modal.add, $modal).click(function() {
+          one.f.flows.modal.save($modal, 'false');
+        });
 
+        // bind install flow button
+        $('#'+one.f.flows.id.modal.install, $modal).click(function() {
+          one.f.flows.modal.save($modal, 'true');
+        });
+      }
 
-            var nodes = one.f.flows.registry.nodes;
-            var nodeports = one.f.flows.registry.nodeports;
-            var $body = one.f.flows.modal.body(nodes, nodeports, edit);
-            one.lib.modal.inject.body($modal, $body,edit);
-
-            return $modal;
-        },
-        save : function($modal, install, edit) {
-            var result = {};
-
-            result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
-            result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
-            result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
-            result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
-            result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
-            result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
-            result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
-            result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
-            result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
-            result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
-            result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
-            result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
-            result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
-            result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
-            result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
-            result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
-            result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
-            result['installInHw'] = install;
-
-            var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
-
-            $.each(result, function(key, value) {
-                if (value == "") delete result[key];
-            });
+      var nodes = one.f.flows.registry.nodes;
+      var nodeports = one.f.flows.registry.nodeports;
+      var $body = one.f.flows.modal.body(nodes, nodeports, edit);
+      one.lib.modal.inject.body($modal, $body,edit);
 
-            var action = [];
-            var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
-            $($table.find('tbody').find('tr')).each(function(index, value) {
-                if (!$(this).find('td').hasClass('empty')) {
-                    action.push($(value).data('action'));
-                }
+      return $modal;
+    },
+    save : function($modal, install, edit) {
+      var result = {};
+
+      result['name'] = $('#'+one.f.flows.id.modal.form.name, $modal).val();
+      result['ingressPort'] = $('#'+one.f.flows.id.modal.form.port, $modal).val();
+      result['priority'] = $('#'+one.f.flows.id.modal.form.priority, $modal).val();
+      result['hardTimeout'] = $('#'+one.f.flows.id.modal.form.hardTimeout, $modal).val();
+      result['idleTimeout'] = $('#'+one.f.flows.id.modal.form.idleTimeout, $modal).val();
+      result['cookie'] = $('#'+one.f.flows.id.modal.form.cookie, $modal).val();
+      result['etherType'] = $('#'+one.f.flows.id.modal.form.etherType, $modal).val();
+      result['vlanId'] = $('#'+one.f.flows.id.modal.form.vlanId, $modal).val();
+      result['vlanPriority'] = $('#'+one.f.flows.id.modal.form.vlanPriority, $modal).val();
+      result['dlSrc'] = $('#'+one.f.flows.id.modal.form.srcMac, $modal).val();
+      result['dlDst'] = $('#'+one.f.flows.id.modal.form.dstMac, $modal).val();
+      result['nwSrc'] = $('#'+one.f.flows.id.modal.form.srcIp, $modal).val();
+      result['nwDst'] = $('#'+one.f.flows.id.modal.form.dstIp, $modal).val();
+      result['tosBits'] = $('#'+one.f.flows.id.modal.form.tosBits, $modal).val();
+      result['tpSrc'] = $('#'+one.f.flows.id.modal.form.srcPort, $modal).val();
+      result['tpDst'] = $('#'+one.f.flows.id.modal.form.dstPort, $modal).val();
+      result['protocol'] = $('#'+one.f.flows.id.modal.form.protocol, $modal).val();
+      result['installInHw'] = install;
+
+      var nodeId = $('#'+one.f.flows.id.modal.form.nodes, $modal).val();
+
+      $.each(result, function(key, value) {
+        if (value == "") delete result[key];
+      });
+
+      var action = [];
+      var $table = $('#'+one.f.flows.id.modal.action.table, $modal);
+      $($table.find('tbody').find('tr')).each(function(index, value) {
+        if (!$(this).find('td').hasClass('empty')) {
+          action.push($(value).data('action'));
+        }
+      });
+      result['actions'] = action;
+
+      // frontend validation
+      if (result['name'] == undefined) {
+        alert('Need flow name');
+        return;
+      }
+      if (nodeId == '') {
+        alert('Select node');
+        return;
+      }
+      if (action.length == 0) {
+        alert('Please specify an action');
+        return;
+      }
+
+      // package for ajax call
+      var resource = {};
+      resource['body'] = JSON.stringify(result);
+      if(edit){
+        resource['action'] = 'edit';
+      } else {
+        resource['action'] = 'add';
+      }
+
+      resource['nodeId'] = nodeId;
+
+      if (edit) {
+        one.f.flows.modal.ajax.saveflow(resource, function(data) {
+          if (data == "Success") {
+            $modal.modal('hide').on('hidden', function () {
+              one.f.flows.detail(result['name'], nodeId);
             });
-            result['actions'] = action;
-
-            // frontend validation
-            if (result['name'] == undefined) {
-                alert('Need flow name');
-                return;
-            }
-            if (nodeId == '') {
-                alert('Select node');
-                return;
-            }
-            if (action.length == 0) {
-                alert('Please specify an action');
-                return;
-            }
-
-            // package for ajax call
-            var resource = {};
-            resource['body'] = JSON.stringify(result);
-            if(edit){
-                resource['action'] = 'edit';
+            one.lib.alert('Flow Entry edited');
+            one.main.dashlet.left.top.empty();
+            one.f.flows.dashlet(one.main.dashlet.left.top);
+          } else {
+            alert('Could not edit flow: '+data);
+          }
+        });
+      } else {
+        one.f.flows.modal.ajax.saveflow(resource, function(data) {
+          if (data == "Success") {
+            $modal.modal('hide');
+            one.lib.alert('Flow Entry added');
+            one.main.dashlet.left.top.empty();
+            one.f.flows.dashlet(one.main.dashlet.left.top);
+          } else {
+            alert('Could not add flow: '+data);
+          }
+        });
+      }
+    },
+    ajax : {
+      nodes : function(successCallback) {
+        $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
+          var nodes = one.f.flows.modal.data.nodes(data);
+          var nodeports = data;
+          one.f.flows.registry['nodes'] = nodes;
+          one.f.flows.registry['nodeports'] = nodeports;
+
+          successCallback(nodes, nodeports);
+        });
+      },
+      saveflow : function(resource, callback) {
+        $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
+          callback(data);
+        });
+      },
+      removeflow : function(id, node, callback) {
+        resource = {};
+        resource['action'] = 'remove';
+        $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
+          callback(data);
+        });
+      },
+      toggleflow : function(id, node, callback) {
+        resource = {};
+        resource['action'] = 'toggle';
+        $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
+          callback(data);
+        });
+      }
+    },
+    data : {
+      nodes : function(data) {
+        result = {};
+        $.each(data, function(key, value) {
+          result[key] = value['name'];
+        });
+        return result;
+      }
+    },
+    body : function(nodes, nodeports, edit) {
+      var $form = $(document.createElement('form'));
+      var $fieldset = $(document.createElement('fieldset'));
+      var existingFlow;
+      // flow description
+      var $legend = one.lib.form.legend("");
+      $legend.css('visibility', 'hidden');
+      $fieldset.append($legend);
+      // name
+      var $label = one.lib.form.label("Name");
+      var $input = one.lib.form.input("Flow Name");
+      $input.attr('id', one.f.flows.id.modal.form.name);
+      if(edit) {
+        $input.attr('disabled', 'disabled');
+        var flows = one.f.flows.registry.flows;
+        $(flows).each(function(index, value) {
+          if (value.name == one.f.flows.registry.selectedId && value.nodeId == one.f.flows.registry.selectedNode) {
+            existingFlow = value.flow;
+          }
+        });
+        $input.val(existingFlow.name);
+      }
+
+      $fieldset.append($label).append($input);
+      // node
+      var $label = one.lib.form.label("Node");
+      var $select = one.lib.form.select.create(nodes);
+      one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
+      $select.val($select.find("option:first").val());
+      $select.attr('id', one.f.flows.id.modal.form.nodes);
+      if(edit) {
+        $select.attr('disabled', 'disabled');
+        $select.val(existingFlow.node.type + "|"+ existingFlow.node.nodeIDString);
+      }
+
+      // bind onchange
+      $select.change(function() {
+        // retrieve port value
+        var node = $(this).find('option:selected').attr('value');
+        var $ports = $('#'+one.f.flows.id.modal.form.port);
+        if (node == '') {
+          one.lib.form.select.inject($ports, {});
+          return;
+        }
+        one.f.flows.registry['currentNode'] = node;
+        var ports = nodeports[node]['ports'];
+        one.lib.form.select.inject($ports, ports);
+        one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
+        $ports.val($ports.find("option:first").val());
+        if(edit) {
+          $ports.val( existingFlow.ingressPort );
+        }
+        $.getJSON(one.f.address.root+'/valid-flows/'+node, function(response) {
+          var $select = $('#'+one.f.flows.id.modal.form.action, $fieldset);
+          one.lib.form.select.inject($select, response);
+          one.lib.form.select.prepend($select, {'' : 'Please Select an Action'});
+          // when selecting an action
+          $select.change(function() {
+            var action = $(this).find('option:selected');
+            one.f.flows.modal.action.parse(action.attr('value'));
+            $select[0].selectedIndex = 0;
+          });
+        });
+      });
+
+      $fieldset.append($label).append($select);
+      // input port
+      var $label = one.lib.form.label("Input Port");
+      var $select = one.lib.form.select.create();
+
+      $select.attr('id', one.f.flows.id.modal.form.port);
+      $fieldset.append($label).append($select);
+      // priority
+      var $label = one.lib.form.label("Priority");
+      var $input = one.lib.form.input("Priority");
+      $input.attr('id', one.f.flows.id.modal.form.priority);
+      $input.val('500');
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.priority);
+      }
+      // hardTimeout
+      var $label = one.lib.form.label("Hard Timeout");
+      var $input = one.lib.form.input("Hard Timeout");
+      $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
+      if(edit) {
+        $input.val(existingFlow.hardTimeout);
+      }
+      $fieldset.append($label).append($input);
+
+      // idleTimeout
+      var $label = one.lib.form.label("Idle Timeout");
+      var $input = one.lib.form.input("Idle Timeout");
+      $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.idleTimeout);
+      }
+      // cookie
+      var $label = one.lib.form.label("Cookie");
+      var $input = one.lib.form.input("Cookie");
+      $input.attr('id', one.f.flows.id.modal.form.cookie);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.cookie);
+      }
+
+      // layer 2
+      var $legend = one.lib.form.legend("Layer 2");
+      $fieldset.append($legend);
+      // etherType
+      var $label = one.lib.form.label("Ethernet Type");
+      var $input = one.lib.form.input("Ethernet Type");
+      $input.attr('id', one.f.flows.id.modal.form.etherType);
+      $input.val('0x800');
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.etherType);
+      }
+      // vlanId
+      var $label = one.lib.form.label("VLAN Identification Number");
+      var $input = one.lib.form.input("VLAN Identification Number");
+      $input.attr('id', one.f.flows.id.modal.form.vlanId);
+      var $help = one.lib.form.help("Range: 0 - 4095");
+      $fieldset.append($label).append($input).append($help);
+      if(edit) {
+        $input.val(existingFlow.vlanId);
+      }
+
+      // vlanPriority
+      var $label = one.lib.form.label("VLAN Priority");
+      var $input = one.lib.form.input("VLAN Priority");
+      $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
+      var $help = one.lib.form.help("Range: 0 - 7");
+      $fieldset.append($label).append($input).append($help);
+      if(edit) {
+        $input.val(existingFlow.vlanPriority);
+      }
+
+      // srcMac
+      var $label = one.lib.form.label("Source MAC Address");
+      var $input = one.lib.form.input("3c:97:0e:75:c3:f7");
+      $input.attr('id', one.f.flows.id.modal.form.srcMac);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.srcMac);
+      }
+      // dstMac
+      var $label = one.lib.form.label("Destination MAC Address");
+      var $input = one.lib.form.input("7c:d1:c3:e8:e6:99");
+      $input.attr('id', one.f.flows.id.modal.form.dstMac);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.dstMac);
+      }
+      // layer 3
+      var $legend = one.lib.form.legend("Layer 3");
+      $fieldset.append($legend);
+
+      // srcIp
+      var $label = one.lib.form.label("Source IP Address");
+      var $input = one.lib.form.input("192.168.3.128");
+      $input.attr('id', one.f.flows.id.modal.form.srcIp);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.srcIp);
+      }
+      // dstIp
+      var $label = one.lib.form.label("Destination IP Address");
+      var $input = one.lib.form.input("2001:2334::0/32");
+      $input.attr('id', one.f.flows.id.modal.form.dstIp);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.dstIp);
+      }
+      // tosBits
+      var $label = one.lib.form.label("ToS Bits");
+      var $input = one.lib.form.input("ToS Bits");
+      $input.attr('id', one.f.flows.id.modal.form.tosBits);
+      var $help = one.lib.form.help("Range: 0 - 63");
+      $fieldset.append($label).append($input).append($help);
+      if(edit) {
+        $input.val(existingFlow.tosBits);
+      }
+
+      // layer 4
+      var $legend = one.lib.form.legend("Layer 4");
+      $fieldset.append($legend);
+      // srcPort
+      var $label = one.lib.form.label("Source Port");
+      var $input = one.lib.form.input("Source Port");
+      $input.attr('id', one.f.flows.id.modal.form.srcPort);
+      var $help = one.lib.form.help("Range: 0 - 65535");
+      $fieldset.append($label).append($input).append($help);
+      if(edit) {
+        $input.val(existingFlow.srcPort);
+      }
+      // dstPort
+      var $label = one.lib.form.label("Destination Port");
+      var $input = one.lib.form.input("Destination Port");
+      $input.attr('id', one.f.flows.id.modal.form.dstPort);
+      var $help = one.lib.form.help("Range: 0 - 65535");
+      $fieldset.append($label).append($input).append($help);
+      if(edit) {
+        $input.val(existingFlow.dstPort);
+      }
+      // protocol
+      var $label = one.lib.form.label("Protocol");
+      var $input = one.lib.form.input("Protocol");
+      $input.attr('id', one.f.flows.id.modal.form.protocol);
+      $fieldset.append($label).append($input);
+      if(edit) {
+        $input.val(existingFlow.protocol);
+      }
+      // actions
+      var $legend = one.lib.form.label("Actions");
+      $fieldset.append($legend);
+      // actions table
+      var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
+      var $table = one.lib.dashlet.table.table(tableAttributes);
+      $table.attr('id', one.f.flows.id.modal.action.table);
+      var tableHeaders = ["Action", "Data"];
+      var $thead = one.lib.dashlet.table.header(tableHeaders);
+      var $tbody = one.lib.dashlet.table.body("", tableHeaders);
+      $table.append($thead).append($tbody);
+      // actions
+      var actions = {
+        "" : "Please Select an Action",
+        "DROP" : "Drop",
+        "LOOPBACK" : "Loopback",
+        "FLOOD" : "Flood",
+        "FLOOD_ALL" : "Flood All",
+        "CONTROLLER" : "Controller",
+        "SW_PATH" : "Software Path",
+        "HW_PATH" : "Hardware Path",
+        "OUTPUT" : "Add Output Ports",
+        "ENQUEUE" : "Enqueue",
+        "SET_VLAN_ID" : "Set VLAN ID",
+        "SET_VLAN_PCP" : "Set VLAN Priority",
+        "SET_VLAN_CFI" : "Set VLAN CFI",
+        "POP_VLAN" : "Strip VLAN Header",
+        "PUSH_VLAN" : "Push VLAN",
+        "SET_DL_SRC" : "Modify Datalayer Source Address",
+        "SET_DL_DST" : "Modify Datalayer Destination Address",
+        "SET_DL_TYPE" : "Set Ethertype",
+        "SET_NW_SRC" : "Modify Network Source Address",
+        "SET_NW_DST" :"Modify Network Destination Address",
+        "SET_NW_TOS" : "Modify ToS Bits",
+        "SET_TP_SRC" : "Modify Transport Source Port",
+        "SET_TP_DST" : "Modify Transport Destination Port"
+      };
+      var $select = one.lib.form.select.create(actions);
+      $select.attr('id', one.f.flows.id.modal.form.action);
+      // when selecting an action
+      $select.change(function() {
+        var action = $(this).find('option:selected');
+        one.f.flows.modal.action.parse(action.attr('value'));
+        $select[0].selectedIndex = 0;
+      });
+
+      if(edit) {
+        $(existingFlow.actions).each(function(index, value){
+          setTimeout(function(){
+            var locEqualTo = value.indexOf("=");
+            if ( locEqualTo == -1 ) {
+              one.f.flows.modal.action.add.add(actions[value], value);
             } else {
-                resource['action'] = 'add';
+              var action = value.substr(0,locEqualTo);
+              if( action == "OUTPUT") {
+                var portIds = value.substr(locEqualTo+1).split(",");
+                var ports = [];
+                var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
+                for(var i =0; i < portIds.length ; i++) {
+                  var portName = allPorts[portIds[i]];
+                  ports.push(portName);
+                }
+                one.f.flows.modal.action.add.addPortsToTable(ports.join(", "), portIds.join(","));
+              } else {
+                var val = value.substr(locEqualTo+1);
+                one.f.flows.modal.action.add.addDataToTable(actions[action], val, action)
+              }
             }
+          }, 1000)
+        });
+      }
+      $fieldset.append($select).append($table);
 
-            resource['nodeId'] = nodeId;
-
-            if (edit) {
-                    one.f.flows.modal.ajax.saveflow(resource, function(data) {
-                    if (data == "Success") {
-                        $modal.modal('hide').on('hidden', function () {
-                            one.f.flows.detail(result['name'], nodeId);
-                        });
-                        one.lib.alert('Flow Entry edited');
-                        one.main.dashlet.left.top.empty();
-                        one.f.flows.dashlet(one.main.dashlet.left.top);
-                    } else {
-                        alert('Could not edit flow: '+data);
-                    }
-                });
-            } else {
-                    one.f.flows.modal.ajax.saveflow(resource, function(data) {
-                    if (data == "Success") {
-                        $modal.modal('hide');
-                        one.lib.alert('Flow Entry added');
-                        one.main.dashlet.left.top.empty();
-                        one.f.flows.dashlet(one.main.dashlet.left.top);
-                    } else {
-                        alert('Could not add flow: '+data);
-                    }
-                });
-            }
+      // return
+      $form.append($fieldset);
+      return $form;
+    },
+    action : {
+      parse : function(option) {
+        switch (option) {
+          case "OUTPUT" :
+            var h3 = "Add Output Port";
+            var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
+            $modal.modal();
+            break;
+          case "SET_VLAN_ID" :
+            var h3 = "Set VLAN ID";
+            var placeholder = "VLAN Identification Number";
+            var id = one.f.flows.id.modal.action.setVlanId;
+            var help = "Range: 0 - 4095";
+            var action = 'SET_VLAN_ID';
+            var name = "VLAN ID";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_VLAN_PCP" :
+            var h3 = "Set VLAN Priority";
+            var placeholder = "VLAN Priority";
+            var id = one.f.flows.id.modal.action.setVlanPriority;
+            var help = "Range: 0 - 7";
+            var action = 'SET_VLAN_PCP';
+            var name = "VLAN Priority";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_VLAN_CFI" :
+            var h3 = "Set VLAN CFI";
+            var placeholder = "VLAN CFI";
+            var id = one.f.flows.id.modal.action.setVlanPriority;
+            var help = "Range: 0 - 1";
+            var action = 'SET_VLAN_CFI';
+            var name = "VLAN CFI";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "POP_VLAN" :
+            var name = "Strip VLAN Header";
+            var action = 'POP_VLAN';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "PUSH_VLAN" :
+            var h3 = "Push VLAN";
+            var placeholder = "VLAN";
+            var id = one.f.flows.id.modal.action.setVlanPriority;
+            var help = "Range: 0 - 4095";
+            var action = 'PUSH_VLAN';
+            var name = "VLAN";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_DL_SRC" :
+            var h3 = "Set Source MAC Address";
+            var placeholder = "Source MAC Address";
+            var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
+            var help = "Example: 00:11:22:aa:bb:cc";
+            var action = 'SET_DL_SRC';
+            var name = "Source MAC";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_DL_DST" :
+            var h3 = "Set Destination MAC Address";
+            var placeholder = "Destination MAC Address";
+            var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
+            var help = "Example: 00:11:22:aa:bb:cc";
+            var action = 'SET_DL_DST';
+            var name = "Destination MAC";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_DL_TYPE" :
+            var h3 = "Set Ethertype";
+            var placeholder = "Ethertype";
+            var id = one.f.flows.id.modal.action.setVlanPriority;
+            var help = "Range: 0 - 65535";
+            var action = 'SET_DL_TYPE';
+            var name = "Ethertype";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_NW_SRC" :
+            var h3 = "Set IP Source Address";
+            var placeholder = "Source IP Address";
+            var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
+            var help = "Example: 127.0.0.1";
+            var action = 'SET_NW_SRC';
+            var name = "Source IP";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_NW_DST" :
+            var h3 = "Set IP Destination Address";
+            var placeholder = "Destination IP Address";
+            var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
+            var help = "Example: 127.0.0.1";
+            var action = 'SET_NW_DST';
+            var name = "Destination IP";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_NW_TOS" :
+            var h3 = "Set IPv4 ToS";
+            var placeholder = "IPv4 ToS";
+            var id = one.f.flows.id.modal.action.modifyTosBits;
+            var help = "Range: 0 - 63";
+            var action = 'SET_NW_TOS';
+            var name = "ToS Bits";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_TP_SRC" :
+            var h3 = "Set Transport Source Port";
+            var placeholder = "Transport Source Port";
+            var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
+            var help = "Range: 1 - 65535";
+            var action = 'SET_TP_SRC';
+            var name = "Source Port";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "SET_TP_DST" :
+            var h3 = "Set Transport Destination Port";
+            var placeholder = "Transport Destination Port";
+            var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
+            var help = "Range: 1 - 65535";
+            var action = 'SET_TP_DST';
+            var name = "Destination Port";
+            var body = function() {
+              return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
+            };
+            var add = function($modal) {
+              one.f.flows.modal.action.add.set(name, id, action, $modal);
+            };
+            var $modal = one.f.flows.modal.action.initialize(h3, body, add);
+            $modal.modal();
+            break;
+          case "DROP" :
+            var name = "Drop";
+            var action = 'DROP';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "LOOPBACK" :
+            var name = "Loopback";
+            var action = 'LOOPBACK';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "FLOOD" :
+            var name = "Flood";
+            var action = 'FLOOD';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "FLOOD_ALL" :
+            var name = "Flood All";
+            var action = 'FLOOD_ALL';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "SW_PATH" :
+            var name = "Software Path";
+            var action = 'SW_PATH';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "HW_PATH" :
+            var name = "Hardware Path";
+            var action = 'HW_PATH';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "CONTROLLER" :
+            var name = "Controller";
+            var action = 'CONTROLLER';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+          case "ENQUEUE" :
+            var name = "Enqueue";
+            var action = 'ENQUEUE';
+            one.f.flows.modal.action.add.add(name, action);
+            break;
+        }
+      },
+      initialize : function(h3, bodyCallback, addCallback) {
+        var footer = one.f.flows.modal.action.footer();
+        var $body = bodyCallback();
+        var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
+        // bind close button
+        $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
+          $modal.modal('hide');
+        });
+        // bind add flow button
+        $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
+          addCallback($modal);
+        });
+        return $modal;
+      },
+      add : {
+        addOutputPorts : function($modal) {
+          var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
+          var ports = '';
+          var pid = '';
+          $options.each(function(index, value) {
+            ports = ports+$(value).text()+", ";
+            pid = pid+$(value).attr('value')+",";
+          });
+          ports = ports.slice(0,-2);
+          pid = pid.slice(0,-1);
+          one.f.flows.modal.action.add.addPortsToTable(ports, pid);
+          $modal.modal('hide');
         },
-        ajax : {
-            nodes : function(successCallback) {
-                $.getJSON(one.f.address.root+one.f.address.flows.nodes, function(data) {
-                    var nodes = one.f.flows.modal.data.nodes(data);
-                    var nodeports = data;
-                    one.f.flows.registry['nodes'] = nodes;
-                    one.f.flows.registry['nodeports'] = nodeports;
-
-                    successCallback(nodes, nodeports);
-                });
-            },
-            saveflow : function(resource, callback) {
-                $.post(one.f.address.root+one.f.address.flows.flow, resource, function(data) {
-                    callback(data);
-                });
-            },
-            removeflow : function(id, node, callback) {
-                resource = {};
-                resource['action'] = 'remove';
-                $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
-                    callback(data);
-                });
-            },
-            toggleflow : function(id, node, callback) {
-                resource = {};
-                resource['action'] = 'toggle';
-                $.post(one.f.address.root+one.f.address.flows.flow+'/'+node+'/'+id, resource, function(data) {
-                    callback(data);
-                });
-            }
+        addPortsToTable : function(ports, pid){
+          var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
+          $tr.attr('id', 'OUTPUT');
+          $tr.data('action', 'OUTPUT='+pid);
+          $tr.click(function() {
+            one.f.flows.modal.action.add.modal.initialize(this);
+          });
+          one.f.flows.modal.action.table.append($tr);
         },
-        data : {
-            nodes : function(data) {
-                result = {};
-                $.each(data, function(key, value) {
-                    result[key] = value['name'];
-                });
-                return result;
-            }
+        add : function(name, action) {
+          var $tr = one.f.flows.modal.action.table.add(name);
+          $tr.attr('id', action);
+          $tr.data('action', action);
+          $tr.click(function() {
+            one.f.flows.modal.action.add.modal.initialize(this);
+          });
+          one.f.flows.modal.action.table.append($tr);
         },
-        body : function(nodes, nodeports, edit) {
-            var $form = $(document.createElement('form'));
-            var $fieldset = $(document.createElement('fieldset'));
-            var existingFlow;
-            // flow description
-            var $legend = one.lib.form.legend("");
-            $legend.css('visibility', 'hidden');
-            $fieldset.append($legend);
-            // name
-            var $label = one.lib.form.label("Name");
-            var $input = one.lib.form.input("Flow Name");
-            $input.attr('id', one.f.flows.id.modal.form.name);
-            if(edit) {
-                $input.attr('disabled', 'disabled');
-                var flows = one.f.flows.registry.flows;
-                $(flows).each(function(index, value) {
-                  if (value.name == one.f.flows.registry.selectedId && value.nodeId == one.f.flows.registry.selectedNode) {
-                    existingFlow = value.flow;
-                  }
-                });
-                $input.val(existingFlow.name);
-            }
-
-            $fieldset.append($label).append($input);
-            // node
-            var $label = one.lib.form.label("Node");
-            var $select = one.lib.form.select.create(nodes);
-            one.lib.form.select.prepend($select, { '' : 'Please Select a Node' });
-            $select.val($select.find("option:first").val());
-            $select.attr('id', one.f.flows.id.modal.form.nodes);
-            if(edit) {
-                $select.attr('disabled', 'disabled');
-                $select.val(existingFlow.node.type + "|"+ existingFlow.node.nodeIDString);
-            }
+        set : function(name, id, action, $modal) {
+          var $input = $('#'+id);
+          var value = $input.val();
+          one.f.flows.modal.action.add.addDataToTable(name,value,action)
+            $modal.modal('hide');
+        },
+        addDataToTable : function(name,value,action) {
+          var $tr = one.f.flows.modal.action.table.add(name, value);
+          $tr.attr('id', action);
+          $tr.data('action', action+'='+value);
+          $tr.click(function() {
+            one.f.flows.modal.action.add.modal.initialize(this);
+          });
+          one.f.flows.modal.action.table.append($tr);
+        },
+        remove : function(that) {
+          $(that).remove();
+          var $table = $('#'+one.f.flows.id.modal.action.table);
+          if ($table.find('tbody').find('tr').size() == 0) {
+            var $tr = $(document.createElement('tr'));
+            var $td = $(document.createElement('td'));
+            $td.attr('colspan', '3');
+            $tr.addClass('empty');
+            $td.text('No data available');
+            $tr.append($td);
+            $table.find('tbody').append($tr);
+          }
+        },
+        modal : {
+          initialize : function(that) {
+            var h3 = "Remove Action";
+            var footer = one.f.flows.modal.action.add.modal.footer();
+            var $body = one.f.flows.modal.action.add.modal.body();
+            var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
+
+            // bind cancel button
+            $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
+              $modal.modal('hide');
+            });
 
-            // bind onchange
-            $select.change(function() {
-                // retrieve port value
-                var node = $(this).find('option:selected').attr('value');
-                var $ports = $('#'+one.f.flows.id.modal.form.port);
-                if (node == '') {
-                    one.lib.form.select.inject($ports, {});
-                    return;
-                }
-                one.f.flows.registry['currentNode'] = node;
-                var ports = nodeports[node]['ports'];
-                one.lib.form.select.inject($ports, ports);
-                one.lib.form.select.prepend($ports, { '' : 'Please Select a Port' });
-                $ports.val($ports.find("option:first").val());
-                if(edit) {
-                    $ports.val( existingFlow.ingressPort );
-                }
+            // bind remove button
+            $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
+              one.f.flows.modal.action.add.remove(that);
+              $modal.modal('hide');
             });
 
-            $fieldset.append($label).append($select);
-            // input port
-            var $label = one.lib.form.label("Input Port");
-            var $select = one.lib.form.select.create();
-
-            $select.attr('id', one.f.flows.id.modal.form.port);
-            $fieldset.append($label).append($select);
-            // priority
-            var $label = one.lib.form.label("Priority");
-            var $input = one.lib.form.input("Priority");
-            $input.attr('id', one.f.flows.id.modal.form.priority);
-            $input.val('500');
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.priority);
-            }
-            // hardTimeout
-            var $label = one.lib.form.label("Hard Timeout");
-            var $input = one.lib.form.input("Hard Timeout");
-            $input.attr('id', one.f.flows.id.modal.form.hardTimeout);
-            if(edit) {
-                $input.val(existingFlow.hardTimeout);
-            }
-            $fieldset.append($label).append($input);
-
-            // idleTimeout
-            var $label = one.lib.form.label("Idle Timeout");
-            var $input = one.lib.form.input("Idle Timeout");
-            $input.attr('id', one.f.flows.id.modal.form.idleTimeout);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.idleTimeout);
-            }
-            // cookie
-            var $label = one.lib.form.label("Cookie");
-            var $input = one.lib.form.input("Cookie");
-            $input.attr('id', one.f.flows.id.modal.form.cookie);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.cookie);
-            }
+            $modal.modal();
+          },
+          body : function() {
+            var $p = $(document.createElement('p'));
+            $p.append("Remove this action?");
+            return $p;
+          },
+          footer : function() {
+            var footer = [];
 
-            // layer 2
-            var $legend = one.lib.form.legend("Layer 2");
-            $fieldset.append($legend);
-            // etherType
-            var $label = one.lib.form.label("Ethernet Type");
-            var $input = one.lib.form.input("Ethernet Type");
-            $input.attr('id', one.f.flows.id.modal.form.etherType);
-            $input.val('0x800');
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.etherType);
-            }
-            // vlanId
-            var $label = one.lib.form.label("VLAN Identification Number");
-            var $input = one.lib.form.input("VLAN Identification Number");
-            $input.attr('id', one.f.flows.id.modal.form.vlanId);
-            var $help = one.lib.form.help("Range: 0 - 4095");
-            $fieldset.append($label).append($input).append($help);
-            if(edit) {
-                $input.val(existingFlow.vlanId);
-            }
+            var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
+            var $removeButton = one.lib.dashlet.button.button(removeButton);
+            footer.push($removeButton);
 
-            // vlanPriority
-            var $label = one.lib.form.label("VLAN Priority");
-            var $input = one.lib.form.input("VLAN Priority");
-            $input.attr('id', one.f.flows.id.modal.form.vlanPriority);
-            var $help = one.lib.form.help("Range: 0 - 7");
-            $fieldset.append($label).append($input).append($help);
-            if(edit) {
-                $input.val(existingFlow.vlanPriority);
-            }
+            var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
+            var $cancelButton = one.lib.dashlet.button.button(cancelButton);
+            footer.push($cancelButton);
 
-            // srcMac
-            var $label = one.lib.form.label("Source MAC Address");
-            var $input = one.lib.form.input("3c:97:0e:75:c3:f7");
-            $input.attr('id', one.f.flows.id.modal.form.srcMac);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.srcMac);
-            }
-            // dstMac
-            var $label = one.lib.form.label("Destination MAC Address");
-            var $input = one.lib.form.input("7c:d1:c3:e8:e6:99");
-            $input.attr('id', one.f.flows.id.modal.form.dstMac);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.dstMac);
-            }
-            // layer 3
-            var $legend = one.lib.form.legend("Layer 3");
-            $fieldset.append($legend);
-
-            // srcIp
-            var $label = one.lib.form.label("Source IP Address");
-            var $input = one.lib.form.input("192.168.3.128");
-            $input.attr('id', one.f.flows.id.modal.form.srcIp);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.srcIp);
-            }
-            // dstIp
-            var $label = one.lib.form.label("Destination IP Address");
-            var $input = one.lib.form.input("2001:2334::0/32");
-            $input.attr('id', one.f.flows.id.modal.form.dstIp);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.dstIp);
-            }
-            // tosBits
-            var $label = one.lib.form.label("ToS Bits");
-            var $input = one.lib.form.input("ToS Bits");
-            $input.attr('id', one.f.flows.id.modal.form.tosBits);
-            var $help = one.lib.form.help("Range: 0 - 63");
-            $fieldset.append($label).append($input).append($help);
-            if(edit) {
-                $input.val(existingFlow.tosBits);
-            }
+            return footer;
+          }
+        }
+      },
+      table : {
+        add : function(action, data) {
+          var $tr = $(document.createElement('tr'));
+          var $td = $(document.createElement('td'));
+          $td.append(action);
+          $tr.append($td);
+          var $td = $(document.createElement('td'));
+          if (data != undefined) $td.append(data);
+          $tr.append($td);
+          return $tr;
+        },
+        append : function($tr) {
+          var $table = $('#'+one.f.flows.id.modal.action.table);
+          var $empty = $table.find('.empty').parent();
+          if ($empty.size() > 0) $empty.remove();
+          $table.append($tr);
+        }
+      },
+      body : {
+        common : function() {
+          var $form = $(document.createElement('form'));
+          var $fieldset = $(document.createElement('fieldset'));
+          return [$form, $fieldset];
+        },
+        addOutputPorts : function() {
+          var common = one.f.flows.modal.action.body.common();
+          var $form = common[0];
+          var $fieldset = common[1];
+          // output port
+          $label = one.lib.form.label("Select Output Ports");
+          if (one.f.flows.registry.currentNode == undefined){
+            return; //Selecting Output ports without selecting node throws an exception
+          }
+          var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
+          $select = one.lib.form.select.create(ports, true);
+          $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
+          $fieldset.append($label).append($select);
+          $form.append($fieldset);
+          return $form;
+        },
+        set : function(label, placeholder, id, help) {
+          var common = one.f.flows.modal.action.body.common();
+          var $form = common[0];
+          var $fieldset = common[1];
+          // input
+          $label = one.lib.form.label(label);
+          $input = one.lib.form.input(placeholder);
+          $input.attr('id', id);
+          $help = one.lib.form.help(help);
+          // append
+          $fieldset.append($label).append($input).append($help);
+          $form.append($fieldset);
+          return $form;
+        }
+      },
+      footer : function() {
+        var footer = [];
+        var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
+        var $addButton = one.lib.dashlet.button.button(addButton);
+        footer.push($addButton);
+
+        var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
+        var $closeButton = one.lib.dashlet.button.button(closeButton);
+        footer.push($closeButton);
+
+        return footer;
+      }
+    },
+    footer : function() {
+      var footer = [];
 
-            // layer 4
-            var $legend = one.lib.form.legend("Layer 4");
-            $fieldset.append($legend);
-            // srcPort
-            var $label = one.lib.form.label("Source Port");
-            var $input = one.lib.form.input("Source Port");
-            $input.attr('id', one.f.flows.id.modal.form.srcPort);
-            var $help = one.lib.form.help("Range: 0 - 65535");
-            $fieldset.append($label).append($input).append($help);
-            if(edit) {
-                $input.val(existingFlow.srcPort);
-            }
-            // dstPort
-            var $label = one.lib.form.label("Destination Port");
-            var $input = one.lib.form.input("Destination Port");
-            $input.attr('id', one.f.flows.id.modal.form.dstPort);
-            var $help = one.lib.form.help("Range: 0 - 65535");
-            $fieldset.append($label).append($input).append($help);
-            if(edit) {
-                $input.val(existingFlow.dstPort);
-            }
-            // protocol
-            var $label = one.lib.form.label("Protocol");
-            var $input = one.lib.form.input("Protocol");
-            $input.attr('id', one.f.flows.id.modal.form.protocol);
-            $fieldset.append($label).append($input);
-            if(edit) {
-                $input.val(existingFlow.protocol);
-            }
-            // actions
-            var $legend = one.lib.form.label("Actions");
-            $fieldset.append($legend);
-            // actions table
-            var tableAttributes = ["table-striped", "table-bordered", "table-condensed", "table-hover", "table-cursor"];
-            var $table = one.lib.dashlet.table.table(tableAttributes);
-            $table.attr('id', one.f.flows.id.modal.action.table);
-            var tableHeaders = ["Action", "Data"];
-            var $thead = one.lib.dashlet.table.header(tableHeaders);
-            var $tbody = one.lib.dashlet.table.body("", tableHeaders);
-            $table.append($thead).append($tbody);
-            // actions
-            var actions = {
-                "" : "Please Select an Action",
-                "DROP" : "Drop",
-                "LOOPBACK" : "Loopback",
-                "FLOOD" : "Flood",
-                "SW_PATH" : "Software Path",
-                "HW_PATH" : "Hardware Path",
-                "CONTROLLER" : "Controller",
-                "OUTPUT" : "Add Output Ports",
-                "SET_VLAN_ID" : "Set VLAN ID",
-                "SET_VLAN_PCP" : "Set VLAN Priority",
-                "POP_VLAN" : "Strip VLAN Header",
-                "SET_DL_SRC" : "Modify Datalayer Source Address",
-                "SET_DL_DST" : "Modify Datalayer Destination Address",
-                "SET_NW_SRC" : "Modify Network Source Address",
-                "SET_NW_DST" :"Modify Network Destination Address",
-                "SET_NW_TOS" : "Modify ToS Bits",
-                "SET_TP_SRC" : "Modify Transport Source Port",
-                "SET_TP_DST" : "Modify Transport Destination Port"
-            };
-            var $select = one.lib.form.select.create(actions);
-            // when selecting an action
-            $select.change(function() {
-                var action = $(this).find('option:selected');
-                one.f.flows.modal.action.parse(action.attr('value'));
-                $select[0].selectedIndex = 0;
-            });
+      var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
+      var $installButton = one.lib.dashlet.button.button(installButton);
+      footer.push($installButton);
 
-            if(edit) {
-                $(existingFlow.actions).each(function(index, value){
-                    setTimeout(function(){
-                        var locEqualTo = value.indexOf("=");
-                        if ( locEqualTo == -1 ) {
-                            one.f.flows.modal.action.add.add(actions[value], value);
-                        } else {
-                            var action = value.substr(0,locEqualTo);
-                            if( action == "OUTPUT") {
-                                var portIds = value.substr(locEqualTo+1).split(",");
-                                var ports = [];
-                                var allPorts = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
-                                for(var i =0; i < portIds.length ; i++) {
-                                    var portName = allPorts[portIds[i]];
-                                    ports.push(portName);
-                                }
-                                one.f.flows.modal.action.add.addPortsToTable(ports.join(", "), portIds.join(","));
-                            } else {
-                                var val = value.substr(locEqualTo+1);
-                                one.f.flows.modal.action.add.addDataToTable(actions[action], val, action)
-                            }
-                        }
-                    }, 1000)
-                });
-            }
-            $fieldset.append($select).append($table);
+      var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
+      var $addButton = one.lib.dashlet.button.button(addButton);
+      footer.push($addButton);
 
-            // return
-            $form.append($fieldset);
-            return $form;
-        },
-        action : {
-            parse : function(option) {
-                switch (option) {
-                    case "OUTPUT" :
-                        var h3 = "Add Output Port";
-                        var $modal = one.f.flows.modal.action.initialize(h3, one.f.flows.modal.action.body.addOutputPorts, one.f.flows.modal.action.add.addOutputPorts);
-                        $modal.modal();
-                        break;
-                    case "SET_VLAN_ID" :
-                        var h3 = "Set VLAN ID";
-                        var placeholder = "VLAN Identification Number";
-                        var id = one.f.flows.id.modal.action.setVlanId;
-                        var help = "Range: 0 - 4095";
-                        var action = 'SET_VLAN_ID';
-                        var name = "VLAN ID";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_VLAN_PCP" :
-                        var h3 = "Set VLAN Priority";
-                        var placeholder = "VLAN Priority";
-                        var id = one.f.flows.id.modal.action.setVlanPriority;
-                        var help = "Range: 0 - 7";
-                        var action = 'SET_VLAN_PCP';
-                        var name = "VLAN Priority";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "POP_VLAN" :
-                        var name = "Strip VLAN Header";
-                        var action = 'POP_VLAN';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "SET_DL_SRC" :
-                        var h3 = "Set Source MAC Address";
-                        var placeholder = "Source MAC Address";
-                        var id = one.f.flows.id.modal.action.modifyDatalayerSourceAddress;
-                        var help = "Example: 00:11:22:aa:bb:cc";
-                        var action = 'SET_DL_SRC';
-                        var name = "Source MAC";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_DL_DST" :
-                        var h3 = "Set Destination MAC Address";
-                        var placeholder = "Destination MAC Address";
-                        var id = one.f.flows.id.modal.action.modifyDatalayerDestinationAddress;
-                        var help = "Example: 00:11:22:aa:bb:cc";
-                        var action = 'SET_DL_DST';
-                        var name = "Destination MAC";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_NW_SRC" :
-                        var h3 = "Set IP Source Address";
-                        var placeholder = "Source IP Address";
-                        var id = one.f.flows.id.modal.action.modifyNetworkSourceAddress;
-                        var help = "Example: 127.0.0.1";
-                        var action = 'SET_NW_SRC';
-                        var name = "Source IP";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_NW_DST" :
-                        var h3 = "Set IP Destination Address";
-                        var placeholder = "Destination IP Address";
-                        var id = one.f.flows.id.modal.action.modifyNetworkDestinationAddress;
-                        var help = "Example: 127.0.0.1";
-                        var action = 'SET_NW_DST';
-                        var name = "Destination IP";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_NW_TOS" :
-                        var h3 = "Set IPv4 ToS";
-                        var placeholder = "IPv4 ToS";
-                        var id = one.f.flows.id.modal.action.modifyTosBits;
-                        var help = "Range: 0 - 63";
-                        var action = 'SET_NW_TOS';
-                        var name = "ToS Bits";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_TP_SRC" :
-                        var h3 = "Set Transport Source Port";
-                        var placeholder = "Transport Source Port";
-                        var id = one.f.flows.id.modal.action.modifyTransportSourcePort;
-                        var help = "Range: 1 - 65535";
-                        var action = 'SET_TP_SRC';
-                        var name = "Source Port";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "SET_TP_DST" :
-                        var h3 = "Set Transport Destination Port";
-                        var placeholder = "Transport Destination Port";
-                        var id = one.f.flows.id.modal.action.modifyTransportDestinationPort;
-                        var help = "Range: 1 - 65535";
-                        var action = 'SET_TP_DST';
-                        var name = "Destination Port";
-                        var body = function() {
-                            return one.f.flows.modal.action.body.set(h3, placeholder, id, help);
-                        };
-                        var add = function($modal) {
-                            one.f.flows.modal.action.add.set(name, id, action, $modal);
-                        };
-                        var $modal = one.f.flows.modal.action.initialize(h3, body, add);
-                        $modal.modal();
-                        break;
-                    case "DROP" :
-                        var name = "Drop";
-                        var action = 'DROP';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "LOOPBACK" :
-                        var name = "Loopback";
-                        var action = 'LOOPBACK';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "FLOOD" :
-                        var name = "Flood";
-                        var action = 'FLOOD';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "SW_PATH" :
-                        var name = "Software Path";
-                        var action = 'SW_PATH';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "HW_PATH" :
-                        var name = "Hardware Path";
-                        var action = 'HW_PATH';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                    case "CONTROLLER" :
-                        var name = "Controller";
-                        var action = 'CONTROLLER';
-                        one.f.flows.modal.action.add.add(name, action);
-                        break;
-                }
-            },
-            initialize : function(h3, bodyCallback, addCallback) {
-                var footer = one.f.flows.modal.action.footer();
-                var $body = bodyCallback();
-                var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal, h3, $body, footer);
-                // bind close button
-                $('#'+one.f.flows.id.modal.action.close, $modal).click(function() {
-                    $modal.modal('hide');
-                });
-                // bind add flow button
-                $('#'+one.f.flows.id.modal.action.add, $modal).click(function() {
-                    addCallback($modal);
-                });
-                return $modal;
-            },
-            add : {
-                addOutputPorts : function($modal) {
-                    var $options = $('#'+one.f.flows.id.modal.action.addOutputPorts).find('option:selected');
-                    var ports = '';
-                    var pid = '';
-                    $options.each(function(index, value) {
-                        ports = ports+$(value).text()+", ";
-                        pid = pid+$(value).attr('value')+",";
-                    });
-                    ports = ports.slice(0,-2);
-                    pid = pid.slice(0,-1);
-                    one.f.flows.modal.action.add.addPortsToTable(ports, pid);
-                    $modal.modal('hide');
-                },
-                addPortsToTable : function(ports, pid){
-                    var $tr = one.f.flows.modal.action.table.add("Add Output Ports", ports);
-                    $tr.attr('id', 'OUTPUT');
-                    $tr.data('action', 'OUTPUT='+pid);
-                    $tr.click(function() {
-                        one.f.flows.modal.action.add.modal.initialize(this);
-                    });
-                    one.f.flows.modal.action.table.append($tr);
-                },
-                add : function(name, action) {
-                    var $tr = one.f.flows.modal.action.table.add(name);
-                    $tr.attr('id', action);
-                    $tr.data('action', action);
-                    $tr.click(function() {
-                        one.f.flows.modal.action.add.modal.initialize(this);
-                    });
-                    one.f.flows.modal.action.table.append($tr);
-                },
-                set : function(name, id, action, $modal) {
-                    var $input = $('#'+id);
-                    var value = $input.val();
-                    one.f.flows.modal.action.add.addDataToTable(name,value,action)
-                    $modal.modal('hide');
-                },
-                addDataToTable : function(name,value,action) {
-                    var $tr = one.f.flows.modal.action.table.add(name, value);
-                    $tr.attr('id', action);
-                    $tr.data('action', action+'='+value);
-                    $tr.click(function() {
-                        one.f.flows.modal.action.add.modal.initialize(this);
-                    });
-                    one.f.flows.modal.action.table.append($tr);
-                },
-                remove : function(that) {
-                    $(that).remove();
-                    var $table = $('#'+one.f.flows.id.modal.action.table);
-                    if ($table.find('tbody').find('tr').size() == 0) {
-                        var $tr = $(document.createElement('tr'));
-                        var $td = $(document.createElement('td'));
-                        $td.attr('colspan', '3');
-                        $tr.addClass('empty');
-                        $td.text('No data available');
-                        $tr.append($td);
-                        $table.find('tbody').append($tr);
-                    }
-                },
-                modal : {
-                    initialize : function(that) {
-                        var h3 = "Remove Action";
-                        var footer = one.f.flows.modal.action.add.modal.footer();
-                        var $body = one.f.flows.modal.action.add.modal.body();
-                        var $modal = one.lib.modal.spawn(one.f.flows.id.modal.action.modal.modal, h3, $body, footer);
-
-                        // bind cancel button
-                        $('#'+one.f.flows.id.modal.action.modal.cancel, $modal).click(function() {
-                            $modal.modal('hide');
-                        });
-
-                        // bind remove button
-                        $('#'+one.f.flows.id.modal.action.modal.remove, $modal).click(function() {
-                            one.f.flows.modal.action.add.remove(that);
-                            $modal.modal('hide');
-                        });
-
-                        $modal.modal();
-                    },
-                    body : function() {
-                        var $p = $(document.createElement('p'));
-                        $p.append("Remove this action?");
-                        return $p;
-                    },
-                    footer : function() {
-                        var footer = [];
-
-                        var removeButton = one.lib.dashlet.button.single("Remove Action", one.f.flows.id.modal.action.modal.remove, "btn-danger", "");
-                        var $removeButton = one.lib.dashlet.button.button(removeButton);
-                        footer.push($removeButton);
-
-                        var cancelButton = one.lib.dashlet.button.single("Cancel", one.f.flows.id.modal.action.modal.cancel, "", "");
-                        var $cancelButton = one.lib.dashlet.button.button(cancelButton);
-                        footer.push($cancelButton);
-
-                        return footer;
-                    }
-                }
-            },
-            table : {
-                add : function(action, data) {
-                    var $tr = $(document.createElement('tr'));
-                    var $td = $(document.createElement('td'));
-                    $td.append(action);
-                    $tr.append($td);
-                    var $td = $(document.createElement('td'));
-                    if (data != undefined) $td.append(data);
-                    $tr.append($td);
-                    return $tr;
-                },
-                append : function($tr) {
-                    var $table = $('#'+one.f.flows.id.modal.action.table);
-                    var $empty = $table.find('.empty').parent();
-                    if ($empty.size() > 0) $empty.remove();
-                    $table.append($tr);
-                }
-            },
-            body : {
-                common : function() {
-                    var $form = $(document.createElement('form'));
-                    var $fieldset = $(document.createElement('fieldset'));
-                    return [$form, $fieldset];
-                },
-                addOutputPorts : function() {
-                    var common = one.f.flows.modal.action.body.common();
-                    var $form = common[0];
-                    var $fieldset = common[1];
-                    // output port
-                    $label = one.lib.form.label("Select Output Ports");
-                    if (one.f.flows.registry.currentNode == undefined){
-                        return; //Selecting Output ports without selecting node throws an exception
-                    }
-                    var ports = one.f.flows.registry.nodeports[one.f.flows.registry.currentNode]['ports'];
-                    $select = one.lib.form.select.create(ports, true);
-                    $select.attr('id', one.f.flows.id.modal.action.addOutputPorts);
-                    $fieldset.append($label).append($select);
-                    $form.append($fieldset);
-                    return $form;
-                },
-                set : function(label, placeholder, id, help) {
-                    var common = one.f.flows.modal.action.body.common();
-                    var $form = common[0];
-                    var $fieldset = common[1];
-                    // input
-                    $label = one.lib.form.label(label);
-                    $input = one.lib.form.input(placeholder);
-                    $input.attr('id', id);
-                    $help = one.lib.form.help(help);
-                    // append
-                    $fieldset.append($label).append($input).append($help);
-                    $form.append($fieldset);
-                    return $form;
-                }
-            },
-            footer : function() {
-                var footer = [];
-                var addButton = one.lib.dashlet.button.single("Add Action", one.f.flows.id.modal.action.add, "btn-primary", "");
-                var $addButton = one.lib.dashlet.button.button(addButton);
-                footer.push($addButton);
-
-                var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.action.close, "", "");
-                var $closeButton = one.lib.dashlet.button.button(closeButton);
-                footer.push($closeButton);
-
-                return footer;
-            }
-        },
-        footer : function() {
-            var footer = [];
+      var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
+      var $closeButton = one.lib.dashlet.button.button(closeButton);
+      footer.push($closeButton);
 
-            var installButton = one.lib.dashlet.button.single("Install Flow", one.f.flows.id.modal.install, "btn-success", "");
-            var $installButton = one.lib.dashlet.button.button(installButton);
-            footer.push($installButton);
+      return footer;
+    },
+    footerEdit : function() {
+      var footer = [];
 
-            var addButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.add, "btn-primary", "");
-            var $addButton = one.lib.dashlet.button.button(addButton);
-            footer.push($addButton);
+      var editButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.edit, "btn-success", "");
+      var $editButton = one.lib.dashlet.button.button(editButton);
+      footer.push($editButton);
 
-            var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
-            var $closeButton = one.lib.dashlet.button.button(closeButton);
-            footer.push($closeButton);
+      var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
+      var $closeButton = one.lib.dashlet.button.button(closeButton);
+      footer.push($closeButton);
 
-            return footer;
-        },
-        footerEdit : function() {
-            var footer = [];
+      return footer;
+    },
+    removeMultiple: {
+      dialog: function(flows) {
+        var h3 = 'Remove Flow Entry';
+        var flowList = [];
+        for (var i = 0; i < flows.length; i++) {
+          flowList.push(flows[i]["name"]);
+        }
+        var footer = one.f.flows.modal.removeMultiple.footer();
+        var $body = one.f.flows.modal.removeMultiple.body(flowList);
+        var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $body, footer);
 
-            var editButton = one.lib.dashlet.button.single("Save Flow", one.f.flows.id.modal.edit, "btn-success", "");
-            var $editButton = one.lib.dashlet.button.button(editButton);
-            footer.push($editButton);
+        // bind close button
+        $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
+          $modal.modal('hide');
+        });
 
-            var closeButton = one.lib.dashlet.button.single("Close", one.f.flows.id.modal.close, "", "");
-            var $closeButton = one.lib.dashlet.button.button(closeButton);
-            footer.push($closeButton);
+        // bind remove rule button
+        $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(this, function(e) {
+          var resource = {};
+          resource['body'] = JSON.stringify(flows);
 
-            return footer;
-        },
-        removeMultiple: {
-            dialog: function(flows) {
-                var h3 = 'Remove Flow Entry';
-                var flowList = [];
-                for (var i = 0; i < flows.length; i++) {
-                    flowList.push(flows[i]["name"]);
-                }
-                var footer = one.f.flows.modal.removeMultiple.footer();
-                var $body = one.f.flows.modal.removeMultiple.body(flowList);
-                var $modal = one.lib.modal.spawn(one.f.flows.id.modal.dialog.modal, h3, $body, footer);
-
-                // bind close button
-                $('#'+one.f.flows.id.modal.dialog.close, $modal).click(function() {
-                    $modal.modal('hide');
-                });
-
-                // bind remove rule button
-                $('#'+one.f.flows.id.modal.dialog.remove, $modal).click(this, function(e) {
-                    var resource = {};
-                    resource['body'] = JSON.stringify(flows);
-
-                    $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) {
-                        $modal.modal('hide');
-                        if(response == "Success") {
-                            one.lib.alert("Flow Entry(s) successfully removed");
-                        } else {
-                            one.lib.alert(response);
-                        }
-                        one.main.dashlet.right.bottom.empty();
-                        one.f.detail.dashlet(one.main.dashlet.right.bottom);
-                        one.main.dashlet.left.top.empty();
-                        one.f.flows.dashlet(one.main.dashlet.left.top);
-                    });
-                });
-                $modal.modal();
-            },
-            footer : function() {
-                var footer = [];
-                var remove = one.lib.dashlet.button.single('Remove Flow Entry',one.f.flows.id.modal.dialog.remove, 'btn-danger', '');
-                var $remove = one.lib.dashlet.button.button(remove);
-                footer.push($remove);
-
-                var cancel = one.lib.dashlet.button.single('Cancel', one.f.flows.id.modal.dialog.close, '', '');
-                var $cancel = one.lib.dashlet.button.button(cancel);
-                footer.push($cancel);
-
-                return footer;
-            },
-            body : function (flows) {
-                var $p = $(document.createElement('p'));
-                var p = 'Remove the following Flow Entry(s)?';
-                //creata a BS label for each rule and append to list
-                $(flows).each(function(){
-                    var $span = $(document.createElement('span'));
-                    $span.append(this);
-                    p += '<br/>' + $span[0].outerHTML;
-                });
-                $p.append(p);
-                return $p;
+          $.post(one.f.address.root+one.f.address.flows.deleteFlows, resource, function(response) {
+            $modal.modal('hide');
+            if(response == "Success") {
+              one.lib.alert("Flow Entry(s) successfully removed");
+            } else {
+              one.lib.alert(response);
             }
-        }
-    },
-    ajax : {
-        dashlet : function(callback) {
-            $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
-                one.f.flows.registry['flows'] = data.flows;
-                one.f.flows.registry['privilege'] = data.privilege;
-                one.f.flows.modal.ajax.nodes(function(){/*Empty function. Do nothing. */})
+            one.main.dashlet.right.bottom.empty();
+            one.f.detail.dashlet(one.main.dashlet.right.bottom);
+            one.main.dashlet.left.top.empty();
+            one.f.flows.dashlet(one.main.dashlet.left.top);
+          });
+        });
+        $modal.modal();
+      },
+      footer : function() {
+        var footer = [];
+        var remove = one.lib.dashlet.button.single('Remove Flow Entry',one.f.flows.id.modal.dialog.remove, 'btn-danger', '');
+        var $remove = one.lib.dashlet.button.button(remove);
+        footer.push($remove);
+
+        var cancel = one.lib.dashlet.button.single('Cancel', one.f.flows.id.modal.dialog.close, '', '');
+        var $cancel = one.lib.dashlet.button.button(cancel);
+        footer.push($cancel);
+
+        return footer;
+      },
+      body : function (flows) {
+        var $p = $(document.createElement('p'));
+        var p = 'Remove the following Flow Entry(s)?';
+        //creata a BS label for each rule and append to list
+        $(flows).each(function(){
+          var $span = $(document.createElement('span'));
+          $span.append(this);
+          p += '<br/>' + $span[0].outerHTML;
+        });
+        $p.append(p);
+        return $p;
+      }
+    }
+  },
+  ajax : {
+    dashlet : function(callback) {
+      $.getJSON(one.f.address.root+one.f.address.flows.main, function(data) {
+        one.f.flows.registry['flows'] = data.flows;
+        one.f.flows.registry['privilege'] = data.privilege;
+        one.f.flows.modal.ajax.nodes(function(){/*Empty function. Do nothing. */})
+
+        callback(data);
+      });
+    }
+  },
+  data : {
+    flowsDataGrid: function(data) {
+      var source = new StaticDataSource({
+        columns: [
+      {
+        property: 'selector',
+      label: "<input type='checkbox' id='"+one.f.flows.id.dashlet.datagrid.selectAllFlows+"'/>",
+      sortable: false
+      },
+      {
+        property: 'name',
+      label: 'Flow Name',
+      sortable: true
+      },
+      {
+        property: 'node',
+      label: 'Node',
+      sortable: true
+      }
+      ],
+      data: data.flows,
+      formatter: function(items) {
+        $.each(items, function(index, item) {
+          var $checkbox = document.createElement("input");
+          $checkbox.setAttribute("type", "checkbox");
+          $checkbox.setAttribute("name", item.name);
+          $checkbox.setAttribute("node", item.nodeId);
+          $checkbox.setAttribute('class','flowEntry')
+          item.selector = $checkbox.outerHTML;
+        item["name"] = '<span data-installInHw=' + item["flow"]["installInHw"] + 
+          ' data-flowstatus=' + item["flow"]["status"] + 
+          ' data-nodeId=' + item["nodeId"] + '>' + item["name"] + '</span>';
+        });
 
-                callback(data);
-            });
-        }
-    },
-    data : {
-        flowsDataGrid: function(data) {
-            var source = new StaticDataSource({
-                    columns: [
-                        {
-                            property: 'selector',
-                            label: "<input type='checkbox' id='"+one.f.flows.id.dashlet.datagrid.selectAllFlows+"'/>",
-                            sortable: false
-                        },
-                        {
-                            property: 'name',
-                            label: 'Flow Name',
-                            sortable: true
-                        },
-                        {
-                            property: 'node',
-                            label: 'Node',
-                            sortable: true
-                        }
-                    ],
-                    data: data.flows,
-                    formatter: function(items) {
-                        $.each(items, function(index, item) {
-                            var $checkbox = document.createElement("input");
-                            $checkbox.setAttribute("type", "checkbox");
-                            $checkbox.setAttribute("name", item.name);
-                            $checkbox.setAttribute("node", item.nodeId);
-                            $checkbox.setAttribute('class','flowEntry')
-                            item.selector = $checkbox.outerHTML;
-                                  item["name"] = '<span data-installInHw=' + item["flow"]["installInHw"] + 
-                                ' data-flowstatus=' + item["flow"]["status"] + 
-                                ' data-nodeId=' + item["nodeId"] + '>' + item["name"] + '</span>';
-                        });
-
-                    },
-                    delay: 0
-                });
-            return source;
-        },
-        dashlet : function(data) {
-            var body = [];
-            $(data).each(function(index, value) {
-                var tr = {};
-                var entry = [];
-
-                
-                entry.push(value['name']);
-                entry.push(value['node']);
-                if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
-                    tr['type'] = ['success'];
-                else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
-                    tr['type'] = ['warning'];
-                else 
-                    tr['type'] = ['warning'];
-                tr['entry'] = entry;
-                tr['id'] = value['nodeId'];
-
-                body.push(tr);
-            });
-            return body;
-        }
+      },
+      delay: 0
+      });
+      return source;
     },
-    body : {
-        dashlet : function(body, callback) {
-            var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
-            var $table = one.lib.dashlet.table.table(attributes);
-
-            var headers = ['Flow Name', 'Node'];
-                
-            var $thead = one.lib.dashlet.table.header(headers);
-            $table.append($thead);
-
-            var $tbody = one.lib.dashlet.table.body(body);
-            $table.append($tbody);
-            return $table;
-        }
+    dashlet : function(data) {
+      var body = [];
+      $(data).each(function(index, value) {
+        var tr = {};
+        var entry = [];
+
+
+        entry.push(value['name']);
+        entry.push(value['node']);
+        if (value['flow']['installInHw'] == 'true' && value['flow']['status'] == 'Success')
+        tr['type'] = ['success'];
+        else if (value['flow']['installInHw'] == 'false' && value['flow']['status'] == 'Success')
+        tr['type'] = ['warning'];
+        else 
+        tr['type'] = ['warning'];
+      tr['entry'] = entry;
+      tr['id'] = value['nodeId'];
+
+      body.push(tr);
+      });
+      return body;
     }
+  },
+  body : {
+    dashlet : function(body, callback) {
+      var attributes = ['table-striped', 'table-bordered', 'table-hover', 'table-condensed', 'table-cursor'];
+      var $table = one.lib.dashlet.table.table(attributes);
+
+      var headers = ['Flow Name', 'Node'];
+
+      var $thead = one.lib.dashlet.table.header(headers);
+      $table.append($thead);
+
+      var $tbody = one.lib.dashlet.table.body(body);
+      $table.append($tbody);
+      return $table;
+    }
+  }
 }
 
 /** INIT **/
 // populate nav tabs
 $(one.f.menu.left.top).each(function(index, value) {
-    var $nav = $(".nav", "#left-top");
-    one.main.page.dashlet($nav, value);
+  var $nav = $(".nav", "#left-top");
+  one.main.page.dashlet($nav, value);
 });
 
 $(one.f.menu.left.bottom).each(function(index, value) {
-    var $nav = $(".nav", "#left-bottom");
-    one.main.page.dashlet($nav, value);
+  var $nav = $(".nav", "#left-bottom");
+  one.main.page.dashlet($nav, value);
 });
 
 $(one.f.menu.right.bottom).each(function(index, value) {
-    var $nav = $(".nav", "#right-bottom");
-    one.main.page.dashlet($nav, value);
+  var $nav = $(".nav", "#right-bottom");
+  one.main.page.dashlet($nav, value);
 });
 
 one.f.populate = function($dashlet, header) {
-    var $h4 = one.lib.dashlet.header(header);
-    $dashlet.append($h4);
+  var $h4 = one.lib.dashlet.header(header);
+  $dashlet.append($h4);
 };
 
 // bind dashlet nav
 $('.dash .nav a', '#main').click(function() {
-    // de/activation
-    var $li = $(this).parent();
-    var $ul = $li.parent();
-    one.lib.nav.unfocus($ul);
-    $li.addClass('active');
-    // clear respective dashlet
-    var $dashlet = $ul.parent().find('.dashlet');
-    one.lib.dashlet.empty($dashlet);
-    // callback based on menu
-    var id = $(this).attr('id');
-    var menu = one.f.dashlet;
-    switch (id) {
-        case menu.flows.id:
-            one.f.flows.dashlet($dashlet);
-            break;
-        case menu.nodes.id:
-            one.f.nodes.dashlet($dashlet);
-            break;
-        case menu.detail.id:
-            one.f.detail.dashlet($dashlet);
-            break;
-    };
+  // de/activation
+  var $li = $(this).parent();
+  var $ul = $li.parent();
+  one.lib.nav.unfocus($ul);
+  $li.addClass('active');
+  // clear respective dashlet
+  var $dashlet = $ul.parent().find('.dashlet');
+  one.lib.dashlet.empty($dashlet);
+  // callback based on menu
+  var id = $(this).attr('id');
+  var menu = one.f.dashlet;
+  switch (id) {
+    case menu.flows.id:
+      one.f.flows.dashlet($dashlet);
+      break;
+    case menu.nodes.id:
+      one.f.nodes.dashlet($dashlet);
+      break;
+    case menu.detail.id:
+      one.f.detail.dashlet($dashlet);
+      break;
+  };
 });
 
 // activate first tab on each dashlet
 $('.dash .nav').each(function(index, value) {
-    $($(value).find('li')[0]).find('a').click();
+  $($(value).find('li')[0]).find('a').click();
 });
index ccd07865a8d2b0e67ee22e8b3f13e5fec2081d75..e38829926220bb65eb9f6b326966fadad6110ff0 100644 (file)
@@ -18,6 +18,8 @@
   <properties>
     <sonar.host.url>https://sonar.opendaylight.org/</sonar.host.url>
     <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>
+    <nexus.repository.release>opendaylight.release</nexus.repository.release>
+    <nexus.repository.snapshot>opendaylight.snapshot</nexus.repository.snapshot>
     <sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
     <siteplugin>3.2</siteplugin>
     <projectinfo>2.6</projectinfo>
@@ -29,7 +31,7 @@
   </properties>
 
   <pluginRepositories>
-    <pluginRepository>    
+    <pluginRepository>
       <id>central2</id>
       <name>central2</name>
       <url>http://repo2.maven.org/maven2</url>
     <!-- OpenDayLight Released artifact -->
     <repository>
       <id>opendaylight-release</id>
-      <url>${nexusproxy}/repositories/opendaylight.release/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
     </repository>
     <!-- OpenDayLight Snapshot artifact -->
     <snapshotRepository>
       <id>opendaylight-snapshot</id>
-      <url>${nexusproxy}/repositories/opendaylight.snapshot/</url>
+      <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
     </snapshotRepository>
     <!-- Site deployment -->
     <site>