Merge "Take advantage of MultipartTransactionAware"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 18 Mar 2014 10:42:51 +0000 (10:42 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 18 Mar 2014 10:42:51 +0000 (10:42 +0000)
103 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/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/ConfigManagerActivator.java
opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/mapping/ModuleInfoBundleTracker.java
opendaylight/config/config-persister-directory-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryStorageAdapterTest.java
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/src/main/resources/configuration/config.ini
opendaylight/md-sal/clustered-data-store/implementation/pom.xml
opendaylight/md-sal/model/model-inventory/src/main/yang/netconf-node-inventory.yang
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/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-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/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/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/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationPublishService.java
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/osgi/NotificationPublishServiceProxy.java
opendaylight/md-sal/sal-remoterpc-connector/implementation/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-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/AbstractConfigNetconfOperation.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Commit.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/DiscardChanges.java
opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/Validate.java
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/NetconfOperationServiceImpl.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/ValidateTest.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListener.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/NetconfServerSessionListenerFactory.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCloseSession.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultCommit.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultGetSchema.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStartExi.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/mapping/operations/DefaultStopExi.java
opendaylight/netconf/netconf-impl/src/main/java/org/opendaylight/controller/netconf/impl/osgi/NetconfOperationRouterImpl.java
opendaylight/netconf/netconf-impl/src/test/java/org/opendaylight/controller/netconf/impl/ConcurrentClientsTest.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/HandlingPriority.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperation.java
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java [new file with mode: 0644]
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilter.java [deleted file]
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilterChain.java [deleted file]
opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationService.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/Get.java
opendaylight/netconf/netconf-monitoring/src/main/java/org/opendaylight/controller/netconf/monitoring/osgi/NetconfMonitoringOperationService.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractNetconfOperation.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java [new file with mode: 0644]
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XMLNetconfUtil.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlNetconfConstants.java
opendaylight/networkconfiguration/neutron/implementation/pom.xml
opendaylight/networkconfiguration/neutron/pom.xml
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/neutron/pom.xml
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/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
third-party/commons/thirdparty/pom.xml

index b079cba..175ab5f 100644 (file)
@@ -21,3 +21,5 @@ opendaylight/northbound/integrationtest/logs/*
 xtend-gen
 classes
 out/
+.externalToolBuilders
+maven-eclipse.xml
index 63759c6..d289602 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 ebb9302..016c30d 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 7924ade..36af861 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 8ae038c..fa88382 100644 (file)
@@ -172,6 +172,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 +186,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 +383,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 +418,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);
index 34ddb7a..e05f9df 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 97d9ded..06e5bc5 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 9f2bf90..55567af 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 77c807b..3858f1a 100644 (file)
     <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 085096d..c81dba7 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>
index 02cc5ea..c075b09 100644 (file)
@@ -18,7 +18,7 @@ import org.opendaylight.controller.config.manager.impl.jmx.ConfigRegistryJMXRegi
 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.spi.ModuleFactory;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
 import org.osgi.framework.BundleActivator;
@@ -31,13 +31,11 @@ import org.slf4j.LoggerFactory;
 public class ConfigManagerActivator implements BundleActivator {
     private static final Logger logger = LoggerFactory.getLogger(ConfigManagerActivator.class);
 
-    private ExtensibleBundleTracker<Collection<Registration<YangModuleInfo>>> bundleTracker;
+    private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
+    private ExtensibleBundleTracker<Collection<ObjectRegistration<YangModuleInfo>>> bundleTracker;
     private ConfigRegistryImpl configRegistry;
     private ConfigRegistryJMXRegistrator configRegistryJMXRegistrator;
-    private ServiceRegistration configRegistryServiceRegistration;
-
-    private final MBeanServer configMBeanServer = ManagementFactory.getPlatformMBeanServer();
-
+    private ServiceRegistration<?> configRegistryServiceRegistration;
     private RuntimeGeneratedMappingServiceActivator mappingServiceActivator;
 
     @Override
index a8fdfda..7680f72 100644 (file)
@@ -7,8 +7,16 @@
  */
 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.concepts.ObjectRegistration;
 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
 import org.opendaylight.yangtools.yang.binding.YangModelBindingProvider;
@@ -19,39 +27,31 @@ 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.
  */
-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();
+    private final ModuleInfoBackedContext moduleInfoLoadingStrategy = ModuleInfoBackedContext.create();
 
     public GeneratedClassLoadingStrategy getModuleInfoLoadingStrategy() {
         return moduleInfoLoadingStrategy;
     }
 
     @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());
 
         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);
@@ -70,17 +70,17 @@ public final class ModuleInfoBundleTracker implements BundleTrackerCustomizer<Co
     }
 
     @Override
-    public void modifiedBundle(Bundle bundle, BundleEvent event, Collection<Registration<YangModuleInfo>> object) {
+    public void modifiedBundle(Bundle bundle, BundleEvent event, Collection<ObjectRegistration<YangModuleInfo>> object) {
         // NOOP
     }
 
     @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) {
index 3ae2906..278d0d2 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 773c6ca..ebc5692 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 1d0e86e..68d1b23 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 99f8df3..7d45c82 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
 
index e6cfee1..fe0b516 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 7914de0..e7ac38c 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 db20a13..db0d674 100644 (file)
@@ -27,7 +27,7 @@ import org.osgi.framework.BundleContext;
  * 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.
  * 
  * 
index b3309b7..dd454c6 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 08029dc..b94695b 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 24ca2a3..6e8bda5 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 69a2108..f71d69b 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 c64e24c..cdf5584 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 d7cb926..da6d46d 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 81fe39c..0042998 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 bf82302..fe2681f 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 e98d5b9..e0c7d26 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 64c1ad3..7d7e56d 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 efa02e0..8f367de 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 f6662c3..22c5fa0 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 4b6a018..3ceeb7e 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;
     }
index ed186dc..82ce44c 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 c73a627..b030e6c 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 e201f88..a51dc64 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 652eab1..aa22b90 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 5d93f4e..dc554a0 100644 (file)
@@ -47,8 +47,8 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
     private final DataBrokerImpl dataReader;
     private final NotificationRouter notificationRouter;
     private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
-    
-    
+
+
     private final InstanceIdentifier mountPath;
 
     private SchemaContext schemaContext;
@@ -89,11 +89,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,15 +117,18 @@ 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);
     }
@@ -145,27 +150,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 +174,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 +196,7 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
             }
             return ret;
         }
-        
+
         @Override
         public CompositeNode readConfigurationData(InstanceIdentifier path) {
             InstanceIdentifier newPath = shortenPath(path);
@@ -203,7 +205,7 @@ public class MountPointImpl implements MountProvisionInstance, SchemaContextProv
             }
             return MountPointImpl.this.readConfigurationData(newPath);
         }
-        
+
         @Override
         public CompositeNode readOperationalData(InstanceIdentifier path) {
             InstanceIdentifier newPath = shortenPath(path);
index bbe017f..b298a02 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 8a15d84..cd26c4e 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 9a8f149..e06363d 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>
             <plugin>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>yang-maven-plugin</artifactId>
-                <version>${yangtools.version}</version>
                 <executions>
                     <execution>
                         <goals>
index 0683c45..067b7d9 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 e09dc7a..8ebf28f 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 36c9c67..9c8351a 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 d7b4bd9..1640035 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 18b5ce4..0492b3e 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 5a2c964..2037fd4 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 6f507f9..dff9d65 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 11264e7..c6e2f14 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 359b68d..b681653 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 3272ce5..c08f329 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 7f9cc8f..c2ff3b8 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 a484154..e1d6980 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 6689759..cd99ac4 100644 (file)
@@ -9,15 +9,9 @@
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
 
-public abstract class AbstractConfigNetconfOperation extends AbstractNetconfOperation {
+public abstract class AbstractConfigNetconfOperation extends AbstractLastNetconfOperation {
 
     protected final ConfigRegistryClient configRegistryClient;
 
@@ -26,21 +20,4 @@ public abstract class AbstractConfigNetconfOperation extends AbstractNetconfOper
         super(netconfSessionIdForReporting);
         this.configRegistryClient = configRegistryClient;
     }
-
-    @Override
-    protected HandlingPriority canHandle(String operationName, String operationNamespace) {
-        // TODO check namespace
-        return operationName.equals(getOperationName()) ? HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY
-                : HandlingPriority.CANNOT_HANDLE;
-    }
-
-    protected abstract String getOperationName();
-
-    @Override
-    protected Element handle(Document document, XmlElement operationElement, NetconfOperationRouter opRouter)
-            throws NetconfDocumentedException {
-        return handle(document, operationElement);
-    }
-
-    protected abstract Element handle(Document document, XmlElement operationElement) throws NetconfDocumentedException;
 }
index b3327f5..57e3567 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.opendaylight.controller.config.api.ConflictingVersionException;
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.api.jmx.CommitStatus;
@@ -24,9 +27,6 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.HashMap;
-import java.util.Map;
-
 public class Commit extends AbstractConfigNetconfOperation {
 
     private static final Logger logger = LoggerFactory.getLogger(Commit.class);
@@ -50,7 +50,7 @@ public class Commit extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         checkXml(xml);
 
         CommitStatus status;
index 8965deb..2f72612 100644 (file)
@@ -8,6 +8,9 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorSeverity;
@@ -21,9 +24,6 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.HashMap;
-import java.util.Map;
-
 public class DiscardChanges extends AbstractConfigNetconfOperation {
 
     public static final String DISCARD = "discard-changes";
@@ -49,7 +49,7 @@ public class DiscardChanges extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         try {
             fromXml(xml);
         } catch (final IllegalArgumentException e) {
index 017b5e6..33432e4 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations;
 
-import com.google.common.base.Preconditions;
+import java.util.HashMap;
+import java.util.Map;
+
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
@@ -23,8 +25,7 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.HashMap;
-import java.util.Map;
+import com.google.common.base.Preconditions;
 
 public class Validate extends AbstractConfigNetconfOperation {
 
@@ -62,7 +63,7 @@ public class Validate extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         try {
             checkXml(xml);
         } catch (IllegalStateException e) {
index bd85f94..bb19dc2 100644 (file)
@@ -8,10 +8,15 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+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;
@@ -40,13 +45,10 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 
 public class EditConfig extends AbstractConfigNetconfOperation {
 
@@ -312,7 +314,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
 
         EditConfigXmlParser.EditConfigExecution editConfigExecution;
         Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot);
index dd9a071..73f9ecd 100644 (file)
@@ -8,7 +8,13 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.get;
 
-import com.google.common.collect.Maps;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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;
@@ -35,11 +41,7 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import javax.management.ObjectName;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import com.google.common.collect.Maps;
 
 public class Get extends AbstractConfigNetconfOperation {
 
@@ -119,7 +121,7 @@ public class Get extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         try {
             checkXml(xml);
         } catch (final IllegalArgumentException e) {
index 297f789..7cf6e17 100644 (file)
@@ -8,7 +8,12 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.getconfig;
 
-import com.google.common.base.Optional;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+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;
@@ -29,10 +34,7 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import javax.management.ObjectName;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
+import com.google.common.base.Optional;
 
 public class GetConfig extends AbstractConfigNetconfOperation {
 
@@ -101,7 +103,7 @@ public class GetConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    public Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    public Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         Datastore source;
         try {
             source = fromXml(xml);
index e7f9772..5b7c575 100644 (file)
@@ -8,9 +8,11 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
 
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Maps;
+import java.util.Map;
+
+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.config.yangjmxgenerator.ModuleMXBeanEntry;
@@ -36,9 +38,9 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import javax.management.ObjectName;
-import javax.management.openmbean.OpenType;
-import java.util.Map;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
 
 public class RuntimeRpc extends AbstractConfigNetconfOperation {
 
@@ -64,7 +66,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
         // Either allow List of Elements to be returned from NetconfOperation or
         // pass reference to parent output xml element for netconf operations to
         // append result(s) on their own
-        Element tempParent = doc.createElementNS(XmlNetconfConstants.RFC4741_TARGET_NAMESPACE, "output");
+        Element tempParent = doc.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0, "output");
         new ObjectXmlWriter().prepareWritingStrategy(elementName, returnType, doc).writeElement(tempParent, namespace, mappedAttributeOpt.get());
 
         XmlElement xmlElement = XmlElement.fromDomElement(tempParent);
@@ -161,7 +163,7 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
 
         // TODO exception handling
         // TODO check for namespaces and unknown elements
index 6eabbe6..444500d 100644 (file)
@@ -8,10 +8,11 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.osgi;
 
-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;
+
 import org.opendaylight.controller.config.api.LookupRegistry;
 import org.opendaylight.controller.config.util.ConfigRegistryJMXClient;
 import org.opendaylight.controller.config.yang.store.api.YangStoreException;
@@ -22,15 +23,13 @@ import org.opendaylight.controller.netconf.confignetconfconnector.transactions.T
 import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.yangtools.yang.model.api.Module;
 
-import java.util.Collections;
-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;
 
 /**
  * Manages life cycle of {@link YangStoreSnapshot}.
@@ -94,11 +93,6 @@ public class NetconfOperationServiceImpl implements NetconfOperationService {
         return operationProvider.getOperations();
     }
 
-    @Override
-    public Set<NetconfOperationFilter> getFilters() {
-        return Collections.emptySet();
-    }
-
     private static Set<Capability> setupCapabilities(YangStoreSnapshot yangStoreSnapshot) {
         Set<Capability> capabilities = new HashSet<>();
         // [RFC6241] 8.3.  Candidate Configuration Capability
index 0a4f82f..41d9181 100644 (file)
@@ -8,11 +8,33 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector;
 
-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 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 org.apache.commons.lang3.StringUtils;
 import org.junit.Before;
 import org.junit.Ignore;
@@ -52,6 +74,8 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.get
 import org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc.RuntimeRpc;
 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;
+import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceSnapshot;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
 import org.opendaylight.controller.netconf.util.test.XmlFileLoader;
@@ -72,31 +96,11 @@ import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-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.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;
+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;
 
 
 public class NetconfMappingTest extends AbstractConfigTest {
@@ -112,6 +116,8 @@ public class NetconfMappingTest extends AbstractConfigTest {
     YangStoreSnapshot yangStoreSnapshot;
     @Mock
     NetconfOperationRouter netconfOperationRouter;
+    @Mock
+    NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
 
     private TransactionProvider transactionProvider;
 
@@ -120,6 +126,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
         MockitoAnnotations.initMocks(this);
         doReturn(getMbes()).when(this.yangStoreSnapshot).getModuleMXBeanEntryMap();
         doReturn(getModules()).when(this.yangStoreSnapshot).getModules();
+        doNothing().when(netconfOperationServiceSnapshot).close();
 
         this.factory = new NetconfTestImplModuleFactory();
         this.factory2 = new DepTestImplModuleFactory();
@@ -305,10 +312,10 @@ public class NetconfMappingTest extends AbstractConfigTest {
         assertEquals(expectedResult, responseFromCandidate);
 
         edit("netconfMessages/editConfig_none.xml");
-        doNothing().when(netconfOperationRouter).close();
         closeSession();
-        verify(netconfOperationRouter).close();
+        verify(netconfOperationServiceSnapshot).close();
         verifyNoMoreInteractions(netconfOperationRouter);
+        verifyNoMoreInteractions(netconfOperationServiceSnapshot);
     }
 
     private void checkBigDecimal(Element response) {
@@ -322,7 +329,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
     private void closeSession() throws NetconfDocumentedException, ParserConfigurationException, SAXException,
             IOException {
-        DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID);
+        DefaultCloseSession closeOp = new DefaultCloseSession(NETCONF_SESSION_ID, netconfOperationServiceSnapshot);
         executeOp(closeOp, "netconfMessages/closeSession.xml");
     }
 
@@ -665,7 +672,7 @@ public class NetconfMappingTest extends AbstractConfigTest {
 
         Preconditions.checkState(priority != HandlingPriority.CANNOT_HANDLE);
 
-        final Document response = op.handle(request, netconfOperationRouter);
+        final Document response = op.handle(request, NetconfOperationRouterImpl.EXECUTION_TERMINATION_POINT);
         logger.debug("Got response\n{}", XmlUtil.toString(response));
         return response.getDocumentElement();
     }
index de1ab71..d393121 100644 (file)
@@ -30,7 +30,7 @@ public class ValidateTest {
     public void test() throws Exception {
         final XmlElement xml = XmlElement.fromString("<abc></abc>");
         final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test(expected = NetconfDocumentedException.class)
@@ -38,14 +38,14 @@ public class ValidateTest {
         final XmlElement xml = XmlElement.fromString("<validate xmlns=\""
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 + "\"/>");
         final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test(expected = NetconfDocumentedException.class)
     public void testNoNamespace() throws Exception {
         final XmlElement xml = XmlElement.fromString("<validate/>");
         final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test(expected = NetconfDocumentedException.class)
@@ -55,7 +55,7 @@ public class ValidateTest {
                 + XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0
                 + "\"><source><running></running></source></validate>");
         final Validate validate = new Validate(null, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test(expected = NetconfDocumentedException.class)
@@ -66,7 +66,7 @@ public class ValidateTest {
         final TransactionProvider transactionProvider = mock(TransactionProvider.class);
         doThrow(IllegalStateException.class).when(transactionProvider).validateTransaction();
         final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test(expected = NetconfDocumentedException.class)
@@ -77,7 +77,7 @@ public class ValidateTest {
         final TransactionProvider transactionProvider = mock(TransactionProvider.class);
         doThrow(ValidationException.class).when(transactionProvider).validateTransaction();
         final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        validate.handle(null, xml);
+        validate.handleWithNoSubsequentOperations(null, xml);
     }
 
     @Test
@@ -89,7 +89,7 @@ public class ValidateTest {
         final Element okElement = XmlUtil.readXmlToElement("<ok/>");
         doNothing().when(transactionProvider).validateTransaction();
         final Validate validate = new Validate(transactionProvider, null, NETCONF_SESSION_ID_FOR_REPORTING);
-        Element ok = validate.handle(XmlUtil.newDocument(), xml);
+        Element ok = validate.handleWithNoSubsequentOperations(XmlUtil.newDocument(), xml);
         assertEquals(XmlUtil.toString(okElement), XmlUtil.toString(ok));
     }
 
index 460288f..f8d9a45 100644 (file)
@@ -12,9 +12,9 @@ import static com.google.common.base.Preconditions.checkState;
 
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.api.NetconfSessionListener;
 import org.opendaylight.controller.netconf.api.NetconfTerminationReason;
-import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
 import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
 import org.opendaylight.controller.netconf.util.messages.SendErrorExceptionUtil;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
@@ -33,9 +33,9 @@ public class NetconfServerSessionListener implements NetconfSessionListener<Netc
 
     static final Logger logger = LoggerFactory.getLogger(NetconfServerSessionListener.class);
     private final SessionMonitoringService monitoringService;
-    private final NetconfOperationRouterImpl operationRouter;
+    private final NetconfOperationRouter operationRouter;
 
-    public NetconfServerSessionListener(NetconfOperationRouterImpl operationRouter, SessionMonitoringService monitoringService) {
+    public NetconfServerSessionListener(NetconfOperationRouter operationRouter, SessionMonitoringService monitoringService) {
         this.operationRouter = operationRouter;
         this.monitoringService = monitoringService;
     }
index e25eaac..7e047b1 100644 (file)
@@ -8,6 +8,7 @@
 
 package org.opendaylight.controller.netconf.impl;
 
+import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationRouterImpl;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
@@ -41,7 +42,7 @@ public class NetconfServerSessionListenerFactory implements SessionListenerFacto
 
         CapabilityProvider capabilityProvider = new CapabilityProviderImpl(netconfOperationServiceSnapshot);
 
-        NetconfOperationRouterImpl operationRouter = new NetconfOperationRouterImpl(
+        NetconfOperationRouter operationRouter = NetconfOperationRouterImpl.createOperationRouter(
                 netconfOperationServiceSnapshot, capabilityProvider,
                 commitNotifier);
 
index 1438515..8bc93e0 100644 (file)
@@ -8,30 +8,27 @@
 
 package org.opendaylight.controller.netconf.impl.mapping.operations;
 
+import java.util.Collections;
+
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
+import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-public class DefaultCloseSession extends AbstractNetconfOperation {
+public class DefaultCloseSession extends AbstractSingletonNetconfOperation {
     public static final String CLOSE_SESSION = "close-session";
+    private final AutoCloseable sessionResources;
 
-    public DefaultCloseSession(String netconfSessionIdForReporting) {
+    public DefaultCloseSession(String netconfSessionIdForReporting, AutoCloseable sessionResources) {
         super(netconfSessionIdForReporting);
+        this.sessionResources = sessionResources;
     }
 
     @Override
-    protected HandlingPriority canHandle(String operationName, String netconfOperationNamespace) {
-        if (operationName.equals(CLOSE_SESSION) == false)
-            return HandlingPriority.CANNOT_HANDLE;
-        if (netconfOperationNamespace.equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0) == false)
-            return HandlingPriority.CANNOT_HANDLE;
-
-        return HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
+    protected String getOperationName() {
+        return CLOSE_SESSION;
     }
 
     /**
@@ -40,9 +37,17 @@ public class DefaultCloseSession extends AbstractNetconfOperation {
      * instances
      */
     @Override
-    protected Element handle(Document document, XmlElement operationElement, NetconfOperationRouter opRouter)
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement)
             throws NetconfDocumentedException {
-        opRouter.close();
+        try {
+            sessionResources.close();
+        } catch (Exception e) {
+            throw new NetconfDocumentedException("Unable to properly close session "
+                    + getNetconfSessionIdForReporting(), NetconfDocumentedException.ErrorType.application,
+                    NetconfDocumentedException.ErrorTag.operation_failed,
+                    NetconfDocumentedException.ErrorSeverity.error, Collections.singletonMap(
+                    NetconfDocumentedException.ErrorSeverity.error.toString(), e.getMessage()));
+        }
         return document.createElement(XmlNetconfConstants.OK);
     }
 }
index 9069e87..ee0c6ce 100644 (file)
@@ -15,9 +15,9 @@ import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.impl.DefaultCommitNotificationProducer;
 import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilterChain;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation.OperationNameAndNamespace;
+import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
+import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -26,9 +26,10 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
 
-public class DefaultCommit implements NetconfOperationFilter {
+public class DefaultCommit extends AbstractNetconfOperation {
 
     private static final Logger logger = LoggerFactory.getLogger(DefaultCommit.class);
 
@@ -36,13 +37,14 @@ public class DefaultCommit implements NetconfOperationFilter {
 
     private final DefaultCommitNotificationProducer notificationProducer;
     private final CapabilityProvider cap;
-    private final String netconfSessionIdForReporting;
+    private final NetconfOperationRouter operationRouter;
 
     public DefaultCommit(DefaultCommitNotificationProducer notifier, CapabilityProvider cap,
-            String netconfSessionIdForReporting) {
+                         String netconfSessionIdForReporting, NetconfOperationRouter netconfOperationRouter) {
+        super(netconfSessionIdForReporting);
         this.notificationProducer = notifier;
         this.cap = cap;
-        this.netconfSessionIdForReporting = netconfSessionIdForReporting;
+        this.operationRouter = netconfOperationRouter;
         this.getConfigMessage = loadGetConfigMessage();
     }
 
@@ -59,40 +61,36 @@ public class DefaultCommit implements NetconfOperationFilter {
     }
 
     @Override
-    public Document doFilter(Document message, NetconfOperationRouter operationRouter,
-            NetconfOperationFilterChain filterChain) throws NetconfDocumentedException {
-        OperationNameAndNamespace operationNameAndNamespace = new OperationNameAndNamespace(message);
-        if (canHandle(operationNameAndNamespace)) {
-            if (isCommitWithoutNotification(message)) {
-                message = removePersisterAttributes(message);
-                logger.debug("Skipping commit notification");
-                // fall back to filter chain
-            } else {
-                Document innerResult = filterChain.execute(message, operationRouter);
-                Element cfgSnapshot = getConfigSnapshot(operationRouter);
-                logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot);
-                notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities());
-                return innerResult;
-            }
-        }
-        return filterChain.execute(message, operationRouter);
+    protected String getOperationName() {
+        return XmlNetconfConstants.COMMIT;
     }
 
     @Override
-    public int getSortingOrder() {
-        return 0;
+    public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+        Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
+                "Subsequent netconf operation expected by %s", this);
+
+        if (isCommitWithoutNotification(requestMessage)) {
+            logger.debug("Skipping commit notification");
+        } else {
+            // Send commit notification if commit was not issued by persister
+            requestMessage = removePersisterAttributes(requestMessage);
+            Element cfgSnapshot = getConfigSnapshot(operationRouter);
+            logger.debug("Config snapshot retrieved successfully {}", cfgSnapshot);
+            notificationProducer.sendCommitNotification("ok", cfgSnapshot, cap.getCapabilities());
+        }
+
+        return subsequentOperation.execute(requestMessage);
     }
 
     @Override
-    public int compareTo(NetconfOperationFilter o) {
-        return Integer.compare(getSortingOrder(), o.getSortingOrder());
+    protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+        throw new UnsupportedOperationException("Never gets called");
     }
 
-    private boolean canHandle(OperationNameAndNamespace operationNameAndNamespace) {
-        if (operationNameAndNamespace.getOperationName().equals("commit") == false)
-            return false;
-        return operationNameAndNamespace.getNamespace().equals(
-                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+    @Override
+    protected HandlingPriority getHandlingPriority() {
+        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
     }
 
     private Document removePersisterAttributes(Document message) {
@@ -139,8 +137,4 @@ public class DefaultCommit implements NetconfOperationFilter {
         return dataElement.getDomElement();
     }
 
-    @Override
-    public String toString() {
-        return "DefaultCommit{" + netconfSessionIdForReporting + '}';
-    }
 }
index 904f3f6..a81bbd6 100644 (file)
@@ -12,10 +12,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
+import org.opendaylight.controller.netconf.util.mapping.AbstractLastNetconfOperation;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -27,7 +25,7 @@ import org.w3c.dom.Element;
 import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
 
-public final class DefaultGetSchema extends AbstractNetconfOperation {
+public final class DefaultGetSchema extends AbstractLastNetconfOperation {
     public static final String GET_SCHEMA = "get-schema";
     public static final String IDENTIFIER = "identifier";
     public static final String VERSION = "version";
@@ -41,18 +39,17 @@ public final class DefaultGetSchema extends AbstractNetconfOperation {
     }
 
     @Override
-    protected HandlingPriority canHandle(String netconfOperationName, String namespace) {
-        if (netconfOperationName.equals("get-schema") == false)
-            return HandlingPriority.CANNOT_HANDLE;
-        if (namespace.equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING) == false)
-            return HandlingPriority.CANNOT_HANDLE;
+    protected String getOperationName() {
+        return GET_SCHEMA;
+    }
 
-        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
+    @Override
+    protected String getOperationNamespace() {
+        return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING;
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml, NetconfOperationRouter router)
-            throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
         GetSchemaEntry entry;
 
         try {
index 38c1a44..31a7d32 100644 (file)
@@ -7,12 +7,10 @@
  */\r
 package org.opendaylight.controller.netconf.impl.mapping.operations;\r
 \r
-import org.opendaylight.controller.netconf.api.NetconfSession;\r
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;\r
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;\r
+import org.opendaylight.controller.netconf.api.NetconfSession;\r
 import org.opendaylight.controller.netconf.mapping.api.DefaultNetconfOperation;\r
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;\r
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;\r
+import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;\r
 import org.opendaylight.controller.netconf.util.xml.XmlElement;\r
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;\r
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;\r
@@ -21,7 +19,7 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;\r
 import org.w3c.dom.Element;\r
 \r
-public class DefaultStartExi extends AbstractNetconfOperation implements DefaultNetconfOperation {\r
+public class DefaultStartExi extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {\r
 \r
     public static final String START_EXI = "start-exi";\r
 \r
@@ -34,20 +32,12 @@ public class DefaultStartExi extends AbstractNetconfOperation implements Default
     }\r
 \r
     @Override\r
-    protected HandlingPriority canHandle(String operationName,\r
-            String netconfOperationNamespace) {\r
-        if (operationName.equals(START_EXI) == false)\r
-            return HandlingPriority.CANNOT_HANDLE;\r
-        if (netconfOperationNamespace\r
-                .equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0) == false)\r
-            return HandlingPriority.CANNOT_HANDLE;\r
-\r
-        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;\r
+    protected String getOperationName() {\r
+        return START_EXI;\r
     }\r
 \r
     @Override\r
-    protected Element handle(Document document, XmlElement operationElement,\r
-            NetconfOperationRouter opRouter) throws NetconfDocumentedException {\r
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException {\r
 \r
 \r
         Element getSchemaResult = document\r
index 6ea5deb..ae3b00b 100644 (file)
@@ -7,20 +7,17 @@
  */\r
 package org.opendaylight.controller.netconf.impl.mapping.operations;\r
 \r
-import org.opendaylight.controller.netconf.api.NetconfSession;\r
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;\r
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;\r
+import org.opendaylight.controller.netconf.api.NetconfSession;\r
 import org.opendaylight.controller.netconf.mapping.api.DefaultNetconfOperation;\r
-import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;\r
-import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;\r
+import org.opendaylight.controller.netconf.util.mapping.AbstractSingletonNetconfOperation;\r
 import org.opendaylight.controller.netconf.util.xml.XmlElement;\r
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
 import org.w3c.dom.Document;\r
 import org.w3c.dom.Element;\r
 \r
-public class DefaultStopExi extends AbstractNetconfOperation implements DefaultNetconfOperation {\r
+public class DefaultStopExi extends AbstractSingletonNetconfOperation implements DefaultNetconfOperation {\r
 \r
     public static final String STOP_EXI = "stop-exi";\r
     private NetconfSession netconfSession;\r
@@ -33,20 +30,13 @@ public class DefaultStopExi extends AbstractNetconfOperation implements DefaultN
     }\r
 \r
     @Override\r
-    protected HandlingPriority canHandle(String operationName,\r
-            String netconfOperationNamespace) {\r
-        if (operationName.equals(STOP_EXI) == false)\r
-            return HandlingPriority.CANNOT_HANDLE;\r
-        if (netconfOperationNamespace\r
-                .equals(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0) == false)\r
-            return HandlingPriority.CANNOT_HANDLE;\r
-\r
-        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;\r
+    protected String getOperationName() {\r
+        return STOP_EXI;\r
     }\r
 \r
     @Override\r
-    protected Element handle(Document document, XmlElement operationElement,\r
-            NetconfOperationRouter opRouter) throws NetconfDocumentedException {\r
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement)\r
+            throws NetconfDocumentedException {\r
         throw new UnsupportedOperationException("Not implemented");\r
         /*\r
         netconfSession.remove(ExiDecoderHandler.class);\r
index ece9d47..8d532d4 100644 (file)
@@ -9,12 +9,9 @@ package org.opendaylight.controller.netconf.impl.osgi;
 
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.TreeSet;
 
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
 import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
@@ -29,8 +26,7 @@ import org.opendaylight.controller.netconf.impl.mapping.operations.DefaultStopEx
 import org.opendaylight.controller.netconf.mapping.api.DefaultNetconfOperation;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilterChain;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.slf4j.Logger;
@@ -46,31 +42,38 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
     private static final Logger logger = LoggerFactory.getLogger(NetconfOperationRouterImpl.class);
 
     private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
+    private Set<NetconfOperation> allNetconfOperations;
 
-    private final Set<NetconfOperation> allNetconfOperations;
-    private final TreeSet<NetconfOperationFilter> allSortedFilters;
-
-    private final CapabilityProvider capabilityProvider;
+    private NetconfOperationRouterImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
+        this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
+    }
 
+    private void initNetconfOperations(Set<NetconfOperation> allOperations) {
+        allNetconfOperations = allOperations;
+    }
 
-    public NetconfOperationRouterImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot,
-            CapabilityProvider capabilityProvider, DefaultCommitNotificationProducer commitNotifier) {
+    /**
+     * Factory method to produce instance of NetconfOperationRouter
+     */
+    public static NetconfOperationRouter createOperationRouter(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot,
+                                                               CapabilityProvider capabilityProvider, DefaultCommitNotificationProducer commitNotifier) {
+        NetconfOperationRouterImpl router = new NetconfOperationRouterImpl(netconfOperationServiceSnapshot);
 
-        this.netconfOperationServiceSnapshot = Preconditions.checkNotNull(netconfOperationServiceSnapshot);
-        this.capabilityProvider = Preconditions.checkNotNull(capabilityProvider);
+        Preconditions.checkNotNull(netconfOperationServiceSnapshot);
+        Preconditions.checkNotNull(capabilityProvider);
 
         final String sessionId = netconfOperationServiceSnapshot.getNetconfSessionIdForReporting();
+
         final Set<NetconfOperation> defaultNetconfOperations = Sets.newHashSet();
         defaultNetconfOperations.add(new DefaultGetSchema(capabilityProvider, sessionId));
-        defaultNetconfOperations.add(new DefaultCloseSession(sessionId));
+        defaultNetconfOperations.add(new DefaultCloseSession(sessionId, router));
         defaultNetconfOperations.add(new DefaultStartExi(sessionId));
         defaultNetconfOperations.add(new DefaultStopExi(sessionId));
+        defaultNetconfOperations.add(new DefaultCommit(commitNotifier, capabilityProvider, sessionId, router));
 
-        allNetconfOperations = getAllNetconfOperations(defaultNetconfOperations, netconfOperationServiceSnapshot);
+        router.initNetconfOperations(getAllNetconfOperations(defaultNetconfOperations, netconfOperationServiceSnapshot));
 
-        DefaultCommit defaultCommit = new DefaultCommit(commitNotifier, capabilityProvider, sessionId);
-        Set<NetconfOperationFilter> defaultFilters = Sets.<NetconfOperationFilter> newHashSet(defaultCommit);
-        allSortedFilters = getAllNetconfFilters(defaultFilters, netconfOperationServiceSnapshot);
+        return router;
     }
 
     private static Set<NetconfOperation> getAllNetconfOperations(Set<NetconfOperation> defaultNetconfOperations,
@@ -89,29 +92,12 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         return Collections.unmodifiableSet(result);
     }
 
-    private static TreeSet<NetconfOperationFilter> getAllNetconfFilters(Set<NetconfOperationFilter> defaultFilters,
-            NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
-        TreeSet<NetconfOperationFilter> result = new TreeSet<>(defaultFilters);
-        for (NetconfOperationService netconfOperationService : netconfOperationServiceSnapshot.getServices()) {
-            final Set<NetconfOperationFilter> filtersFromService = netconfOperationService.getFilters();
-            for (NetconfOperationFilter filter : filtersFromService) {
-                Preconditions.checkState(result.contains(filter) == false,
-                        "Filter %s already present, all filters so far: %s", filter, result);
-                result.add(filter);
-            }
-        }
-        return result;
-    }
-
-    public CapabilityProvider getCapabilityProvider() {
-        return capabilityProvider;
-    }
-
     @Override
     public synchronized Document onNetconfMessage(Document message,
             NetconfSession session) throws NetconfDocumentedException {
-        NetconfOperationExecution netconfOperationExecution;
+        Preconditions.checkNotNull(allNetconfOperations, "Operation router was not initialized properly");
 
+        NetconfOperationExecution netconfOperationExecution;
         String messageAsString = XmlUtil.toString(message);
 
         try {
@@ -144,6 +130,11 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         }
     }
 
+    @Override
+    public void close() {
+        netconfOperationServiceSnapshot.close();
+    }
+
     private NetconfDocumentedException handleUnexpectedEx(String s, Exception e) throws NetconfDocumentedException {
         logger.error(s, e);
 
@@ -155,94 +146,91 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
                 NetconfDocumentedException.ErrorSeverity.error, info);
     }
 
-    private Document executeOperationWithHighestPriority(Document message, NetconfOperationExecution netconfOperationExecution, String messageAsString) throws NetconfDocumentedException {
-        logger.debug("Forwarding netconf message {} to {}", messageAsString,
-                netconfOperationExecution.operationWithHighestPriority);
-
-        final LinkedList<NetconfOperationFilterChain> chain = new LinkedList<>();
-        chain.push(netconfOperationExecution);
-
-        for (Iterator<NetconfOperationFilter> it = allSortedFilters.descendingIterator(); it.hasNext();) {
-            final NetconfOperationFilter filter = it.next();
-            final NetconfOperationFilterChain prevItem = chain.getFirst();
-            NetconfOperationFilterChain currentItem = new NetconfOperationFilterChain() {
-                @Override
-                public Document execute(Document message, NetconfOperationRouter operationRouter)
-                        throws NetconfDocumentedException {
-                    logger.trace("Entering {}", filter);
-                    return filter.doFilter(message, operationRouter, prevItem);
-                }
-            };
-            chain.push(currentItem);
-        }
-        return chain.getFirst().execute(message, this);
+    private Document executeOperationWithHighestPriority(Document message,
+            NetconfOperationExecution netconfOperationExecution, String messageAsString)
+            throws NetconfDocumentedException {
+        logger.debug("Forwarding netconf message {} to {}", messageAsString, netconfOperationExecution.netconfOperation);
+        return netconfOperationExecution.execute(message);
     }
 
     private NetconfOperationExecution getNetconfOperationWithHighestPriority(
             Document message, NetconfSession session) {
 
-        TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = getSortedNetconfOperationsWithCanHandle(
+        TreeMap<HandlingPriority, NetconfOperation> sortedByPriority = getSortedNetconfOperationsWithCanHandle(
                 message, session);
 
-        Preconditions.checkArgument(sortedPriority.isEmpty() == false, "No %s available to handle message %s",
-                NetconfOperation.class.getName(), XmlUtil.toString(message));
-
-        HandlingPriority highestFoundPriority = sortedPriority.lastKey();
-
-        int netconfOperationsWithHighestPriority = sortedPriority.get(highestFoundPriority).size();
-
-        Preconditions.checkState(netconfOperationsWithHighestPriority == 1,
-                "Multiple %s available to handle message %s", NetconfOperation.class.getName(), message);
+        Preconditions.checkArgument(sortedByPriority.isEmpty() == false,
+                "No %s available to handleWithNoSubsequentOperations message %s", NetconfOperation.class.getName(),
+                XmlUtil.toString(message));
 
-        return new NetconfOperationExecution(sortedPriority, highestFoundPriority);
+        return NetconfOperationExecution.createExecutionChain(sortedByPriority, sortedByPriority.lastKey());
     }
 
-    private TreeMap<HandlingPriority, Set<NetconfOperation>> getSortedNetconfOperationsWithCanHandle(
-            Document message, NetconfSession session) {
-        TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority = Maps.newTreeMap();
+    private TreeMap<HandlingPriority, NetconfOperation> getSortedNetconfOperationsWithCanHandle(Document message,
+            NetconfSession session) {
+        TreeMap<HandlingPriority, NetconfOperation> sortedPriority = Maps.newTreeMap();
 
         for (NetconfOperation netconfOperation : allNetconfOperations) {
             final HandlingPriority handlingPriority = netconfOperation.canHandle(message);
             if (netconfOperation instanceof DefaultNetconfOperation) {
-                ((DefaultNetconfOperation) netconfOperation)
-                        .setNetconfSession(session);
+                ((DefaultNetconfOperation) netconfOperation).setNetconfSession(session);
             }
             if (handlingPriority.equals(HandlingPriority.CANNOT_HANDLE) == false) {
-                Set<NetconfOperation> netconfOperations = sortedPriority.get(handlingPriority);
-                netconfOperations = checkIfNoOperationsOnPriority(sortedPriority, handlingPriority, netconfOperations);
-                netconfOperations.add(netconfOperation);
+
+                Preconditions.checkState(sortedPriority.containsKey(handlingPriority) == false,
+                        "Multiple %s available to handle message %s with priority %s",
+                        NetconfOperation.class.getName(), message, handlingPriority);
+                sortedPriority.put(handlingPriority, netconfOperation);
             }
         }
         return sortedPriority;
     }
 
-    private Set<NetconfOperation> checkIfNoOperationsOnPriority(
-            TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority, HandlingPriority handlingPriority,
-            Set<NetconfOperation> netconfOperations) {
-        if (netconfOperations == null) {
-            netconfOperations = Sets.newHashSet();
-            sortedPriority.put(handlingPriority, netconfOperations);
+    public static final NetconfOperationChainedExecution EXECUTION_TERMINATION_POINT = new NetconfOperationChainedExecution() {
+        @Override
+        public boolean isExecutionTermination() {
+            return true;
         }
-        return netconfOperations;
-    }
 
-    @Override
-    public void close() {
-        netconfOperationServiceSnapshot.close();
-    }
+        @Override
+        public Document execute(Document requestMessage) throws NetconfDocumentedException {
+            throw new IllegalStateException("This execution represents the termination point in operation execution and cannot be executed itself");
+        }
+    };
+
+    private static class NetconfOperationExecution implements NetconfOperationChainedExecution {
+        private final NetconfOperation netconfOperation;
+        private NetconfOperationChainedExecution subsequentExecution;
 
-    private class NetconfOperationExecution implements NetconfOperationFilterChain {
-        private final NetconfOperation operationWithHighestPriority;
+        private NetconfOperationExecution(NetconfOperation netconfOperation, NetconfOperationChainedExecution subsequentExecution) {
+            this.netconfOperation = netconfOperation;
+            this.subsequentExecution = subsequentExecution;
+        }
 
-        public NetconfOperationExecution(TreeMap<HandlingPriority, Set<NetconfOperation>> sortedPriority,
-                HandlingPriority highestFoundPriority) {
-            operationWithHighestPriority = sortedPriority.get(highestFoundPriority).iterator().next();
-            sortedPriority.remove(highestFoundPriority);
+        @Override
+        public boolean isExecutionTermination() {
+            return false;
         }
 
         @Override
-        public Document execute(Document message, NetconfOperationRouter router) throws NetconfDocumentedException {
-            return operationWithHighestPriority.handle(message, router);
+        public Document execute(Document message) throws NetconfDocumentedException {
+            return netconfOperation.handle(message, subsequentExecution);
+        }
+
+        public static NetconfOperationExecution createExecutionChain(
+                TreeMap<HandlingPriority, NetconfOperation> sortedByPriority, HandlingPriority handlingPriority) {
+            NetconfOperation netconfOperation = sortedByPriority.get(handlingPriority);
+            HandlingPriority subsequentHandlingPriority = sortedByPriority.lowerKey(handlingPriority);
+
+            NetconfOperationChainedExecution subsequentExecution = null;
+
+            if (subsequentHandlingPriority != null) {
+                subsequentExecution = createExecutionChain(sortedByPriority, subsequentHandlingPriority);
+            } else {
+                subsequentExecution = EXECUTION_TERMINATION_POINT;
+            }
+
+            return new NetconfOperationExecution(netconfOperation, subsequentExecution);
         }
     }
 
@@ -251,7 +239,4 @@ public class NetconfOperationRouterImpl implements NetconfOperationRouter {
         return "NetconfOperationRouterImpl{" + "netconfOperationServiceSnapshot=" + netconfOperationServiceSnapshot
                 + '}';
     }
-
-
-
 }
index c0d52ad..4385437 100644 (file)
@@ -8,12 +8,26 @@
 
 package org.opendaylight.controller.netconf.impl;
 
-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 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 org.apache.commons.io.IOUtils;
 import org.junit.After;
 import org.junit.Before;
@@ -26,7 +40,6 @@ 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.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.client.NetconfClient;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListenerImpl;
@@ -34,7 +47,7 @@ import org.opendaylight.controller.netconf.impl.osgi.SessionMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationServiceFactory;
 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
@@ -44,24 +57,13 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
-import javax.management.ObjectName;
-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 com.google.common.base.Optional;
+import com.google.common.collect.Sets;
 
-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 io.netty.channel.ChannelFuture;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.util.HashedWheelTimer;
 
 public class ConcurrentClientsTest {
 
@@ -151,8 +153,7 @@ public class ConcurrentClientsTest {
                             }
 
                             @Override
-                            public Document handle(Document message, NetconfOperationRouter operationRouter)
-                                    throws NetconfDocumentedException {
+                            public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
                                 try {
                                     return XmlUtil.readXmlToDocument("<test/>");
                                 } catch (Exception e) {
@@ -162,11 +163,6 @@ public class ConcurrentClientsTest {
                         });
                     }
 
-                    @Override
-                    public Set<NetconfOperationFilter> getFilters() {
-                        return Collections.emptySet();
-                    }
-
                     @Override
                     public void close() {
                     }
index 176cf2d..1236138 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.controller.netconf.mapping.api;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
 
 public class HandlingPriority implements Comparable<HandlingPriority> {
 
@@ -33,7 +34,15 @@ public class HandlingPriority implements Comparable<HandlingPriority> {
      * @return priority number or Optional.absent otherwise
      */
     public Optional<Integer> getPriority() {
-        return Optional.of(priority).or(Optional.<Integer> absent());
+        return Optional.fromNullable(priority);
+    }
+
+    public HandlingPriority increasePriority(int priorityIncrease) {
+        Preconditions.checkState(priority!=null, "Unable to increase priority for %s", this);
+        Preconditions.checkArgument(priorityIncrease > 0, "Negative increase");
+        Preconditions.checkArgument(Long.valueOf(priority) + priorityIncrease < Integer.MAX_VALUE,
+                "Resulting priority cannot be higher than %s", Integer.MAX_VALUE);
+        return getHandlingPriority(priority + priorityIncrease);
     }
 
     @Override
index 58857b4..b70f8db 100644 (file)
@@ -9,12 +9,45 @@
 package org.opendaylight.controller.netconf.mapping.api;
 
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.w3c.dom.Document;
 
+/**
+ * NetconfOperation handles netconf requests. Multiple operations might be
+ * capable of handling one request at the same time. In such case, these
+ * operations are chained (ordered by HandlingPriority returned by canHandle
+ * method) and executed.
+ *
+ * Operation can be declared as singleton or last in chain (see abstract
+ * implementations in netconf-util). If the operation is not singleton or last,
+ * it is responsible for the execution of subsequent operation and for merging
+ * the results.
+ *
+ */
 public interface NetconfOperation {
 
-    HandlingPriority canHandle(Document message);
+    /**
+     * Singleton operations should return
+     * HandlingPriority.HANDLE_WITH_MAX_PRIORITY, last operations
+     * HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.
+     *
+     * @param requestMessage
+     * @return
+     */
+    HandlingPriority canHandle(Document requestMessage);
 
-    Document handle(Document message, NetconfOperationRouter operationRouter) throws NetconfDocumentedException;
+    /**
+     * Execute current netconf operation and trigger execution of subsequent
+     * operations. subsequentOperation parameter will provide information, if
+     * current operation is the termination point in execution. In case of
+     * last/singleton operation, subsequentOperation must indicate termination
+     * point.
+     *
+     * @param requestMessage
+     * @param subsequentOperation
+     *            execution of subsequent netconf operation
+     * @return
+     * @throws NetconfDocumentedException
+     */
+    Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
+            throws NetconfDocumentedException;
 }
diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationChainedExecution.java
new file mode 100644 (file)
index 0000000..2298153
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.netconf.mapping.api;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.w3c.dom.Document;
+
+/**
+ * Single link in netconf operation execution chain.
+ * Wraps the execution of a single netconf operation.
+ */
+public interface NetconfOperationChainedExecution {
+
+    /**
+     * @return true if this is termination point in operation execution, false
+     *         if there is a subsequent operation present that needs to be
+     *         executed
+     */
+    boolean isExecutionTermination();
+
+    /**
+     * Do not execute if this is termination point
+     */
+    Document execute(Document requestMessage) throws NetconfDocumentedException;
+}
diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilter.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilter.java
deleted file mode 100644 (file)
index c9e04e3..0000000
+++ /dev/null
@@ -1,26 +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.mapping.api;
-
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
-import org.w3c.dom.Document;
-
-/**
- * Filters wrap each netconf operation, if there is one found. Filters are
- * sorted and applied from the greatest to smallest sorting order.
- */
-public interface NetconfOperationFilter extends Comparable<NetconfOperationFilter> {
-
-    Document doFilter(Document message, NetconfOperationRouter operationRouter, NetconfOperationFilterChain filterChain)
-            throws NetconfDocumentedException;
-
-    int getSortingOrder();
-
-}
diff --git a/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilterChain.java b/opendaylight/netconf/netconf-mapping-api/src/main/java/org/opendaylight/controller/netconf/mapping/api/NetconfOperationFilterChain.java
deleted file mode 100644 (file)
index 7a0eb91..0000000
+++ /dev/null
@@ -1,19 +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.mapping.api;
-
-import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
-import org.w3c.dom.Document;
-
-public interface NetconfOperationFilterChain {
-
-    Document execute(Document message, NetconfOperationRouter operationRouter) throws NetconfDocumentedException;
-
-}
index 0b923f6..08da361 100644 (file)
@@ -7,12 +7,12 @@
  */
 package org.opendaylight.controller.netconf.monitoring;
 
-import com.google.common.collect.Maps;
+import java.util.Map;
+
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilterChain;
+import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.monitoring.xml.JaxBSerializer;
 import org.opendaylight.controller.netconf.monitoring.xml.model.NetconfState;
 import org.opendaylight.controller.netconf.util.mapping.AbstractNetconfOperation;
@@ -24,32 +24,50 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import java.util.Map;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
 
-public class Get implements NetconfOperationFilter {
+public class Get extends AbstractNetconfOperation {
 
     private static final Logger logger = LoggerFactory.getLogger(Get.class);
     private final NetconfMonitoringService netconfMonitor;
 
     public Get(NetconfMonitoringService netconfMonitor) {
+        super(MonitoringConstants.MODULE_NAME);
         this.netconfMonitor = netconfMonitor;
     }
 
-    @Override
-    public Document doFilter(Document message, NetconfOperationRouter operationRouter,
-            NetconfOperationFilterChain filterChain) throws NetconfDocumentedException {
-        AbstractNetconfOperation.OperationNameAndNamespace operationNameAndNamespace = new AbstractNetconfOperation.OperationNameAndNamespace(
-                message);
-        if (canHandle(operationNameAndNamespace)) {
-            return handle(message, operationRouter, filterChain);
+    private Element getPlaceholder(Document innerResult) {
+        try {
+            XmlElement rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(),
+                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+            return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
+        } catch (RuntimeException e) {
+            throw new IllegalArgumentException(String.format(
+                    "Input xml in wrong format, Expecting root element %s with child element %s, but was %s",
+                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.DATA_KEY,
+                    XmlUtil.toString(innerResult.getDocumentElement())), e);
         }
-        return filterChain.execute(message, operationRouter);
     }
 
-    private Document handle(Document message, NetconfOperationRouter operationRouter,
-            NetconfOperationFilterChain filterChain) throws NetconfDocumentedException {
+    @Override
+    protected String getOperationName() {
+        return XmlNetconfConstants.GET;
+    }
+
+    @Override
+    protected HandlingPriority getHandlingPriority() {
+        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY.increasePriority(1);
+    }
+
+    @Override
+    public Document handle(Document requestMessage, NetconfOperationChainedExecution subsequentOperation)
+            throws NetconfDocumentedException {
+        Preconditions.checkArgument(subsequentOperation.isExecutionTermination() == false,
+                "Subsequent netconf operation expected by %s", this);
+
         try {
-            Document innerResult = filterChain.execute(message, operationRouter);
+            Document innerResult = subsequentOperation.execute(requestMessage);
 
             NetconfState netconfMonitoring = new NetconfState(netconfMonitor);
             Element monitoringXmlElement = new JaxBSerializer().toXml(netconfMonitoring);
@@ -70,35 +88,9 @@ public class Get implements NetconfOperationFilter {
         }
     }
 
-    private Element getPlaceholder(Document innerResult) {
-        try {
-            XmlElement rootElement = XmlElement.fromDomElementWithExpected(innerResult.getDocumentElement(),
-                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.RFC4741_TARGET_NAMESPACE);
-            return rootElement.getOnlyChildElement(XmlNetconfConstants.DATA_KEY).getDomElement();
-        } catch (RuntimeException e) {
-            throw new IllegalArgumentException(String.format(
-                    "Input xml in wrong format, Expecting root element %s with child element %s, but was %s",
-                    XmlNetconfConstants.RPC_REPLY_KEY, XmlNetconfConstants.DATA_KEY,
-                    XmlUtil.toString(innerResult.getDocumentElement())), e);
-        }
-    }
-
-    private boolean canHandle(AbstractNetconfOperation.OperationNameAndNamespace operationNameAndNamespace) {
-        if (operationNameAndNamespace.getOperationName().equals(XmlNetconfConstants.GET) == false)
-            return false;
-        return operationNameAndNamespace.getNamespace().equals(
-                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
-    }
-
     @Override
-    public int getSortingOrder() {
-        // FIXME filters for different operations cannot have same order
-        return 1;
+    protected Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
+            throws NetconfDocumentedException {
+        throw new UnsupportedOperationException("Never gets called");
     }
-
-    @Override
-    public int compareTo(NetconfOperationFilter o) {
-        return Integer.compare(getSortingOrder(), o.getSortingOrder());
-    }
-
 }
index fe01847..a42bc09 100644 (file)
@@ -7,27 +7,26 @@
 */
 package org.opendaylight.controller.netconf.monitoring.osgi;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
 import org.opendaylight.controller.netconf.api.monitoring.NetconfMonitoringService;
 import org.opendaylight.controller.netconf.mapping.api.Capability;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
-import org.opendaylight.controller.netconf.mapping.api.NetconfOperationFilter;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
 import org.opendaylight.controller.netconf.monitoring.Get;
 import org.opendaylight.controller.netconf.monitoring.MonitoringConstants;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import com.google.common.io.Files;
 
 public class NetconfMonitoringOperationService implements NetconfOperationService {
 
@@ -89,12 +88,7 @@ public class NetconfMonitoringOperationService implements NetconfOperationServic
 
     @Override
     public Set<NetconfOperation> getNetconfOperations() {
-        return Collections.emptySet();
-    }
-
-    @Override
-    public Set<NetconfOperationFilter> getFilters() {
-        return Sets.<NetconfOperationFilter>newHashSet(new Get(monitor));
+        return Sets.<NetconfOperation>newHashSet(new Get(monitor));
     }
 
     @Override
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractLastNetconfOperation.java
new file mode 100644 (file)
index 0000000..d6d57c5
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * 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.util.mapping;
+
+import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
+import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import com.google.common.base.Preconditions;
+
+public abstract class AbstractLastNetconfOperation extends AbstractNetconfOperation {
+
+    protected AbstractLastNetconfOperation(String netconfSessionIdForReporting) {
+        super(netconfSessionIdForReporting);
+    }
+
+    @Override
+    protected Element handle(Document document, XmlElement operationElement,
+            NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
+        Preconditions.checkArgument(subsequentOperation.isExecutionTermination(),
+                "No netconf operation expected to be subsequent to %s, but is %s", this, subsequentOperation);
+
+        return handleWithNoSubsequentOperations(document, operationElement);
+    }
+
+    @Override
+    protected HandlingPriority getHandlingPriority() {
+        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
+    }
+
+    protected abstract Element handleWithNoSubsequentOperations(Document document, XmlElement operationElement) throws NetconfDocumentedException;
+}
index ba63646..2e3100f 100644 (file)
@@ -11,9 +11,9 @@ package org.opendaylight.controller.netconf.util.mapping;
 import java.util.Map;
 
 import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
-import org.opendaylight.controller.netconf.api.NetconfOperationRouter;
 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.controller.netconf.mapping.api.NetconfOperation;
+import org.opendaylight.controller.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
@@ -64,19 +64,34 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
                 XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
     }
 
-    protected abstract HandlingPriority canHandle(String operationName, String netconfOperationNamespace);
+    protected HandlingPriority canHandle(String operationName, String operationNamespace) {
+        return operationName.equals(getOperationName()) && operationNamespace.equals(getOperationNamespace())
+                ? getHandlingPriority()
+                : HandlingPriority.CANNOT_HANDLE;
+    }
+
+    protected HandlingPriority getHandlingPriority() {
+        return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
+    }
+
+    protected String getOperationNamespace() {
+        return XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0;
+    }
+
+    protected abstract String getOperationName();
 
     @Override
-    public final Document handle(Document message, NetconfOperationRouter opRouter) throws NetconfDocumentedException {
+    public Document handle(Document requestMessage,
+            NetconfOperationChainedExecution subsequentOperation) throws NetconfDocumentedException {
 
-        XmlElement requestElement = getRequestElementWithCheck(message);
+        XmlElement requestElement = getRequestElementWithCheck(requestMessage);
 
         Document document = XmlUtil.newDocument();
 
         XmlElement operationElement = requestElement.getOnlyChildElement();
         Map<String, Attr> attributes = requestElement.getAttributes();
 
-        Element response = handle(document, operationElement, opRouter);
+        Element response = handle(document, operationElement, subsequentOperation);
         Element rpcReply = document.createElementNS(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0,
                 XmlNetconfConstants.RPC_REPLY_KEY);
 
@@ -98,11 +113,16 @@ public abstract class AbstractNetconfOperation implements NetconfOperation {
         return document;
     }
 
-    protected abstract Element handle(Document document, XmlElement operationElement, NetconfOperationRouter opRouter)
+    protected abstract Element handle(Document document, XmlElement message, NetconfOperationChainedExecution subsequentOperation)
             throws NetconfDocumentedException;
 
     @Override
     public String toString() {
-        return getClass() + "{" + netconfSessionIdForReporting + '}';
+        final StringBuffer sb = new StringBuffer("AbstractConfigNetconfOperation{");
+        sb.append("name=").append(getOperationName());
+        sb.append(", namespace=").append(getOperationNamespace());
+        sb.append(", session=").append(netconfSessionIdForReporting);
+        sb.append('}');
+        return sb.toString();
     }
 }
diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/mapping/AbstractSingletonNetconfOperation.java
new file mode 100644 (file)
index 0000000..4491e76
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.util.mapping;
+
+import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
+
+public abstract class AbstractSingletonNetconfOperation extends AbstractLastNetconfOperation {
+
+    protected AbstractSingletonNetconfOperation(String netconfSessionIdForReporting) {
+        super(netconfSessionIdForReporting);
+    }
+
+    @Override
+    protected HandlingPriority getHandlingPriority() {
+        return HandlingPriority.HANDLE_WITH_MAX_PRIORITY;
+    }
+
+}
index 3247e0f..02ced96 100644 (file)
@@ -21,7 +21,7 @@ public final class XMLNetconfUtil {
         final XPathFactory xPathfactory = XPathFactory.newInstance();
         final XPath xpath = xPathfactory.newXPath();
         xpath.setNamespaceContext(new HardcodedNamespaceResolver("netconf",
-                XmlNetconfConstants.RFC4741_TARGET_NAMESPACE));
+                XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0));
         try {
             return xpath.compile(xPath);
         } catch (final XPathExpressionException e) {
index 4a6586c..c9f3a8a 100644 (file)
@@ -38,10 +38,7 @@ public final class XmlNetconfConstants {
     public static final String PREFIX = "prefix";
 
     //
-    //
-    public static final String RFC4741_TARGET_NAMESPACE = "urn:ietf:params:xml:ns:netconf:base:1.0";
     public static final String URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0 = "urn:ietf:params:xml:ns:netconf:base:1.0";
-
     public static final String URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
     // TODO where to store namespace of config ?
     public static final String URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG = "urn:opendaylight:params:xml:ns:yang:controller:config";
index 821ac92..f539f1c 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 27588b8..b25e99e 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>
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 47bb3ff..4393b79 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 7590a97..774a125 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 b29ce15..548bfb1 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 0208cc7..f972ae6 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 dc34162..6b303f0 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 a2b1278..e5e0a09 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 cc1a8b8..ff1c026 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 a118ccf..e4bb790 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 ccd0786..e388299 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>

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.