</build>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
package org.opendaylight.controller.arphandler.internal;\r
\r
\r
-import junit.framework.TestCase;\r
-\r
import org.junit.Assert;\r
import org.junit.Test;\r
\r
-public class ArphandlerTest extends TestCase {\r
+public class ArphandlerTest {\r
\r
@Test\r
public void testArphandlerCreation() {\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
mavenBundle("org.opendaylight.controller", "sal").versionAsInProject(),\r
mavenBundle("org.opendaylight.controller",\r
"sal.implementation").versionAsInProject(),\r
+ mavenBundle("org.opendaylight.controller", "configuration").versionAsInProject(),\r
mavenBundle("org.opendaylight.controller", "containermanager").versionAsInProject(),\r
mavenBundle("org.opendaylight.controller",\r
"containermanager.it.implementation").versionAsInProject(),\r
assertNotNull(bc);\r
boolean debugit = false;\r
Bundle b[] = bc.getBundles();\r
- for (int i = 0; i < b.length; i++) {\r
- int state = b[i].getState();\r
+ for (Bundle element : b) {\r
+ int state = element.getState();\r
if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {\r
- log.debug("Bundle:" + b[i].getSymbolicName() + " state:"\r
+ log.debug("Bundle:" + element.getSymbolicName() + " state:"\r
+ stateToString(state));\r
debugit = true;\r
}\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jboss.jbossts.jta</groupId>
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Enumeration;
private ViewChangedListener cacheManagerListener;
private static String loopbackAddress = InetAddress.getLoopbackAddress().getHostAddress();
-
+ private static final int gossipRouterPortDefault = 12001;
// defaultTransactionTimeout is 60 seconds
private static int DEFAULT_TRANSACTION_TIMEOUT = 60;
*/
private GossipRouter startGossiper() {
boolean amIGossipRouter = false;
- Integer gossipRouterPortDefault = 12001;
Integer gossipRouterPort = gossipRouterPortDefault;
InetAddress gossipRouterAddress = null;
String supernodes_list = System.getProperty("supernodes",
loopbackAddress);
+ /*
+ * Check the environment for the "container" variable, if this is set
+ * and is equal to "lxc", then ODL is running inside an lxc
+ * container, and address resolution of supernodes will be modified
+ * accordingly.
+ */
+ boolean inContainer = "lxc".equals(System.getenv("container"));
StringBuffer sanitized_supernodes_list = new StringBuffer();
List<InetAddress> myAddresses = new ArrayList<InetAddress>();
+ if (inContainer) {
+ logger.trace("DOCKER: Resolving supernode host names using docker container semantics");
+ }
+
StringTokenizer supernodes = new StringTokenizer(supernodes_list, ":");
if (supernodes.hasMoreTokens()) {
// Populate the list of my addresses
}
host = host_port.nextToken();
InetAddress hostAddr;
+ /*
+ * If we are in a container and the hostname begins with a '+', this is
+ * an indication that we should resolve this host name in the context
+ * of a docker container.
+ *
+ * Specifically this means:
+ * '+self' : self reference and the host will be mapped to the value of
+ * HOSTNAME in the environment
+ * '+<name>' : references another container by its name. The docker established
+ * environment variables will be used to resolve the host to an
+ * IP address.
+ */
+ if (inContainer && host != null && host.charAt(0) == '+') {
+ if ("+self".equals(host)) {
+ host = System.getenv("HOSTNAME");
+ } else {
+ String link = System.getenv(host.substring(1).toUpperCase() + "_PORT");
+ if (link != null) {
+ try {
+ host = new URI(link).getHost();
+ } catch (URISyntaxException e) {
+ logger.error("DOCKER: Unable to translate container reference ({}) to host IP Address, will attempt using normal host name",
+ host.substring(1));
+ }
+ }
+ }
+ }
+
try {
hostAddr = InetAddress.getByName(host);
} catch (UnknownHostException ue) {
- logger.error("Host not known");
+ logger.error("Host {} is not known", host);
continue;
}
if (host_port.hasMoreTokens()) {
try {
port_num = Integer.valueOf(port);
} catch (NumberFormatException ne) {
- logger
- .error("Supplied supernode gossiepr port is not recognized, using standard gossipport");
+ logger.error("Supplied supernode gossip port is not recognized, using default gossip port {}",
+ gossipRouterPortDefault);
port_num = gossipRouterPortDefault;
}
if ((port_num > 65535) || (port_num < 0)) {
- logger
- .error("Supplied supernode gossip port is outside a valid TCP port range");
+ logger.error("Supplied supernode gossip port is outside a valid TCP port range");
port_num = gossipRouterPortDefault;
}
}
if (!sanitized_supernodes_list.toString().equals("")) {
sanitized_supernodes_list.append(",");
}
- sanitized_supernodes_list.append(hostAddr.getHostAddress() + "["
- + port_num + "]");
+ sanitized_supernodes_list.append(hostAddr.getHostAddress()).append("[").append(port_num).append("]");
}
if (amIGossipRouter) {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
import org.junit.Assert;\r
import org.junit.Test;\r
\r
-import junit.framework.TestCase;\r
-\r
-public class TestClusteringTest extends TestCase {\r
+public class TestClusteringTest {\r
\r
@Test\r
public void testComplexClass() {\r
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.console</artifactId>
- <version>1.0.0.v20120522-1841</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.util</artifactId>
- <version>1.0.400.v20120522-2049</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
- <version>3.3.100.v20120522-1822</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.ds</artifactId>
- <version>1.4.0.v20120522-1841</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.command</artifactId>
- <version>0.8.0.v201108120515</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.runtime</artifactId>
- <version>0.8.0.v201108120515</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.shell</artifactId>
- <version>0.8.0.v201110170705</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<ietf-inet-types.version>2010.09.24.2-SNAPSHOT</ietf-inet-types.version>
<ietf-yang-types.version>2010.09.24.2-SNAPSHOT</ietf-yang-types.version>
<ietf-topology.version>2013.10.21.0-SNAPSHOT</ietf-topology.version>
- <opendaylight-l2-types.version>2013.08.27.1</opendaylight-l2-types.version>
- <yang-ext.version>2013.09.07.1</yang-ext.version>
+ <opendaylight-l2-types.version>2013.08.27.2-SNAPSHOT</opendaylight-l2-types.version>
+ <yang-ext.version>2013.09.07.2-SNAPSHOT</yang-ext.version>
<javassist.version>3.17.1-GA</javassist.version>
<sample-toaster.version>1.0-SNAPSHOT</sample-toaster.version>
<releaseplugin.version>2.3.2</releaseplugin.version>
<yangtools.version>0.6.0-SNAPSHOT</yangtools.version>
<!--versions for bits of the controller -->
<controller.version>0.4.1-SNAPSHOT</controller.version>
- <hosttracker.version>0.5.1-SNAPSHOT</hosttracker.version>
+ <hosttracker.api.version>0.5.1-SNAPSHOT</hosttracker.api.version>
+ <hosttracker_new.api.version>0.4.1-SNAPSHOT</hosttracker_new.api.version>
+ <hosttracker.implementation.version>0.5.1-SNAPSHOT</hosttracker.implementation.version>
<arphandler.version>0.5.1-SNAPSHOT</arphandler.version>
<forwarding.staticrouting>0.5.1-SNAPSHOT</forwarding.staticrouting>
<samples.loadbalancer>0.5.1-SNAPSHOT</samples.loadbalancer>
<netconf.version>0.2.3-SNAPSHOT</netconf.version>
<mdsal.version>1.0-SNAPSHOT</mdsal.version>
<containermanager.version>0.5.1-SNAPSHOT</containermanager.version>
+ <containermanager.it.version>0.5.1-SNAPSHOT</containermanager.it.version>
<switchmanager.api.version>0.7.0-SNAPSHOT</switchmanager.api.version>
<connectionmanager.version>0.1.1-SNAPSHOT</connectionmanager.version>
<sal.version>0.7.0-SNAPSHOT</sal.version>
<commons.httpclient.version>0.1.1-SNAPSHOT</commons.httpclient.version>
<concepts.version>0.5.1-SNAPSHOT</concepts.version>
<protocol-framework.version>0.4.0-SNAPSHOT</protocol-framework.version>
- <jolokia.bridge.version>0.0.1-SNAPSHOT</jolokia.bridge.version>
<netty.version>4.0.10.Final</netty.version>
<commons.io.version>2.4</commons.io.version>
<bundlescanner.version>0.4.1-SNAPSHOT</bundlescanner.version>
<clustering.services.version>0.5.0-SNAPSHOT</clustering.services.version>
<configuration.version>0.4.1-SNAPSHOT</configuration.version>
<topologymanager.version>0.4.1-SNAPSHOT</topologymanager.version>
+ <protocol_plugin.stub.version>0.4.1-SNAPSHOT</protocol_plugin.stub.version>
+ <clustering.stub.version>0.4.1-SNAPSHOT</clustering.stub.version>
<!-- Third party version -->
- <jersey-servlet.version>1.18-SNAPSHOT</jersey-servlet.version>
- <corsfilter.version>7.0.43-SNAPSHOT</corsfilter.version>
+ <jersey-servlet.version>1.17</jersey-servlet.version>
+ <corsfilter.version>7.0.42</corsfilter.version>
<!-- Northbound API version -->
<commons.northbound.version>0.4.1-SNAPSHOT</commons.northbound.version>
<!-- Sonar properties using jacoco to retrieve integration test results -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>2.1</version>
- <scope>compile</scope>
+ <version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>protocol-framework</artifactId>
<version>${protocol-framework.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>concepts</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
<!--Netty-->
<dependency>
<artifactId>yang-model-api</artifactId>
<version>${yangtools.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker</artifactId>
+ <version>${hosttracker.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker.implementation</artifactId>
+ <version>${hosttracker.implementation.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker_new</artifactId>
+ <version>${hosttracker_new.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwarding.staticrouting</artifactId>
+ <version>${forwarding.staticrouting}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services</artifactId>
+ <version>${clustering.services.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.services-implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.stub</artifactId>
+ <version>${clustering.stub.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>routing.dijkstra_implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>arphandler</artifactId>
+ <version>${arphandler.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager</artifactId>
+ <version>${containermanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager.implementation</artifactId>
+ <version>${containermanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager.it.implementation</artifactId>
+ <version>${containermanager.it.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>appauth</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
<version>${switchmanager.api.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>concepts</artifactId>
- <version>${yangtools.version}</version>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>statisticsmanager</artifactId>
+ <version>${statisticsmanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>statisticsmanager.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topologymanager</artifactId>
+ <version>${topologymanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager</artifactId>
+ <version>${usermanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager.implementation</artifactId>
+ <version>${usermanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>connectionmanager</artifactId>
+ <version>${connectionmanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>connectionmanager.implementation</artifactId>
+ <version>${connectionmanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>security</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwardingrulesmanager</artifactId>
+ <version>${forwardingrulesmanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwardingrulesmanager.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+
+ <!-- SAL bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ <version>${sal.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+
+ <!-- SAL Extension bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal.connection</artifactId>
+ <version>${sal.connection.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal.connection.implementation</artifactId>
+ <version>${sal.connection.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal.networkconfiguration</artifactId>
+ <version>${sal.networkconfiguration.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal.networkconfiguration.implementation</artifactId>
+ <version>${sal.networkconfiguration.version}</version>
+ </dependency>
+
+ <!-- Web bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>web</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>flows.web</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>devices.web</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>troubleshoot.web</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topology.web</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>osgi-brandfragment.web</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+
+ <!-- Neutron -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.neutron</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.neutron.implementation</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.neutron.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+
+ <!-- Northbound bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>bundlescanner</artifactId>
+ <version>${bundlescanner.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>bundlescanner.implementation</artifactId>
+ <version>${bundlescanner.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>topology.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>forwarding.staticrouting.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>statistics.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>flowprogrammer.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>hosttracker.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>subnets.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>switchmanager.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>containermanager.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>networkconfig.bridgedomain.northbound</artifactId>
+ <version>${networkconfig.bridgedomain.northbound.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>httpservice-bridge</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>jolokia-bridge</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>connectionmanager.northbound</artifactId>
+ <version>${connectionmanager.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>usermanager.northbound</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>controllermanager.northbound</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ </dependency>
+ <!-- Debug and logging -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>logging.bridge</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+
+ <!-- Southbound bundles -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>protocol_plugins.openflow</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>protocol_plugins.stub</artifactId>
+ <version>${protocol_plugin.stub.version}</version>
+ </dependency>
+
+ <!-- samples -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>samples.loadbalancer</artifactId>
+ <version>${samples.loadbalancer}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>samples.loadbalancer.northbound</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>samples.simpleforwarding</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+
+ <!-- testing dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.test</artifactId>
+ <version>${controller.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>commons.httpclient</artifactId>
+ <version>${commons.httpclient.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sanitytest</artifactId>
+ <version>${controller.version}</version>
</dependency>
<!-- equinox http service bridge -->
<version>0.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.codehaus.enunciate</groupId>
+ <artifactId>enunciate-core-annotations</artifactId>
+ <version>${enunciate.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
try {
startNegotiation();
} catch (Exception e) {
- logger.info("Unexpected negotiation failure", e);
+ logger.warn("Unexpected negotiation failure", e);
negotiationFailed(e);
}
}
try {
handleMessage((M)msg);
} catch (Exception e) {
- logger.debug("Unexpected exception during negotiation", e);
+ logger.debug("Unexpected error while handling negotiation message {}", msg, e);
negotiationFailed(e);
}
}
+
+ @Override
+ public void exceptionCaught(final ChannelHandlerContext ctx, final Throwable cause) {
+ logger.info("Unexpected error during negotiation", cause);
+ negotiationFailed(cause);
+ }
}
}
if (!cf.isSuccess()) {
- LOG.info("Attempt to connect to connect to {} failed", ProtocolSessionPromise.this.address, cf.cause());
+ LOG.warn("Attempt to connect to connect to {} failed", ProtocolSessionPromise.this.address, cf.cause());
final Future<Void> rf = ProtocolSessionPromise.this.strategy.scheduleReconnect(cf.cause());
rf.addListener(new FutureListener<Void>() {
@Override
throws ConflictingVersionException, ValidationException {
final String transactionName = ObjectNameUtil
.getTransactionName(transactionControllerON);
- logger.info("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
+ logger.trace("About to commit {}. Current parentVersion: {}, versionCounter {}", transactionName, version, versionCounter);
// find ConfigTransactionController
Map<String, ConfigTransactionControllerInternal> transactions = transactionsHolder.getCurrentTransactions();
private void validate_noLocks() throws ValidationException {
transactionStatus.checkNotAborted();
- logger.info("Validating transaction {}", getTransactionIdentifier());
+ logger.trace("Validating transaction {}", getTransactionIdentifier());
// call validate()
List<ValidationException> collectedExceptions = new ArrayList<>();
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
throw ValidationException
.createFromCollectedValidationExceptions(collectedExceptions);
}
- logger.info("Validated transaction {}", getTransactionIdentifier());
+ logger.trace("Validated transaction {}", getTransactionIdentifier());
}
/**
try {
validate_noLocks();
} catch (ValidationException e) {
- logger.info("Commit failed on validation");
+ logger.trace("Commit failed on validation");
configBeanModificationDisabled.set(false); // recoverable error
throw e;
}
+ "to obtain a lock");
}
- logger.info("Committing transaction {}", getTransactionIdentifier());
+ logger.trace("Committing transaction {}", getTransactionIdentifier());
// call getInstance()
for (Entry<ModuleIdentifier, Module> entry : dependencyResolverManager
// count dependency order
- logger.info("Committed configuration {}", getTransactionIdentifier());
+ logger.trace("Committed configuration {}", getTransactionIdentifier());
transactionStatus.setCommitted();
// unregister this and all modules from jmx
close();
@Override
public void close() {
- logger.info("Destroying {}", identifier);
+ logger.trace("Destroying {}", identifier);
try {
instance.close();
} catch (Exception e) {
when "/config:modules/config:module/config:type = 'logback'";
list file-appenders {
- leaf append {
+ leaf append {
type boolean;
mandatory false;
}
type string;
mandatory true;
}
-
+
leaf encoder-pattern {
type string;
mandatory true;
}
-
+
leaf name {
type string;
mandatory true;
key name;
config:java-name-prefix FileAppenderTO;
}
-
+
list rolling-appenders {
leaf append {
type boolean;
type string;
mandatory true;
}
-
+
leaf rolling-policy-type {
type string;
mandatory true;
}
-
+
leaf max-history {
type int32;
mandatory true;
}
-
+
leaf clean-history-on-start {
type boolean;
default false;
// vi: set smarttab et sw=4 tabstop=4:
module netty {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netty";
- prefix "netty";
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:netty";
+ prefix "netty";
- import config { prefix config; revision-date 2013-04-05; }
+ import config { prefix config; revision-date 2013-04-05; }
- organization "Cisco Systems, Inc.";
+ organization "Cisco Systems, Inc.";
- contact "Milos Fabian <milfabia@cisco.com>";
+ contact "Milos Fabian <milfabia@cisco.com>";
description
"This module contains the base YANG definitions for
Copyright (c)2013 Cisco Systems, Inc. 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";
+ 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";
revision "2013-11-19" {
description
"Initial revision.";
}
-
+
identity netty-threadgroup {
description
"Configuration wrapper around netty's threadgroup";
base "config:service-type";
config:java-class "io.netty.channel.EventLoopGroup";
}
-
+
identity netty-event-executor {
description
"Configuration wrapper around netty's event executor";
base "config:service-type";
config:java-class "io.netty.util.concurrent.EventExecutor";
}
-
+
identity netty-timer {
description
"Configuration wrapper around netty's timer";
base "config:service-type";
- config:java-class "io.netty.util.Timer";
+ config:java-class "io.netty.util.Timer";
}
}
\ No newline at end of file
// vi: set smarttab et sw=4 tabstop=4:
module netty-event-executor {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor";
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor";
prefix "netty-ee";
import config { prefix config; revision-date 2013-04-05; }
netty event executor implementation.
Copyright (c)2013 Cisco Systems, Inc. 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";
+ 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";
revision "2013-11-12" {
description
"Initial revision";
}
-
+
identity netty-global-event-executor {
base config:module-type;
config:provided-service netty:netty-event-executor;
// vi: set smarttab et sw=4 tabstop=4:
module threadgroup {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup";
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup";
prefix "netty-th";
import config { prefix config; revision-date 2013-04-05; }
}
}
-
}
// vi: set smarttab et sw=4 tabstop=4:
module netty-timer {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:timer";
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:netty:timer";
prefix "netty-timer";
import config { prefix config; revision-date 2013-04-05; }
netty timer implementation.
Copyright (c)2013 Cisco Systems, Inc. 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";
+ 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";
revision "2013-11-19" {
description
"Initial revision";
}
-
+
identity netty-hashed-wheel-timer {
base config:module-type;
config:provided-service netty:netty-timer;
augment "/config:modules/config:module/config:configuration" {
case netty-hashed-wheel-timer {
when "/config:modules/config:module/config:type = 'netty-hashed-wheel-timer'";
-
+
leaf tick-duration {
type uint32;
}
-
+
leaf ticks-per-wheel {
type uint16;
}
-
- container thread-factory {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity th:threadfactory;
- }
- }
- }
+
+ container thread-factory {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity th:threadfactory;
+ }
+ }
+ }
}
}
}
\ No newline at end of file
<goal>report</goal>
</goals>
<configuration>
- <outputDirectory>${basedir}/target/jacoco</outputDirectory>
+ <outputDirectory>${project.build.directory}/jacoco</outputDirectory>
<haltOnFailure>false</haltOnFailure>
<check>
<classRatio>80</classRatio>
</generator>
<generator>
<codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>target/site/models</outputBaseDir>
+ <outputBaseDir>${project.build.directory}/site/models</outputBaseDir>
</generator>
</codeGenerators>
<inspectDependencies>true</inspectDependencies>
logger.warn("Thread dump:{}", sb);
System.exit(1);
} catch (InterruptedException e) {
- logger.info("Interrupted, not going to call System.exit(1)");
+ logger.warn("Interrupted, not going to call System.exit(1)");
}
}
}
// vi: set smarttab et sw=4 tabstop=4:
module threadpool {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:threadpool";
- prefix "th";
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:threadpool";
+ prefix "th";
- import config { prefix config; revision-date 2013-04-05; }
+ import config { prefix config; revision-date 2013-04-05; }
- organization "Cisco Systems, Inc.";
+ organization "Cisco Systems, Inc.";
- contact "Robert Varga <rovarga@cisco.com>";
+ contact "Robert Varga <rovarga@cisco.com>";
description
"This module contains the base YANG definitions for
Copyright (c)2013 Cisco Systems, Inc. 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";
+ 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";
revision "2013-04-09" {
description
config:java-class "java.util.concurrent.ThreadFactory";
}
- identity threadpool {
+ identity threadpool {
description
"A simple pool of threads able to execute work.";
- base "config:service-type";
+ base "config:service-type";
config:java-class "org.opendaylight.controller.config.threadpool.ThreadPool";
- }
+ }
- identity scheduled-threadpool {
+ identity scheduled-threadpool {
description
"An extension of the simple pool of threads able to schedule
work to be executed at some point in time.";
- base "threadpool";
+ base "threadpool";
config:java-class "org.opendaylight.controller.config.threadpool.ScheduledThreadPool";
- }
+ }
}
description
"This module contains the base YANG definitions for
- thread services pure Java implementation.
+ thread services pure Java implementation.
Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
description
"This module contains the base YANG definitions for
- thread services pure Java implementation.
+ thread services pure Java implementation.
Copyright (c)2013 Cisco Systems, Inc. All rights reserved.;
pathToFile.mkdirs();
}
if (targetFile.exists() && overwrite == false) {
- logger.info("Skipping {} since it already exists", targetFile);
+ logger.trace("Skipping {} since it already exists", targetFile);
} else {
try (Writer fileWriter = new FileWriter(targetFile)) {
fileWriter.write(entry.getValue());
}
- logger.info("{}: File {} generated successfully",
+ logger.trace("{}: File {} generated successfully",
JMXGenerator.class.getCanonicalName(), targetFile);
result.add(targetFile);
}
*/
package org.opendaylight.controller.config.yang.store.api;
-import java.util.Map;
-import java.util.Map.Entry;
-
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.Module;
+import java.util.Map;
+import java.util.Set;
+
public interface YangStoreSnapshot extends AutoCloseable {
+ /**
+ * @deprecated Use {@link #getQNamesToIdentitiesToModuleMXBeanEntries()} instead. This method return only one
+ * module representation even if multiple revisions are available.
+ */
+ @Deprecated
Map<String/* Namespace from yang file */,
Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> getModuleMXBeanEntryMap();
- Map<String, Entry<Module, String>> getModuleMap();
+ Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries();
+
+ /**
+ * Get number of parsed ModuleMXBeanEntry instances.
+ */
int countModuleMXBeanEntries();
+ /**
+ * Get all modules discovered when this snapshot was created.
+ * @return all modules discovered. If one module exists with two different revisions, return both.
+ */
+ Set<Module> getModules();
+
+ /**
+ * Get all modules together with their yang sources.
+ */
+ Map<Module, String> getModulesToSources();
+
+ /**
+ * Retrieve source of module as it appeared during creation of this snapshot.
+ * @param module
+ * @return yang source of given module
+ * @throws java.lang.IllegalArgumentException if module does not belong to this snapshot
+ */
+ String getModuleSource(Module module);
+
@Override
void close();
}
import com.google.common.collect.Collections2;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
import org.opendaylight.controller.config.yang.store.api.YangStoreException;
import org.opendaylight.controller.config.yang.store.api.YangStoreService;
import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
-import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
-import org.opendaylight.yangtools.yang.model.api.Module;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
updateCache(snapshot);
cache.setInconsistentURLsForReporting(Collections.<URL> emptySet());
- logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
+ logger.trace("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size());
logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs);
}
cache.invalidate();
}
}
-
-class YangStoreCache {
- private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class);
-
- @GuardedBy("this")
- private Set<URL> cachedUrls = null;
- @GuardedBy("this")
- private Optional<YangStoreSnapshot> cachedYangStoreSnapshot = getInitialSnapshot();
- @GuardedBy("this")
- private Collection<URL> inconsistentURLsForReporting = Collections.emptySet();
-
- synchronized Optional<YangStoreSnapshot> getSnapshotIfPossible(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
-
- if (cachedUrls==null || cachedUrls.equals(urls)) {
- Preconditions.checkState(cachedYangStoreSnapshot.isPresent());
- YangStoreSnapshot freshSnapshot = new YangStoreSnapshotImpl(cachedYangStoreSnapshot.get());
- if (inconsistentURLsForReporting.size() > 0){
- logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting);
- }
- return Optional.of(freshSnapshot);
- }
-
- return Optional.absent();
- }
-
- private static Set<URL> setFromMultimapValues(
- Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
- Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
- return urls;
- }
-
- synchronized void cacheYangStore(Multimap<Bundle, URL> urls,
- YangStoreSnapshot yangStoreSnapshot) {
- this.cachedUrls = setFromMultimapValues(urls);
- this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot);
- }
-
- synchronized void invalidate() {
- cachedUrls.clear();
- if (cachedYangStoreSnapshot.isPresent()){
- cachedYangStoreSnapshot.get().close();
- cachedYangStoreSnapshot = Optional.absent();
- }
- }
-
- public synchronized void setInconsistentURLsForReporting(Collection<URL> urls){
- inconsistentURLsForReporting = urls;
- }
-
- private Optional<YangStoreSnapshot> getInitialSnapshot() {
- YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() {
- @Override
- public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
- return Collections.emptyMap();
- }
-
- @Override
- public Map<String, Map.Entry<Module, String>> getModuleMap() {
- return Collections.emptyMap();
- }
-
- @Override
- public int countModuleMXBeanEntries() {
- return 0;
- }
-
- @Override
- public void close() {
- }
- };
- return Optional.of(initialSnapshot);
- }
-}
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class MbeParser {
+ private static final Logger logger = LoggerFactory.getLogger(MbeParser.class);
- public YangStoreSnapshotImpl parseYangFiles(
- Collection<? extends InputStream> allInput)
- throws YangStoreException {
+ public YangStoreSnapshotImpl parseYangFiles(Collection<? extends InputStream> allInput) throws YangStoreException {
YangParserImpl parser = YangParserWrapper.getYangParserInstance();
Map<InputStream, Module> allYangModules = YangParserWrapper.parseYangFiles(parser, allInput);
SchemaContext resolveSchemaContext = YangParserWrapper.getSchemaContextFromModules(parser, allYangModules);
-
+ logger.trace("Resolved modules:{}", resolveSchemaContext.getModules());
// JMX generator
Map<String, String> namespaceToPackageMapping = Maps.newHashMap();
}
}
- Map<String, Map<String, ModuleMXBeanEntry>> retVal = Maps.newHashMap();
- Map<String, Entry<Module, String>> modulesMap = new HashMap<>();
+ Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap = Maps.newHashMap();
+ Map<Module, String> modulesToSources = new HashMap<>();
+ Map<QName, Map<String /* identity local name */, ModuleMXBeanEntry>>
+ qNamesToIdentitiesToModuleMXBeanEntries = new HashMap<>();
+
for (Entry<InputStream, Module> moduleEntry : allYangModules.entrySet()) {
- String packageName = packageTranslator.getPackageName(moduleEntry
- .getValue());
+ Module module = moduleEntry.getValue();
+ String packageName = packageTranslator.getPackageName(module);
TypeProviderWrapper typeProviderWrapper = new TypeProviderWrapper(
new TypeProviderImpl(resolveSchemaContext));
- String yangAsString;
- try {
- moduleEntry.getKey().reset();
- yangAsString = IOUtils.toString(moduleEntry.getKey());
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- modulesMap.put(moduleEntry.getValue().getName(),
- Maps.immutableEntry(moduleEntry.getValue(), yangAsString));
- Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs = ModuleMXBeanEntry
- .create(moduleEntry.getValue(), qNamesToSIEs, resolveSchemaContext, typeProviderWrapper,
- packageName);
- retVal.put(moduleEntry.getValue().getNamespace().toString(),
- namesToMBEs);
+ String yangAsString = reReadInputStream(moduleEntry);
+
+ QName qName = new QName(module.getNamespace(), module.getRevision(), module.getName());
+
+ Map<String /* MB identity local name */, ModuleMXBeanEntry> namesToMBEs =
+ Collections.unmodifiableMap(ModuleMXBeanEntry.create(module, qNamesToSIEs, resolveSchemaContext,
+ typeProviderWrapper, packageName));
+ moduleMXBeanEntryMap.put(module.getNamespace().toString(), namesToMBEs);
+ modulesToSources.put(module, yangAsString);
+ qNamesToIdentitiesToModuleMXBeanEntries.put(qName, namesToMBEs);
}
- return new YangStoreSnapshotImpl(retVal, modulesMap);
+ return new YangStoreSnapshotImpl(moduleMXBeanEntryMap, modulesToSources, qNamesToIdentitiesToModuleMXBeanEntries);
+ }
+
+ private String reReadInputStream(Entry<InputStream, Module> moduleEntry) {
+ String yangAsString;
+ try {
+ moduleEntry.getKey().reset();
+ yangAsString = IOUtils.toString(moduleEntry.getKey());
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot reread " + moduleEntry.getValue(), e);
+ }
+ return yangAsString;
}
- public Map<Module, String> parseYangFilesToString(
- Collection<? extends InputStream> allYangs) {
+ @Deprecated
+ public Map<Module, String> parseYangFilesToString(Collection<? extends InputStream> allYangs) {
+
+ logger.error("Using deprecated method that will be removed soon", new UnsupportedOperationException("Deprecated"));
YangParserImpl parser = YangParserWrapper.getYangParserInstance();
Map<InputStream, Module> allYangModules = parser
--- /dev/null
+package org.opendaylight.controller.config.yang.store.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
+import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.osgi.framework.Bundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.concurrent.GuardedBy;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+class YangStoreCache {
+ private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class);
+
+ @GuardedBy("this")
+ private Set<URL> cachedUrls = null;
+ @GuardedBy("this")
+ private Optional<YangStoreSnapshot> cachedYangStoreSnapshot = getInitialSnapshot();
+ @GuardedBy("this")
+ private Collection<URL> inconsistentURLsForReporting = Collections.emptySet();
+
+ synchronized Optional<YangStoreSnapshot> getSnapshotIfPossible(Multimap<Bundle, URL> bundlesToYangURLs) {
+ Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
+
+ if (cachedUrls==null || cachedUrls.equals(urls)) {
+ Preconditions.checkState(cachedYangStoreSnapshot.isPresent());
+ YangStoreSnapshot freshSnapshot = YangStoreSnapshotImpl.copy(cachedYangStoreSnapshot.get());
+ if (inconsistentURLsForReporting.size() > 0){
+ logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting);
+ }
+ return Optional.of(freshSnapshot);
+ }
+
+ return Optional.absent();
+ }
+
+ private static Set<URL> setFromMultimapValues(
+ Multimap<Bundle, URL> bundlesToYangURLs) {
+ Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
+ Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
+ return urls;
+ }
+
+ synchronized void cacheYangStore(Multimap<Bundle, URL> urls,
+ YangStoreSnapshot yangStoreSnapshot) {
+ this.cachedUrls = setFromMultimapValues(urls);
+ this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot);
+ }
+
+ synchronized void invalidate() {
+ cachedUrls.clear();
+ if (cachedYangStoreSnapshot.isPresent()){
+ cachedYangStoreSnapshot.get().close();
+ cachedYangStoreSnapshot = Optional.absent();
+ }
+ }
+
+ public synchronized void setInconsistentURLsForReporting(Collection<URL> urls){
+ inconsistentURLsForReporting = urls;
+ }
+
+ private Optional<YangStoreSnapshot> getInitialSnapshot() {
+ YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() {
+ @Override
+ public Map<String, Map<String, ModuleMXBeanEntry>> getModuleMXBeanEntryMap() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Set<Module> getModules() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Map<Module, String> getModulesToSources() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public String getModuleSource(Module module) {
+ throw new IllegalArgumentException("Cannot get sources in empty snapshot");
+ }
+
+ @Override
+ public int countModuleMXBeanEntries() {
+ return 0;
+ }
+
+ @Override
+ public void close() {
+ }
+ };
+ return Optional.of(initialSnapshot);
+ }
+}
import org.opendaylight.controller.config.yang.store.api.YangStoreSnapshot;
import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.Module;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.Map;
-import java.util.Map.Entry;
+import java.util.Set;
public class YangStoreSnapshotImpl implements YangStoreSnapshot {
+ private static final Logger logger = LoggerFactory.getLogger(YangStoreSnapshotImpl.class);
+ @Deprecated
private final Map<String /* Namespace from yang file */,
Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> moduleMXBeanEntryMap;
- private final Map<String, Entry<Module, String>> moduleMap;
+ private final Map<Module, String> modulesToSources;
+ private final Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries;
+
+ public YangStoreSnapshotImpl(Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap,
+ Map<Module, String> modulesToSources,
+ Map<QName, Map<String, ModuleMXBeanEntry>> qNamesToIdentitiesToModuleMXBeanEntries) {
- public YangStoreSnapshotImpl(
- Map<String, Map<String, ModuleMXBeanEntry>> moduleMXBeanEntryMap,
- Map<String, Entry<Module, String>> moduleMap) {
this.moduleMXBeanEntryMap = Collections.unmodifiableMap(moduleMXBeanEntryMap);
- this.moduleMap = Collections.unmodifiableMap(moduleMap);
+ this.modulesToSources = Collections.unmodifiableMap(modulesToSources);
+ this.qNamesToIdentitiesToModuleMXBeanEntries = Collections.unmodifiableMap(qNamesToIdentitiesToModuleMXBeanEntries);
}
- public YangStoreSnapshotImpl(YangStoreSnapshot yangStoreSnapshot) {
- this.moduleMXBeanEntryMap = yangStoreSnapshot.getModuleMXBeanEntryMap();
- this.moduleMap = yangStoreSnapshot.getModuleMap();
+ public static YangStoreSnapshotImpl copy(YangStoreSnapshot yangStoreSnapshot) {
+ return new YangStoreSnapshotImpl(
+ yangStoreSnapshot.getModuleMXBeanEntryMap(),
+ yangStoreSnapshot.getModulesToSources(),
+ yangStoreSnapshot.getQNamesToIdentitiesToModuleMXBeanEntries());
}
/**
}
@Override
- public Map<String, Entry<Module, String>> getModuleMap() {
- return moduleMap;
+ public Map<QName, Map<String, ModuleMXBeanEntry>> getQNamesToIdentitiesToModuleMXBeanEntries() {
+ return qNamesToIdentitiesToModuleMXBeanEntries;
+ }
+
+ @Override
+ public Set<Module> getModules() {
+ return modulesToSources.keySet();
+ }
+
+ @Override
+ public String getModuleSource(Module module) {
+ String result = modulesToSources.get(module);
+ if (result == null) {
+ logger.trace("Cannot find module {} in {}", module, modulesToSources);
+ throw new IllegalArgumentException("Module not found in this snapshot:" + module);
+ }
+ return result;
+ }
+
+ @Override
+ public Map<Module, String> getModulesToSources() {
+ return modulesToSources;
}
@Override
import java.util.Map;
import java.util.regex.Pattern;
-import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyCollectionOf;
import static org.mockito.Mockito.doNothing;
doReturn(22).when(yangStoreSnapshot).countModuleMXBeanEntries();
doReturn("mock yang store").when(yangStoreSnapshot).toString();
doNothing().when(yangStoreSnapshot).close();
- doReturn(moduleMap).when(yangStoreSnapshot).getModuleMap();
doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModuleMXBeanEntryMap();
+ doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getModulesToSources();
+ doReturn(Collections.emptyMap()).when(yangStoreSnapshot).getQNamesToIdentitiesToModuleMXBeanEntries();
}
@Test
returnedStore = tested.getYangStoreSnapshot();
- assertEquals(yangStoreSnapshot.getModuleMap(), returnedStore.getModuleMap());
tested.removedBundle(bundle, null, null);
tested.getYangStoreSnapshot();
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/sal
+ ${project.build.directory}/generated-sources/sal
</outputBaseDir>
</generator>
</codeGenerators>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
--- /dev/null
+/*
+ * 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.configuration;
+
+import java.io.Serializable;
+
+public abstract class ConfigurationObject implements Serializable {
+ private static final long serialVersionUID = 1L;
+ private static final String DEFAULT_REGEX = "^[\\w-\\+\\*\\/\\.\\(\\)\\[\\]\\@]{1,256}$";
+ private static final String REGEX_PROP_NAME = "resourceNameRegularExpression";
+ private static String regex;
+
+ static {
+ String customRegex = System.getProperty(REGEX_PROP_NAME);
+ regex = (customRegex != null) ? customRegex : DEFAULT_REGEX;
+ }
+
+ /**
+ * Checks if the provided resource name matches the controller resource name
+ * regular expression
+ *
+ * @param name
+ * The resource name to test
+ * @return true if the resource name is not null and matches the controller
+ * resource name regular expression, false otherwise
+ */
+ protected boolean isValidResourceName(String name) {
+ return (name != null) ? name.matches(regex) : false;
+ }
+
+ /**
+ * Return the regular expression currently in use for testing the controller
+ * resource names
+ *
+ * @return The regular expression
+ */
+ public static String getRegularExpression() {
+ return regex;
+ }
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
Status status = configurationAware.saveConfiguration();
if (!status.isSuccess()) {
success = false;
- logger.info("Failed to save config for {}",
+ logger.warn("Failed to save config for {}",
configurationAware.getClass().getName());
}
}
public Status saveConfiguration() {
boolean success = true;
for (IConfigurationContainerAware configurationAware : configurationAwareList) {
- logger.info("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
+ logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
Status status = configurationAware.saveConfiguration();
if (!status.isSuccess()) {
success = false;
- logger.info("Failed to save config for {}", configurationAware.getClass().getSimpleName());
+ logger.warn("Failed to save config for {}", configurationAware.getClass().getSimpleName());
}
}
if (success) {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<configuration>
<instructions>
<Import-Package>
+ org.opendaylight.controller.configuration,
org.opendaylight.controller.sal.authorization,
org.opendaylight.controller.sal.utils,
org.opendaylight.controller.sal.core,
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>configuration</artifactId>
</dependency>
</dependencies>
</project>
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.sal.core.ContainerFlow;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.match.Match;
*/
@XmlRootElement(name = "containerConfig")
@XmlAccessorType(XmlAccessType.NONE)
-public class ContainerConfig implements Serializable {
+public class ContainerConfig extends ConfigurationObject implements Serializable {
private static final long serialVersionUID = 2L;
private static final String regexName = "^\\w+$";
private static final String containerProfile = System.getProperty("container.profile") == null ? "Container"
*/
private Status validateName() {
// No Container configuration allowed to container default
- return ((container != null) && container.matches(regexName) && !container.equalsIgnoreCase(GlobalConstants.DEFAULT.toString())) ?
+ return (isValidResourceName(container) && !container.equalsIgnoreCase(GlobalConstants.DEFAULT.toString())) ?
new Status(StatusCode.SUCCESS) : new Status(StatusCode.BADREQUEST, "Invalid container name");
}
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.packet.BitBufferHelper;
*/
@XmlRootElement (name = "flow-spec-config")
@XmlAccessorType(XmlAccessType.NONE)
-public class ContainerFlowConfig implements Serializable {
+public class ContainerFlowConfig extends ConfigurationObject implements Serializable {
private static Logger log = LoggerFactory.getLogger(ContainerFlowConfig.class);
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
- /** The Constant regexName. */
- private static final String regexName = "^[\\w-+.@]+$";
-
/** Flow Spec name. */
@XmlElement
private String name;
* @return true, if is valid
*/
public Status validate() {
- if (!hasValidName()) {
+ if (!isValidResourceName(name)) {
return new Status(StatusCode.BADREQUEST, "Invalid name");
}
Status status = validateVlan();
return new Status(StatusCode.SUCCESS);
}
- /**
- * Checks if this flow specification configuration has a valid name.
- *
- * @return true, if successful
- */
- private boolean hasValidName() {
- return (name != null && !name.isEmpty() && name.matches(regexName));
- }
-
/**
* Validates the vlan number
*
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>appauth</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-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>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
+import org.opendaylight.controller.appauth.authorization.Authorization;
import org.opendaylight.controller.clustering.services.CacheConfigException;
import org.opendaylight.controller.clustering.services.CacheExistException;
import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
import org.opendaylight.controller.clustering.services.IClusterServices;
import org.opendaylight.controller.configuration.IConfigurationAware;
import org.opendaylight.controller.configuration.IConfigurationService;
+import org.opendaylight.controller.containermanager.ContainerChangeEvent;
+import org.opendaylight.controller.containermanager.ContainerConfig;
+import org.opendaylight.controller.containermanager.ContainerData;
+import org.opendaylight.controller.containermanager.ContainerFlowChangeEvent;
+import org.opendaylight.controller.containermanager.ContainerFlowConfig;
import org.opendaylight.controller.containermanager.IContainerAuthorization;
import org.opendaylight.controller.containermanager.IContainerManager;
+import org.opendaylight.controller.containermanager.NodeConnectorsChangeEvent;
import org.opendaylight.controller.sal.authorization.AppRoleLevel;
import org.opendaylight.controller.sal.authorization.Privilege;
import org.opendaylight.controller.sal.authorization.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.opendaylight.controller.appauth.authorization.Authorization;
-import org.opendaylight.controller.containermanager.ContainerFlowChangeEvent;
-import org.opendaylight.controller.containermanager.ContainerFlowConfig;
-import org.opendaylight.controller.containermanager.NodeConnectorsChangeEvent;
-import org.opendaylight.controller.containermanager.ContainerChangeEvent;
-import org.opendaylight.controller.containermanager.ContainerConfig;
-import org.opendaylight.controller.containermanager.ContainerData;
-
public class ContainerManager extends Authorization<String> implements IContainerManager, IObjectReader,
CommandProvider, ICacheUpdateAware<String, Object>, IContainerInternal, IContainerAuthorization,
IConfigurationAware {
* Read containers, container flows and finally containers' entries from file
* and program the database accordingly
*/
- if (containerConfigs.isEmpty()) {
+ if ((clusterServices != null) && (clusterServices.amICoordinator())) {
loadContainerConfig();
}
}
*/
private void notifyContainerModeChange(boolean lastActionDelete, boolean notifyLocal) {
if (lastActionDelete == false && containerConfigs.size() == 1) {
- logger.info("First container Creation. Inform listeners");
+ logger.trace("First container Creation. Inform listeners");
synchronized (this.iContainerListener) {
for (IContainerListener i : this.iContainerListener) {
i.containerModeUpdated(UpdateType.ADDED);
}
}
} else if (lastActionDelete == true && containerConfigs.isEmpty()) {
- logger.info("Last container Deletion. Inform listeners");
+ logger.trace("Last container Deletion. Inform listeners");
synchronized (this.iContainerListener) {
for (IContainerListener i : this.iContainerListener) {
i.containerModeUpdated(UpdateType.REMOVED);
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
</property>
</activation>
<dependencies>
-
<!-- md-sal -->
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common</artifactId>
<artifactId>yang-jmx-generator</artifactId>
<version>${config.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-event-executor-config</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netty-threadgroup-config</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-api</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>threadpool-config-impl</artifactId>
- <version>${config.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-store-api</artifactId>
- <version>${config.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>yang-store-api</artifactId>
</dependency>
<dependency>
<groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>0.3.1</version>
- </dependency>
+ <artifactId>jeromq</artifactId>
+ <version>0.3.1</version>
+ </dependency>
+ <!-- yang model dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>ietf-yang-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools.model</groupId>
+ <artifactId>opendaylight-l2-types</artifactId>
+ </dependency>
</dependencies>
</profile>
<profile>
<artifactItem>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sanitytest</artifactId>
- <version>${controller.version}</version>
<type>jar</type>
</artifactItem>
</artifactItems>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
- <version>${forwarding.staticrouting}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>${clustering.services.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services-implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
- <dependency>
+ <dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>arphandler</artifactId>
- <version>${arphandler.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.implementation</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>appauth</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>${switchmanager.api.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>${statisticsmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.implementation</artifactId>
- <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>security</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>${forwardingrulesmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- SAL bundles -->
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- SAL Extension bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection.implementation</artifactId>
- <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.networkconfiguration</artifactId>
- <version>${sal.networkconfiguration.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.networkconfiguration.implementation</artifactId>
- <version>${sal.networkconfiguration.version}</version>
</dependency>
<!-- Web bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flows.web</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>devices.web</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>troubleshoot.web</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.web</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>osgi-brandfragment.web</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Neutron -->
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- Northbound bundles -->
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner.implementation</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statistics.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>subnets.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.bridgedomain.northbound</artifactId>
- <version>${networkconfig.bridgedomain.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>httpservice-bridge</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jolokia</groupId>
<artifactId>jolokia-osgi</artifactId>
- <version>${jolokia.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>jolokia-bridge</artifactId>
- <version>${jolokia.bridge.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.northbound</artifactId>
- <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.northbound</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Debug and logging -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logging.bridge</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- Southbound bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.openflow</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- samples -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer</artifactId>
- <version>${samples.loadbalancer}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer.northbound</artifactId>
- <version>${controller.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.simpleforwarding</artifactId>
- <version>${controller.version}</version>
</dependency>
<!-- Third party depedencies -->
-
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
- </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>2.2.4</version>
- <scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>javax.resource</artifactId>
</dependency>
<!-- Add Pax Exam -->
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-native</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-link-mvn</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.asm</artifactId>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<dependency>
<groupId>org.eclipse.equinox.http</groupId>
<artifactId>servlet</artifactId>
- <!--
- <version>1.0.0-v20070606</version>
- -->
</dependency>
<!-- felix webconsole -->
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.webconsole</artifactId>
- <version>4.2.0</version>
<classifier>all</classifier>
- <!-- the all bundle includes all the necessary plugins -->
</dependency>
<!-- Third parties from opendaylight released -->
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
</dependency>
- <!-- yang model dependencies -->
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-inet-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>ietf-yang-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>opendaylight-l2-types</artifactId>
- </dependency>
<!--Netty-->
<dependency>
<artifactId>netty-common</artifactId>
</dependency>
-
- <!-- testing dependencies I'm pretty sure we should trim -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.test</artifactId>
- <version>${controller.version}</version>
- </dependency>
+ <!-- testing dependencies I'm pretty sure we should trim -->
<dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.httpclient</artifactId>
- <version>${commons.httpclient.version}</version>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>clustering.test</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
- <artifactId>sanitytest</artifactId>
- <version>${controller.version}</version>
+ <artifactId>commons.httpclient</artifactId>
</dependency>
-
-
</dependencies>
-
<build>
<plugins>
<plugin>
<name>runtime-mapping-singleton</name>
</mapping-service>
</module>
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">prefix:remote-zeromq-rpc-server</type>
+ <name>remoter</name>
+ <port xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">5666</port> 59
+ <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc"> 60
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-broker-osgi-registry</type>
+ <name>dom-broker</name>
+ </dom-broker>
+ </module>
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
</configuration>
<required-capabilities>
- <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05</capability>
- <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
- <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12</capability>
- <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28</capability>
- <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24</capability>
- <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
- <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28</capability>
- <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28</capability>
</required-capabilities>
+
</snapshot>
<logger name="org.opendaylight.controller" level="INFO"/>
<!-- OSGi logging bridge -->
- <logger name="org.opendaylight.controller.logging.bridge" level="INFO"/>
+ <logger name="org.opendaylight.controller.logging.bridge" level="WARN"/>
<logger name="org.opendaylight.controller.logging.bridge.internal" level="WARN"/>
<!-- Netty -->
else
echo "Controller with PID: ${daemonpid} -- Doesn't seem to exist"
rm -f "${pidfile}"
- exit 0
+ exit 1
fi
else
echo "Doesn't seem any Controller daemon is currently running, at least no PID file has been found"
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import java.util.List;
import java.util.Map;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.sal.utils.GUIField;
import org.opendaylight.controller.sal.utils.Status;
import org.opendaylight.controller.sal.utils.StatusCode;
/**
* This class defines all the necessary configuration information for a static route.
*/
-public class StaticRouteConfig implements Serializable {
+public class StaticRouteConfig extends ConfigurationObject implements Serializable {
private static final long serialVersionUID = 1L;
private static final String regexSubnet = "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
+ "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\."
* @return SUCCESS if the config is valid
*/
public Status isValid() {
- if ((name == null) || (name.trim().length() < 1)) {
+ if (!isValidResourceName(name)) {
return new Status(StatusCode.BADREQUEST,
"Invalid Static Route name");
}
if (getNextHopType().equalsIgnoreCase(
StaticRoute.NextHopType.SWITCHPORT.toString())) {
String pieces[] = nextHop.split("/");
- if (pieces.length < 2)
+ if (pieces.length < 2) {
return false;
+ }
return isValidSwitchId(pieces[0]);
}
return false;
}
StaticRouteConfig other = (StaticRouteConfig) obj;
if (name == null) {
- if (other.name != null)
+ if (other.name != null) {
return false;
- } else if (!name.equals(other.name))
+ }
+ } else if (!name.equals(other.name)) {
return false;
+ }
if (nextHop == null) {
- if (other.nextHop != null)
+ if (other.nextHop != null) {
return false;
- } else if (!nextHop.equals(other.nextHop))
+ }
+ } else if (!nextHop.equals(other.nextHop)) {
return false;
+ }
if (staticRoute == null) {
- if (other.staticRoute != null)
+ if (other.staticRoute != null) {
return false;
- } else if (!staticRoute.equals(other.staticRoute))
+ }
+ } else if (!staticRoute.equals(other.staticRoute)) {
return false;
+ }
return true;
}
@SuppressWarnings("deprecation")
private void allocateCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.trace("un-initialized clusterContainerService, can't create cache");
return;
}
@SuppressWarnings({ "unchecked", "deprecation" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't retrieve cache");
+ log.warn("un-initialized clusterContainerService, can't retrieve cache");
return;
}
private void notifyStaticRouteUpdate(StaticRoute s, boolean update) {
if (this.staticRoutingAware != null) {
- log.info("Invoking StaticRoutingAware listeners");
+ log.trace("Invoking StaticRoutingAware listeners");
synchronized (this.staticRoutingAware) {
for (IStaticRoutingAware ra : this.staticRoutingAware) {
try {
allocateCaches();
retrieveCaches();
this.executor = Executors.newFixedThreadPool(1);
- if (staticRouteConfigs.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
package org.opendaylight.controller.forwardingrulesmanager;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.sal.action.Action;
import org.opendaylight.controller.sal.action.ActionType;
import org.opendaylight.controller.sal.action.Controller;
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class FlowConfig implements Serializable {
+public class FlowConfig extends ConfigurationObject implements Serializable {
private static final long serialVersionUID = 1L;
private static final Logger log = LoggerFactory.getLogger(FlowConfig.class);
- private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
public static final String STATICFLOWGROUP = "__StaticFlows__";
public static final String INTERNALSTATICFLOWGROUP = "__InternalStaticFlows__";
public static final String INTERNALSTATICFLOWBEGIN = "__";
Switch sw = null;
try {
- if (name == null || name.trim().isEmpty() || !name.matches(FlowConfig.NAMEREGEX)) {
+ // Flow name cannot be internal flow signature
+ if (!isValidResourceName(name) || isInternalFlow()) {
return new Status(StatusCode.BADREQUEST, "Invalid name");
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
Status succeeded = null;
boolean decouple = false;
if (installedList.size() != toInstallList.size()) {
- log.info("Modify: New flow entry does not satisfy the same "
+ log.trace("Modify: New flow entry does not satisfy the same "
+ "number of container flows as the original entry does");
decouple = true;
}
*/
FlowEntryInstall sameMatchEntry = installedSwView.get(installEntry);
if (sameMatchEntry != null && !sameMatchEntry.getOriginal().equals(currentFlowEntry)) {
- log.info("Modify: new container flow merged flow entry clashes with existing flow");
+ log.trace("Modify: new container flow merged flow entry clashes with existing flow");
decouple = true;
} else {
toInstallSafe.add(installEntry);
}
Status error = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (error.isSuccess()) {
- log.info("Ports {} added to FlowEntry {}", portList, flowName);
+ log.trace("Ports {} added to FlowEntry {}", portList, flowName);
} else {
log.warn("Failed to add ports {} to Flow entry {}. The failure is: {}", portList,
currentFlowEntry.toString(), error.getDescription());
}
Status status = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (status.isSuccess()) {
- log.info("Ports {} removed from FlowEntry {}", portList, flowName);
+ log.trace("Ports {} removed from FlowEntry {}", portList, flowName);
} else {
log.warn("Failed to remove ports {} from Flow entry {}. The failure is: {}", portList,
currentFlowEntry.toString(), status.getDescription());
Status status = modifyEntry(currentFlowEntry, newFlowEntry, false);
if (status.isSuccess()) {
- log.info("Output port replaced with {} for flow {} on node {}", outPort, flowName, node);
+ log.trace("Output port replaced with {} for flow {} on node {}", outPort, flowName, node);
} else {
log.warn("Failed to replace output port for flow {} on node {}. The failure is: {}", flowName, node,
status.getDescription());
// Do not attempt to reinstall the flow, warn user
if (newFlowConfig.equals(oldFlowConfig)) {
String msg = "No modification detected";
- log.info("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig);
+ log.trace("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig);
return new Status(StatusCode.SUCCESS, msg);
}
* inactive list
*/
private void uninstallAllFlowEntries(boolean preserveFlowEntries) {
- log.info("Uninstalling all non-internal flows");
+ log.trace("Uninstalling all non-internal flows");
List<FlowEntryInstall> toRemove = new ArrayList<FlowEntryInstall>();
* default container instance of FRM only when the last container is deleted
*/
private void reinstallAllFlowEntries() {
- log.info("Reinstalling all inactive flows");
+ log.trace("Reinstalling all inactive flows");
for (FlowEntry flowEntry : this.inactiveFlows.keySet()) {
this.addEntry(flowEntry, false);
dropAllConfig.setActions(dropAction);
defaultConfigs.add(dropAllConfig);
- log.info("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive"));
+ log.trace("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive"));
for (FlowConfig fc : defaultConfigs) {
Status status = (proactive) ? addStaticFlowInternal(fc, false) : removeStaticFlow(fc);
if (status.isSuccess()) {
- log.info("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName());
+ log.trace("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName());
} else {
log.warn("Failed to {} Proactive Static flow: {}", (proactive ? "install" : "remove"),
fc.getName());
* @param node
*/
private void cleanDatabaseForNode(Node node) {
- log.info("Cleaning Flow database for Node {}", node);
+ log.trace("Cleaning Flow database for Node {}", node);
if (nodeFlows.containsKey(node)) {
List<FlowEntryInstall> toRemove = new ArrayList<FlowEntryInstall>(nodeFlows.get(node));
@Override
public void portGroupChanged(PortGroupConfig config, Map<Node, PortGroup> data, boolean add) {
- log.info("PortGroup Changed for: {} Data: {}", config, portGroupData);
+ log.trace("PortGroup Changed for: {} Data: {}", config, portGroupData);
Map<Node, PortGroup> existingData = portGroupData.get(config);
if (existingData != null) {
for (Map.Entry<Node, PortGroup> entry : data.entrySet()) {
}
/*
- * Read startup and build database if we have not already gotten the
- * configurations synced from another node
+ * Read startup and build database if we are the coordinator
*/
- if (staticFlows.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadFlowConfiguration();
}
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
\r
import org.junit.Assert;\r
import org.junit.Test;\r
-\r
import org.opendaylight.controller.sal.core.ConstructionException;\r
import org.opendaylight.controller.sal.core.Node;\r
-\r
-import junit.framework.TestCase;\r
-\r
+import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.packet.address.EthernetAddress;\r
-\r
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;\r
-import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.utils.NodeCreator;\r
\r
-public class HostNodeConnectorTest extends TestCase {\r
+public class HostNodeConnectorTest {\r
\r
@Test\r
public void testHostNodeConnector() throws UnknownHostException {\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-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>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
import java.net.InetAddress;\r
import java.net.UnknownHostException;\r
\r
-import junit.framework.TestCase;\r
-\r
import org.junit.Assert;\r
import org.junit.Test;\r
import org.opendaylight.controller.hosttracker.IHostId;\r
import org.opendaylight.controller.hosttracker.IPHostId;\r
\r
-public class HostTrackerTest extends TestCase {\r
+public class HostTrackerTest {\r
\r
@Test\r
public void testHostTrackerCallable() throws UnknownHostException {\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>${hosttracker.version}</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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>arphandler</artifactId>
- <version>${arphandler.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
\r
import org.junit.Assert;\r
import org.junit.Test;\r
-\r
import org.opendaylight.controller.sal.core.ConstructionException;\r
import org.opendaylight.controller.sal.core.Node;\r
-\r
-import junit.framework.TestCase;\r
-\r
+import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.packet.address.EthernetAddress;\r
-\r
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;\r
-import org.opendaylight.controller.sal.core.NodeConnector;\r
import org.opendaylight.controller.sal.utils.NodeCreator;\r
\r
-public class HostNodeConnectorTest extends TestCase {\r
+public class HostNodeConnectorTest {\r
\r
@Test\r
public void testHostNodeConnector() throws UnknownHostException {\r
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-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>hosttracker_new</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
if (reader == null) {
this.log.error("Cannot register the LogListener because "
+ "cannot retrieve LogReaderService");
- }
- reader.addLogListener(this.listener);
- // Now lets walk all the exiting messages
- Enumeration<LogEntry> entries = reader.getLog();
- if (entries != null) {
- while (entries.hasMoreElements()) {
- LogEntry entry = (LogEntry) entries.nextElement();
- this.listener.logged(entry);
+ } else {
+ reader.addLogListener(this.listener);
+ // Now lets walk all the exiting messages
+ Enumeration<LogEntry> entries = reader.getLog();
+ if (entries != null) {
+ while (entries.hasMoreElements()) {
+ LogEntry entry = entries.nextElement();
+ this.listener.logged(entry);
+ }
}
}
log.warn("Invalid policy name \"{}\", defaulting to {}", policy, handler);
}
}
- log.info("Setting uncaught exception policy to {}", handler);
+ log.trace("Setting uncaught exception policy to {}", handler);
Thread.setDefaultUncaughtExceptionHandler(handler);
/*
@Override
public void stop(BundleContext context) {
- ServiceReference service = null;
- service = context.getServiceReference(LogReaderService.class.getName());
- if (service != null) {
- LogReaderService reader = (LogReaderService) service;
+ ServiceReference serviceRef = context.getServiceReference(
+ LogReaderService.class.getName());
+ if (serviceRef != null) {
+ LogReaderService reader = (LogReaderService) context.getService(serviceRef);
reader.removeLogListener(this.listener);
}
if (this.shutdownHandler != null) {
private Logger logger = LoggerFactory.getLogger(ClusteredDataStoreImpl.class);
public ClusteredDataStoreImpl(IClusterGlobalServices clusterGlobalServices) throws CacheConfigException {
- logger.info("Constructing clustered data store");
+ logger.trace("Constructing clustered data store");
Preconditions.checkNotNull(clusterGlobalServices, "clusterGlobalServices cannot be null");
operationalDataCache = getOrCreateCache(clusterGlobalServices, OPERATIONAL_DATA_CACHE);
public boolean containsConfigurationPath(InstanceIdentifier path) {
return configurationDataCache.containsKey(path);
}
-
+
@Override
public boolean containsOperationalPath(InstanceIdentifier path) {
return operationalDataCache.containsKey(path);
}
-
+
@Override
public Iterable<InstanceIdentifier> getStoredConfigurationPaths() {
return configurationDataCache.keySet();
}
-
+
@Override
public Iterable<InstanceIdentifier> getStoredOperationalPaths() {
return operationalDataCache.keySet();
}
-
-
-
+
+
+
@Override
public CompositeNode readConfigurationData(InstanceIdentifier path) {
Preconditions.checkNotNull(path, "path cannot be null");
val table= it.readConfigurationData(tableRef) as Table;
if(table != null){
- LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+ LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
for(flow : table.flow){
val table= it.readConfigurationData(tableRef) as Table;
if(table != null){
- LOG.info("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
+ LOG.trace("Number of flows installed in table 0 of node {} : {}",node,table.flow.size);
for(mdsalFlow : table.flow){
if(FromSalConversionsUtils.flowEquals(mdsalFlow, MDFlowMapping.toMDSalflow(targetFlow))){
public static def toAdBandwidth(PortFeatures pf) {
var Bandwidth bw = null
- if (pf.is_10mbHd || pf.is_10mbFd) {
+ if (pf.isTenMbHd || pf.isTenMbFd) {
bw = new Bandwidth(Bandwidth.BW10Mbps)
- } else if (pf.is_100mbHd || pf.is_100mbFd) {
+ } else if (pf.isHundredMbHd || pf.isHundredMbFd) {
bw = new Bandwidth(Bandwidth.BW100Mbps)
- } else if (pf.is_1gbHd || pf.is_1gbFd) {
+ } else if (pf.isOneGbHd || pf.isOneGbFd) {
bw = new Bandwidth(Bandwidth.BW1Gbps)
- } else if (pf.is_1gbFd) {
+ } else if (pf.isOneGbFd) {
bw = new Bandwidth(Bandwidth.BW10Gbps)
- } else if (pf.is_10gbFd) {
+ } else if (pf.isTenGbFd) {
bw = new Bandwidth(Bandwidth.BW10Gbps)
- } else if (pf.is_40gbFd) {
+ } else if (pf.isFortyGbFd) {
bw = new Bandwidth(Bandwidth.BW40Gbps)
- } else if (pf.is_100gbFd) {
+ } else if (pf.isHundredGbFd) {
bw = new Bandwidth(Bandwidth.BW100Gbps)
- } else if (pf.is_1tbFd) {
+ } else if (pf.isOneTbFd) {
bw = new Bandwidth(Bandwidth.BW1Tbps)
}
return bw;
import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector
+import org.slf4j.LoggerFactory
class TopologyMapping {
-
+ private static val LOG = LoggerFactory.getLogger(TopologyMapping);
private new() {
throw new UnsupportedOperationException("Utility class. Instantiation is not allowed.");
}
}
public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) {
- val nc = reader.readOperationalData(e.tailNodeConnector.toNodeConnectorRef.value as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
+ val ncref = e.tailNodeConnector.toNodeConnectorRef
+ if(ncref == null) {
+ LOG.debug("Edge {} ncref {}",e,ncref)
+ return null;
+ }
+ val ncInstanceId = (ncref.value as InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
+ if(ncInstanceId == null) {
+ LOG.debug("Edge {} ncref {}",e,ncref)
+ return null;
+ }
+ val nc = reader.readOperationalData(ncInstanceId)
+ if(nc == null) {
+ return null;
+ }
return nc.toADNodeConnectorProperties
}
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
revision "2013-10-26" {
description "Initial revision of macth types";
}
-
+
grouping "mac-address-filter" {
leaf address {
mandatory true;
type yang:mac-address;
}
leaf mask {
- type binary;
+ type yang:mac-address;
}
}
-
+
grouping "of-metadata" {
leaf metadata {
type uint64;
}
-
+
leaf metadata-mask {
- type binary;
+ type uint64;
}
}
container ethernet-type {
description "Ethernet frame type.";
presence "Match field is active and set";
-
+
leaf type {
mandatory true;
type l2t:ether-type; // Needs to define that as general model
}
-
- leaf mask {
- type binary;
- }
}
}
leaf vlan-id-present {
type boolean;
}
-
+
leaf vlan-id {
- type l2t:vlan-id;
+ type l2t:vlan-id;
}
}
leaf vlan-pcp {
grouping "ip-match-fields" {
leaf ip-protocol {
description "IP protocol.";
- type uint8;
+ type uint8;
}
leaf ip-dscp {
description "IP DSCP (6 bits in ToS field).";
- type inet:dscp;
+ type inet:dscp;
}
-
+
leaf ip-ecn {
description "IP ECN (2 bits in ToS field).";
- type uint8;
+ type uint8;
}
-
- leaf ip-proto {
- description "IP Proto (IPv4 or IPv6 Protocol Number).";
- type inet:ip-version;
+
+ leaf ip-proto {
+ description "IP Proto (IPv4 or IPv6 Protocol Number).";
+ type inet:ip-version;
}
- }
-
+ }
+
grouping "ipv4-match-fields" {
leaf ipv4-source {
description "IPv4 source address.";
type inet:ipv4-prefix;
}
-
+
leaf ipv4-destination {
description "IPv4 destination address.";
type inet:ipv4-prefix;
}
-
+
}
-
+
grouping "ipv6-match-fields" {
leaf ipv6-source {
description "IPv6 source address.";
type inet:ipv6-prefix;
}
-
+
leaf ipv6-destination {
description "IPv6 destination address.";
type inet:ipv6-prefix;
}
-
+
leaf ipv6-nd-target {
description "IPv6 target address for neighbour discovery message";
type inet:ipv6-address;
}
-
+
container "ipv6-label" {
leaf ipv6-flabel {
type inet:ipv6-flow-label;
}
-
+
leaf flabel-mask {
- type binary;
+ type inet:ipv6-flow-label;
}
}
-
+
leaf ipv6-nd-sll {
description "Link layer source address for neighbour discovery message";
type yang:mac-address;
}
-
+
leaf ipv6-nd-tll {
description "Link layer target address for neighbour discovery message";
type yang:mac-address;
}
-
- container "ipv6-ext-header" {
+
+ container "ipv6-ext-header" {
leaf ipv6-exthdr {
description "IPv6 Extension Header field";
type uint16;
}
leaf ipv6-exthdr-mask {
- type binary;
+ type uint16 {
+ range "0..512";
+ }
}
}
}
description "Label in the first MPLS shim header";
type uint32;
}
-
+
leaf mpls-tc {
description "TC in the first MPLS shim header";
type uint8;
}
-
+
leaf mpls-bos {
description "BoS bit in the first MPLS shim header";
type uint8;
}
-
+
container "pbb" {
leaf pbb-isid {
description "I-SID in the first PBB service instance tag";
type uint32;
- }
+ }
leaf pbb-mask {
- type binary;
+ type uint32 {
+ range "0..16777216";
+ }
}
}
}
-
+
grouping "tcp-match-fields" {
leaf tcp-source-port {
description "TCP source port.";
type uint8; // Define ICMP Code
}
}
-
+
grouping "icmpv6-match-fields" {
leaf icmpv6-type {
description "ICMP type.";
leaf arp-op {
type uint16;
}
-
+
leaf arp-source-transport-address {
description "ARP source IPv4 address.";
type inet:ipv4-prefix;
}
-
+
leaf arp-target-transport-address {
description "ARP target IPv4 address.";
type inet:ipv4-prefix;
uses mac-address-filter;
}
}
-
+
grouping match {
leaf in-port {
type inv:node-connector-id;
}
-
+
leaf in-phy-port {
type inv:node-connector-id;
}
-
+
container "metadata" {
uses of-metadata;
}
-
+
container "tunnel" {
leaf tunnel-id {
description "Metadata associated in the logical port";
type uint64;
}
-
+
leaf tunnel-mask {
- type binary;
+ type uint64;
}
}
-
+
container "ethernet-match" {
uses "ethernet-match-fields";
}
-
+
container "vlan-match" {
uses "vlan-match-fields";
}
-
+
container "ip-match" {
uses "ip-match-fields";
}
-
+
choice layer-3-match {
case "ipv4-match" {
uses "ipv4-match-fields";
uses "arp-match-fields";
}
}
-
+
choice layer-4-match {
case "udp-match" {
uses "udp-match-fields";
uses "sctp-match-fields";
}
}
-
+
container "icmpv4-match" {
uses "icmpv4-match-fields";
}
-
+
container "icmpv6-match" {
uses "icmpv6-match-fields";
}
-
+
container "protocol-match-fields" {
uses "protocol-match-fields";
}
namespace "urn:opendaylight:meter:types";
prefix meter;
- import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
grouping band-type {
choice band-type {
case drop {
- leaf rate {
+ leaf drop-rate {
type uint32;
}
- leaf burst-size {
+ leaf drop-burst-size {
type uint32;
}
}
case dscp-remark {
- leaf rate {
+ leaf dscp-remark-rate {
type uint32;
}
- leaf burst-size {
+ leaf dscp-remark-burst-size {
type uint32;
}
}
case experimenter {
- leaf rate {
+ leaf experimenter-rate {
type uint32;
}
- leaf burst-size {
+ leaf experimenter-burst-size {
type uint32;
}
}
}
- leaf rate {
+ leaf band-rate {
type uint32;
}
- leaf burst-size {
+ leaf band-burst-size {
type uint32;
}
uses band-type;
uses meter-features;
}
-}
\ No newline at end of file
+}
namespace "urn:opendaylight:flow:types:port";
prefix port-types;
- import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
import opendaylight-queue-types {prefix queue-types; revision-date "2013-09-25";}
typedef port-features {
type bits {
- bit 10mb-hd;
- bit 10mb-fd;
- bit 100mb-hd;
- bit 100mb-fd;
- bit 1gb-hd;
- bit 1gb-fd;
- bit 10gb-fd;
- bit 40gb-fd;
- bit 100gb-fd;
- bit 1tb-fd;
+ bit ten-mb-hd;
+ bit ten-mb-fd;
+ bit hundred-mb-hd;
+ bit hundred-mb-fd;
+ bit one-gb-hd;
+ bit one-gb-fd;
+ bit ten-gb-fd;
+ bit forty-gb-fd;
+ bit hundred-gb-fd;
+ bit one-tb-fd;
bit other;
bit copper;
bit fiber;
}
}
}
-}
\ No newline at end of file
+}
namespace "urn:opendaylight:table:types";
prefix table;
- import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
- import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
import opendaylight-flow-types {prefix flow;revision-date "2013-10-26";}
import opendaylight-action-types {prefix action;}
}
case next-table-miss {
- container tables {
+ container tables-miss {
leaf-list table-ids {
type uint8;
}
}
case match {
- uses set-field-match;
+ container match-setfield {
+ uses set-field-match;
+ }
}
case wildcards {
- uses set-field-match;
+ container wildcard-setfield {
+ uses set-field-match;
+ }
}
case write-setfield {
- uses set-field-match;
+ container write-setfield {
+ uses set-field-match;
+ }
}
case write-setfield-miss {
- uses set-field-match;
+ container write-setfield-miss {
+ uses set-field-match;
+ }
}
case apply-setfield {
- uses set-field-match;
+ container apply-setfield {
+ uses set-field-match;
+ }
}
case apply-setfield-miss {
- uses set-field-match;
+ container apply-setfield-miss {
+ uses set-field-match;
+ }
}
}
}
uses table-feature-prop-type;
}
}
-
}
}
}
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1-SNAPSHOT</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
</dependencies>
<packaging>bundle</packaging>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>yang-ext</artifactId>
- <version>2013.09.07.1-SNAPSHOT</version>
+ <version>2013.09.07.2-SNAPSHOT</version>
</dependency>
</dependencies>
<!-- Base Models -->
<module>model</module>
+ <module>sal-remote</module>
+ <module>sal-restconf-broker</module>
<!-- Connectors -->
<guava.version>14.0.1</guava.version>
<osgi.core.version>5.0.0</osgi.core.version>
<junit.version>4.8.1</junit.version>
- <powermock.version>1.5.1</powermock.version>
<mockito.version>1.9.5</mockito.version>
<xtend.version>2.4.3</xtend.version>
<maven.clean.plugin.version>2.5</maven.clean.plugin.version>
<jacoco.version>0.5.3.201107060350</jacoco.version>
- <sal.version>0.5.1-SNAPSHOT</sal.version> <!-- AD Sal version -->
<!-- Sonar properties using jacoco to retrieve integration test results -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.branch>${user.name}-private-view</sonar.branch>
<sonar.language>java</sonar.language>
<exam.version>3.0.0</exam.version>
+ <sal.version>0.7.0-SNAPSHOT</sal.version>
</properties>
<pluginRepositories>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-module-junit4</artifactId>
- <version>${powermock.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-mockito</artifactId>
- <version>${powermock.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-core</artifactId>
- <version>${powermock.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>binding-generator-impl</artifactId>
<sources>
<source>${project.build.directory}/generated-sources/config</source>
<source>${project.build.directory}/generated-sources/sal</source>
+ <source>src/main/xtend-gen</source>
</sources>
</configuration>
</execution>
*/
package org.opendaylight.controller.sal.connector.remoterpc.api;
+import java.util.Map;
import java.util.Set;
public interface RoutingTable<I,R> {
*/
public Set<R> getRoutes(I routeId);
+ /**
+ * Returns all network addresses stored in the table
+ * @return
+ */
+ public Set<Map.Entry> getAllRoutes();
+
/**
* Returns only one address from the list of network addresses
* associated with the route. The algorithm to determine that
}
// lets start a transaction
clusterGlobalServices.tbegin();
- Set<R> routes = new HashSet<R>();
- routes.add(route);
- routingTableCache.put(routeId, routes);
+
+ routingTableCache.put(routeId, route);
clusterGlobalServices.tcommit();
} else {
throw new DuplicateRouteException(" There is already existing route " + existingRoute);
}
- } catch (NotSupportedException e) {
- throw new RoutingTableException("Transaction error - while trying to create route id="
- + routeId + "with route" + route, e);
- } catch (HeuristicRollbackException e) {
- throw new RoutingTableException("Transaction error - while trying to create route id="
- + routeId + "with route" + route, e);
- } catch (RollbackException e) {
- throw new RoutingTableException("Transaction error - while trying to create route id="
- + routeId + "with route" + route, e);
- } catch (HeuristicMixedException e) {
+ } catch (NotSupportedException|HeuristicRollbackException|RollbackException|HeuristicMixedException e) {
throw new RoutingTableException("Transaction error - while trying to create route id="
+ routeId + "with route" + route, e);
} catch (javax.transaction.SystemException e) {
routingTableCache.remove(routeId);
clusterGlobalServices.tcommit();
- } catch (NotSupportedException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (HeuristicRollbackException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (RollbackException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (HeuristicMixedException e) {
+ } catch (NotSupportedException|HeuristicRollbackException|RollbackException|HeuristicMixedException e) {
throw new RoutingTableException("Transaction error - while trying to remove route id="
+ routeId, e);
} catch (javax.transaction.SystemException e) {
// Note: currently works for global routes only wherein there is just single
// route
Preconditions.checkNotNull(routeId, "getARoute: routeId cannot be null!");
- return (Set<R>) routingTableCache.get(routeId);
+ R route = (R)routingTableCache.get(routeId);
+ Set<R>routes = null;
+ if(route !=null){
+ routes = new HashSet<R>();
+ routes.add(route);
+ }
+
+ return routes;
}
- @Override
+ @Override
+ public Set<Map.Entry> getAllRoutes() {
+ return routingTableCache.entrySet();
+ }
+
+ @Override
public R getARoute(I routeId) {
throw new UnsupportedOperationException("Not implemented yet!");
}
import java.net.URI;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
rti.addGlobalRoute(routeIdentifier, "172.27.12.1:5000");
- Set<String> globalService = new HashSet<String>();
- globalService.add("172.27.12.1:5000");
+ String globalService = "172.27.12.1:5000";
when(concurrentMap.get(routeIdentifier)).thenReturn(globalService);
ConcurrentMap latestCache = rti.getRoutingTableCache();
Assert.assertEquals(servicesGlobal.size(),1);
-
- Assert.assertEquals(servicesGlobal.iterator().next(),"172.27.12.1:5000");
-
+ Iterator<String> iterator = servicesGlobal.iterator();
+ while(iterator.hasNext()){
+ Assert.assertEquals(iterator.next(),"172.27.12.1:5000");
+ }
}
rti.addGlobalRoute(routeIdentifier, "172.27.12.1:5000");
- Set<String> globalService = new HashSet<String>();
- globalService.add("172.27.12.1:5000");
+ String globalService = "172.27.12.1:5000";
when(concurrentMap.get(routeIdentifier)).thenReturn(globalService);
ConcurrentMap latestCache = rti.getRoutingTableCache();
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/config</source>
+ <source>src/main/xtend-gen</source>
</sources>
</configuration>
</execution>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-broker-impl</artifactId>
<version>1.0-SNAPSHOT</version>
- <scope>runtime</scope>
+ <scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.codegen.impl;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RpcRegistration;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRoutingTable;
+import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@Override
public RpcRegistration<T> registerDefaultService(T service) {
// TODO Auto-generated method stub
+ RuntimeCodeHelper.setDelegate(invocationProxy, service);
return null;
}
baArgs.add(baArg)
}
val ret = new InstanceIdentifier(baArgs,baType as Class<? extends DataObject>);
+ LOG.debug("DOM Instance Identifier {} deserialized to {}",input,ret);
return ret;
}
previousAugmentation = baArg.type;
}
}
- return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+ val ret = new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(components);
+ LOG.debug("Binding Instance Identifier {} serialized to DOM InstanceIdentifier {}",input,ret);
+ return ret;
}
def updateAugmentationInjection(Class<? extends DataObject> class1, ImmutableList<QName> list, Class<?> augmentation) {
if (typeDef !== null) {
return typeDef;
}
- LOG.info("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
+ LOG.trace("Thread blocked waiting for schema for: {}",type.fullyQualifiedName)
return type.getSchemaInFuture.get();
}
method(Object, "deserialize", Object) [
bodyChecked = '''
{
- ////System.out.println("«type.name»#deserialize: " +$1);
+ //System.out.println("«type.name»#deserialize: " +$1);
java.util.Map.Entry _input = (java.util.Map.Entry) $1;
return fromDomStatic((«QName.name»)_input.getKey(),_input.getValue());
}
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
boolean _is_empty = true;
«FOR child : node.childNodes»
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«deserializeKey(type, node)»
«deserializeDataNodeContainerBody(type, node)»
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«deserializeDataNodeContainerBody(type, node)»
«deserializeAugmentations»
return null;
}
java.util.Map _compositeNode = (java.util.Map) $2;
- System.out.println(_localQName + " " + _compositeNode);
+ //System.out.println(_localQName + " " + _compositeNode);
«type.builderName» _builder = new «type.builderName»();
«deserializeDataNodeContainerBody(type, node)»
«deserializeAugmentations»
}
private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
- log.info("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
+ log.trace("Generating Dummy DOM Codec for {} with {}", object, object.classLoader)
return createClass(typeSpec.codecClassName) [
if (object.isYangBindingAvailable) {
implementsType(BINDING_CODEC)
if(log.isDebugEnabled){\r
log.debug("Delivering notification {} to {}",notification,listener);\r
} else {\r
- log.info("Delivering notification {} to {}",notification.class.name,listener);\r
+ log.trace("Delivering notification {} to {}",notification.class.name,listener);\r
}\r
listener.onNotification(notification);\r
if(log.isDebugEnabled){\r
log.debug("Notification delivered {} to {}",notification,listener);\r
} else {\r
- log.info("Notification delivered {} to {}",notification.class.name,listener);\r
+ log.trace("Notification delivered {} to {}",notification.class.name,listener);\r
}\r
} catch (Exception e) {\r
log.error("Unhandled exception thrown by listener: {}", listener, e);\r
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl;
+import java.util.EventListener;
import java.util.Map;
import java.util.Map.Entry;
import java.util.HashMap;
private final Map<Class<? extends RpcService>, RpcRouter<?>> rpcRouters = new WeakHashMap<>();
private final ListenerRegistry<RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> routeChangeListeners = ListenerRegistry
.create();
+ private final ListenerRegistry<RouterInstantiationListener> routerInstantiationListener = ListenerRegistry.create();
private final static Logger LOG = LoggerFactory.getLogger(RpcProviderRegistryImpl.class);
-
+
private final String name;
+ private ListenerRegistry<GlobalRpcRegistrationListener> globalRpcListeners = ListenerRegistry.create();
+
public String getName() {
return name;
}
T publicProxy = getRpcService(type);
RpcService currentDelegate = RuntimeCodeHelper.getDelegate(publicProxy);
checkState(currentDelegate == null, "Rpc service is already registered");
- LOG.debug("Registering {} as global implementation of {} in {}",implementation,type.getSimpleName(),this);
+ LOG.debug("Registering {} as global implementation of {} in {}", implementation, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(publicProxy, implementation);
+ notifyGlobalRpcAdded(type);
return new RpcProxyRegistration<T>(type, implementation, this);
}
if (potentialProxy != null) {
return potentialProxy;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential proxy could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential proxy could be instantiated by other thread while we
+ * were waiting for the lock.
*/
-
+
potentialProxy = (T) publicProxies.get(type);
if (potentialProxy != null) {
return (T) potentialProxy;
}
T proxy = rpcFactory.getDirectProxyFor(type);
- LOG.debug("Created {} as public proxy for {} in {}",proxy,type.getSimpleName(),this);
+ LOG.debug("Created {} as public proxy for {} in {}", proxy, type.getSimpleName(), this);
publicProxies.put(type, proxy);
return proxy;
}
}
- private <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
+ @SuppressWarnings("unchecked")
+ public <T extends RpcService> RpcRouter<T> getRpcRouter(Class<T> type) {
RpcRouter<?> potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- synchronized(this) {
+ synchronized (this) {
/**
- * Potential Router could be instantiated by other thread while we were
- * waiting for the lock.
+ * Potential Router could be instantiated by other thread while we
+ * were waiting for the lock.
*/
- potentialRouter = rpcRouters.get(type);
+ potentialRouter = rpcRouters.get(type);
if (potentialRouter != null) {
return (RpcRouter<T>) potentialRouter;
}
- RpcRouter<T> router = rpcFactory.getRouterFor(type,name);
+ RpcRouter<T> router = rpcFactory.getRouterFor(type, name);
router.registerRouteChangeListener(new RouteChangeForwarder(type));
- LOG.debug("Registering router {} as global implementation of {} in {}",router,type.getSimpleName(),this);
+ LOG.debug("Registering router {} as global implementation of {} in {}", router, type.getSimpleName(), this);
RuntimeCodeHelper.setDelegate(getRpcService(type), router.getInvocationProxy());
rpcRouters.put(type, router);
+ notifyListenersRoutedCreated(router);
return router;
}
}
+ private void notifyGlobalRpcAdded(Class<? extends RpcService> type) {
+ for(ListenerRegistration<GlobalRpcRegistrationListener> listener : globalRpcListeners) {
+ try {
+ listener.getInstance().onGlobalRpcRegistered(type);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ private void notifyListenersRoutedCreated(RpcRouter router) {
+
+ for (ListenerRegistration<RouterInstantiationListener> listener : routerInstantiationListener) {
+ try {
+ listener.getInstance().onRpcRouterCreated(router);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ }
+
+ }
+
+ public ListenerRegistration<RouterInstantiationListener> registerRouterInstantiationListener(
+ RouterInstantiationListener listener) {
+ ListenerRegistration<RouterInstantiationListener> reg = routerInstantiationListener.register(listener);
+ try {
+ for (RpcRouter<?> router : rpcRouters.values()) {
+ listener.onRpcRouterCreated(router);
+ }
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking listener {}", e);
+ }
+ return reg;
+ }
+
@Override
public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(
L listener) {
this.rpcFactory = rpcFactory;
}
+ public interface RouterInstantiationListener extends EventListener {
+ void onRpcRouterCreated(RpcRouter<?> router);
+ }
+
+ public ListenerRegistration<GlobalRpcRegistrationListener> registerGlobalRpcRegistrationListener(GlobalRpcRegistrationListener listener) {
+ return globalRpcListeners.register(listener);
+ }
+
+ public interface GlobalRpcRegistrationListener extends EventListener {
+ void onGlobalRpcRegistered(Class<? extends RpcService> cls);
+ void onGlobalRpcUnregistered(Class<? extends RpcService> cls);
+
+ }
+
private class RouteChangeForwarder<T extends RpcService> implements
RouteChangeListener<Class<? extends BaseIdentity>, InstanceIdentifier<?>> {
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl.connect.dom;
import static com.google.common.base.Preconditions.checkNotNull;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.impl.connect.dom;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.controller.sal.binding.api.data.RuntimeDataProvider;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
import org.opendaylight.controller.sal.binding.api.rpc.RpcRouter;
import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl;
-import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.GlobalRpcRegistrationListener;
+import org.opendaylight.controller.sal.binding.impl.RpcProviderRegistryImpl.RouterInstantiationListener;
import org.opendaylight.controller.sal.common.util.CommitHandlerTransactions;
import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Provider;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-
-import static com.google.common.base.Preconditions.*;
+import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.util.concurrent.Futures;
public class BindingIndependentConnector implements //
RuntimeDataProvider, //
private final Logger LOG = LoggerFactory.getLogger(BindingIndependentConnector.class);
+ @SuppressWarnings( "deprecation")
private static final InstanceIdentifier<? extends DataObject> ROOT = InstanceIdentifier.builder().toInstance();
private static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier ROOT_BI = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
+ private final static Method EQUALS_METHOD;
+
+
private BindingIndependentMappingService mappingService;
private org.opendaylight.controller.sal.core.api.data.DataProviderService biDataService;
private boolean notificationForwarding = false;
+ private RpcProviderRegistryImpl baRpcRegistryImpl;
+
+ private org.opendaylight.controller.sal.dom.broker.spi.RpcRouter biRouter;
+
+
+ static {
+ try {
+ EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@Override
public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readOperationalData(biPath);
- return potentialAugmentationRead(path,biPath,result);
+ return potentialAugmentationRead(path, biPath, result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
}
- private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result) throws DeserializationException {
+ private DataObject potentialAugmentationRead(InstanceIdentifier<? extends DataObject> path,
+ org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath, CompositeNode result)
+ throws DeserializationException {
Class<? extends DataObject> targetType = path.getTargetType();
if (Augmentation.class.isAssignableFrom(targetType)) {
path = mappingService.fromDataDom(biPath);
try {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biPath = mappingService.toDataDom(path);
CompositeNode result = biDataService.readConfigurationData(biPath);
- return potentialAugmentationRead(path,biPath,result);
+ return potentialAugmentationRead(path, biPath, result);
} catch (DeserializationException e) {
throw new IllegalStateException(e);
}
private DataModificationTransaction createBindingToDomTransaction(
DataModification<InstanceIdentifier<? extends DataObject>, DataObject> source) {
DataModificationTransaction target = biDataService.beginTransaction();
+ LOG.debug("Created DOM Transaction {} for {},", target.getIdentifier(),source.getIdentifier());
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedConfigurationData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putConfigurationData(biEntry.getKey(), biEntry.getValue());
+ LOG.debug("Update of Binding Configuration Data {} is translated to {}",entry,biEntry);
}
for (Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry : source.getUpdatedOperationalData()
.entrySet()) {
Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> biEntry = mappingService
.toDataDom(entry);
target.putOperationalData(biEntry.getKey(), biEntry.getValue());
+ LOG.debug("Update of Binding Operational Data {} is translated to {}",entry,biEntry);
}
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedConfigurationData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeConfigurationData(biEntry);
+ LOG.debug("Delete of Binding Configuration Data {} is translated to {}",entry,biEntry);
}
for (InstanceIdentifier<? extends DataObject> entry : source.getRemovedOperationalData()) {
org.opendaylight.yangtools.yang.data.api.InstanceIdentifier biEntry = mappingService.toDataDom(entry);
target.removeOperationalData(biEntry);
+ LOG.debug("Delete of Binding Operational Data {} is translated to {}",entry,biEntry);
}
return target;
}
baDataService.registerCommitHandlerListener(domToBindingCommitHandler);
dataForwarding = true;
}
-
+
public void startRpcForwarding() {
if (baRpcRegistry != null && biRpcRegistry != null && baRpcRegistry instanceof RouteChangePublisher<?, ?>) {
- checkState(!rpcForwarding,"Connector is already forwarding RPCs");
+ checkState(!rpcForwarding, "Connector is already forwarding RPCs");
domToBindingRpcManager = baRpcRegistry.registerRouteChangeListener(new DomToBindingRpcForwardingManager());
+ if (baRpcRegistry instanceof RpcProviderRegistryImpl) {
+ baRpcRegistryImpl = (RpcProviderRegistryImpl) baRpcRegistry;
+ baRpcRegistryImpl.registerRouterInstantiationListener(domToBindingRpcManager.getInstance());
+ baRpcRegistryImpl.registerGlobalRpcRegistrationListener(domToBindingRpcManager.getInstance());
+ }
+ if(biRpcRegistry instanceof org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) {
+ biRouter = (org.opendaylight.controller.sal.dom.broker.spi.RpcRouter) biRpcRegistry;
+ }
rpcForwarding = true;
}
}
-
+
public void startNotificationForwarding() {
checkState(!notificationForwarding, "Connector is already forwarding notifications.");
notificationForwarding = true;
public void onSessionInitiated(ProviderSession session) {
setDomDataService(session.getService(org.opendaylight.controller.sal.core.api.data.DataProviderService.class));
setDomRpcRegistry(session.getService(RpcProvisionRegistry.class));
-
+
}
public <T extends RpcService> void onRpcRouterCreated(Class<T> serviceType, RpcRouter<T> router) {
}
DataModificationTransaction domTransaction = createBindingToDomTransaction(bindingTransaction);
BindingToDomTransaction wrapped = new BindingToDomTransaction(domTransaction, bindingTransaction);
- LOG.info("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
+ LOG.trace("Forwarding Binding Transaction: {} as DOM Transaction: {} .", bindingTransaction.getIdentifier(),
domTransaction.getIdentifier());
return wrapped;
}
org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction baTransaction = createDomToBindingTransaction(domTransaction);
DomToBindingTransaction forwardedTransaction = new DomToBindingTransaction(baTransaction, domTransaction);
- LOG.info("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
+ LOG.trace("Forwarding DOM Transaction: {} as Binding Transaction: {}.", domTransaction.getIdentifier(),
baTransaction.getIdentifier());
return forwardedTransaction;
}
}
+ /**
+ * Manager responsible for instantiating forwarders responsible for
+ * forwarding of RPC invocations from DOM Broker to Binding Aware Broker
+ *
+ */
private class DomToBindingRpcForwardingManager implements
- RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>> {
+ RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>,
+ RouterInstantiationListener,
+ GlobalRpcRegistrationListener {
private final Map<Class<? extends RpcService>, DomToBindingRpcForwarder> forwarders = new WeakHashMap<>();
+ private RpcProviderRegistryImpl registryImpl;
+
+ public RpcProviderRegistryImpl getRegistryImpl() {
+ return registryImpl;
+ }
+
+ public void setRegistryImpl(RpcProviderRegistryImpl registryImpl) {
+ this.registryImpl = registryImpl;
+ }
+
+ @Override
+ public void onGlobalRpcRegistered(Class<? extends RpcService> cls) {
+ getRpcForwarder(cls, null);
+ }
+
+ @Override
+ public void onGlobalRpcUnregistered(Class<? extends RpcService> cls) {
+ // NOOP
+ }
+
+ @Override
+ public void onRpcRouterCreated(RpcRouter<?> router) {
+ Class<? extends BaseIdentity> ctx = router.getContexts().iterator().next();
+ getRpcForwarder(router.getServiceType(), ctx);
+ }
@Override
public void onRouteChange(RouteChange<RpcContextIdentifier, InstanceIdentifier<?>> change) {
} else {
potential = new DomToBindingRpcForwarder(service, context);
}
+
forwarders.put(service, potential);
return potential;
}
}
- private class DomToBindingRpcForwarder implements RpcImplementation {
+ private class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
private final Set<QName> supportedRpcs;
private final WeakReference<Class<? extends RpcService>> rpcServiceType;
private Set<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> registrations;
+ private Map<QName, RpcInvocationStrategy> strategiesByQName = new HashMap<>();
+ private WeakHashMap<Method, RpcInvocationStrategy> strategiesByMethod = new WeakHashMap<>();
public DomToBindingRpcForwarder(Class<? extends RpcService> service) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
- for (QName rpc : supportedRpcs) {
- biRpcRegistry.addRpcImplementation(rpc, this);
+ try {
+ for (QName rpc : supportedRpcs) {
+ RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
+ strategiesByMethod.put(strategy.targetMethod, strategy);
+ strategiesByQName.put(rpc, strategy);
+ biRpcRegistry.addRpcImplementation(rpc, this);
+ }
+
+ } catch (Exception e) {
+ LOG.error("Could not forward Rpcs of type {}", service.getName());
}
registrations = ImmutableSet.of();
}
+ /**
+ * Constructor for Routed RPC Forwareder.
+ *
+ * @param service
+ * @param context
+ */
public DomToBindingRpcForwarder(Class<? extends RpcService> service, Class<? extends BaseIdentity> context) {
this.rpcServiceType = new WeakReference<Class<? extends RpcService>>(service);
this.supportedRpcs = mappingService.getRpcQNamesFor(service);
- registrations = new HashSet<>();
- for (QName rpc : supportedRpcs) {
- registrations.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
+ Builder<RoutedRpcRegistration> registrationsBuilder = ImmutableSet
+ .<org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration> builder();
+ try {
+ for (QName rpc : supportedRpcs) {
+ RpcInvocationStrategy strategy = createInvocationStrategy(rpc, service);
+ strategiesByMethod.put(strategy.targetMethod, strategy);
+ strategiesByQName.put(rpc, strategy);
+ registrationsBuilder.add(biRpcRegistry.addRoutedRpcImplementation(rpc, this));
+ }
+ createDefaultDomForwarder();
+ } catch (Exception e) {
+ LOG.error("Could not forward Rpcs of type {}", service.getName(),e);
}
- registrations = ImmutableSet.copyOf(registrations);
+ registrations = registrationsBuilder.build();
}
public void registerPaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
}
}
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if(EQUALS_METHOD.equals(method)) {
+ return false;
+ }
+ RpcInvocationStrategy strategy = strategiesByMethod.get(method);
+ checkState(strategy != null);
+ checkArgument(args.length <= 2);
+ if(args.length == 1) {
+ checkArgument(args[0] instanceof DataObject);
+ return strategy.forwardToDomBroker((DataObject) args[0]);
+ }
+ return strategy.forwardToDomBroker(null);
+ }
+
public void removePaths(Class<? extends BaseIdentity> context, Class<? extends RpcService> service,
Set<InstanceIdentifier<?>> set) {
QName ctx = BindingReflections.findQName(context);
return supportedRpcs;
}
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public void createDefaultDomForwarder() {
+ if (baRpcRegistryImpl != null) {
+ Class<?> cls = rpcServiceType.get();
+ ClassLoader clsLoader = cls.getClassLoader();
+ RpcService proxy = (RpcService) Proxy.newProxyInstance(clsLoader, new Class<?>[] { cls }, this);
+
+ RpcRouter rpcRouter = baRpcRegistryImpl.getRpcRouter(rpcServiceType.get());
+ rpcRouter.registerDefaultService(proxy);
+ }
+ }
+
@Override
public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode domInput) {
checkArgument(rpc != null);
checkState(rpcService != null);
CompositeNode domUnwrappedInput = domInput.getFirstCompositeByName(QName.create(rpc, "input"));
try {
- return resolveInvocationStrategy(rpc, rpcType).invokeOn(rpcService, domUnwrappedInput);
+ return resolveInvocationStrategy(rpc).invokeOn(rpcService, domUnwrappedInput);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
- private RpcInvocationStrategy resolveInvocationStrategy(final QName rpc,
+ private RpcInvocationStrategy resolveInvocationStrategy(QName rpc) {
+ return strategiesByQName.get(rpc);
+ }
+
+ private RpcInvocationStrategy createInvocationStrategy(final QName rpc,
final Class<? extends RpcService> rpcType) throws Exception {
return ClassLoaderUtils.withClassLoader(rpcType.getClassLoader(), new Callable<RpcInvocationStrategy>() {
@Override
RpcInvocationStrategy strategy = null;
if (outputClass.isPresent()) {
if (inputClass.isPresent()) {
- strategy = new DefaultInvocationStrategy(targetMethod, outputClass.get(), inputClass.get());
+ strategy = new DefaultInvocationStrategy(rpc,targetMethod, outputClass.get(), inputClass.get());
} else {
- strategy = new NoInputNoOutputInvocationStrategy(targetMethod);
+ strategy = new NoInputNoOutputInvocationStrategy(rpc,targetMethod);
}
} else {
strategy = null;
private abstract class RpcInvocationStrategy {
protected final Method targetMethod;
+ protected final QName rpc;
- public RpcInvocationStrategy(Method targetMethod) {
+ public RpcInvocationStrategy(QName rpc,Method targetMethod) {
this.targetMethod = targetMethod;
+ this.rpc = rpc;
}
+ public abstract Future<RpcResult<?>> forwardToDomBroker(DataObject input);
+
public abstract RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput)
throws Exception;
private WeakReference<Class> outputClass;
@SuppressWarnings({ "rawtypes", "unchecked" })
- public DefaultInvocationStrategy(Method targetMethod, Class<?> outputClass,
+ public DefaultInvocationStrategy(QName rpc, Method targetMethod, Class<?> outputClass,
Class<? extends DataContainer> inputClass) {
- super(targetMethod);
+ super(rpc,targetMethod);
this.outputClass = new WeakReference(outputClass);
this.inputClass = new WeakReference(inputClass);
}
RpcResult<?> bindingResult = result.get();
return Rpcs.getRpcResult(true);
}
+
+ @Override
+ public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ if(biRouter != null) {
+ CompositeNode xml = mappingService.toDataDom(input);
+ CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc,ImmutableList.<Node<?>>of(xml));
+ RpcResult<CompositeNode> result = biRouter.invokeRpc(rpc, wrappedXml);
+ Object baResultValue = null;
+ if(result.getResult() != null) {
+ baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), result.getResult());
+ }
+ RpcResult<?> baResult = Rpcs.getRpcResult(result.isSuccessful(), baResultValue, result.getErrors());
+ return Futures.<RpcResult<?>>immediateFuture(baResult);
+ }
+ return Futures.<RpcResult<?>>immediateFuture(Rpcs.getRpcResult(false));
+ }
}
private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy {
- public NoInputNoOutputInvocationStrategy(Method targetMethod) {
- super(targetMethod);
+ public NoInputNoOutputInvocationStrategy(QName rpc, Method targetMethod) {
+ super(rpc,targetMethod);
}
public RpcResult<CompositeNode> uncheckedInvoke(RpcService rpcService, CompositeNode domInput) throws Exception {
RpcResult<Void> bindingResult = result.get();
return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors());
}
+
+ @Override
+ public Future<RpcResult<?>> forwardToDomBroker(DataObject input) {
+ return Futures.immediateFuture(null);
+ }
}
public boolean isRpcForwarding() {
import org.opendaylight.controller.sal.dom.broker.MountPointManagerImpl;
import org.opendaylight.controller.sal.dom.broker.impl.DataStoreStatsWrapper;
import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import static com.google.common.base.Preconditions.*;
-public class BindingTestContext implements AutoCloseable {
+public class BindingTestContext implements AutoCloseable, SchemaContextProvider {
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier TREE_ROOT = org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
.builder().toInstance();
private MountPointManagerImpl biMountImpl;
+ private SchemaContext schemaContext;
+
+ public SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
protected BindingTestContext(ListeningExecutorService executor, ClassPool classPool, boolean startWithSchema) {
this.executor = executor;
this.classPool = classPool;
}
public void updateYangSchema(String[] files) {
- SchemaContext context = getContext(files);
+ schemaContext = getContext(files);
if (schemaAwareDataStore != null) {
- schemaAwareDataStore.onGlobalContextUpdated(context);
+ schemaAwareDataStore.onGlobalContextUpdated(schemaContext);
}
if (mappingServiceImpl != null) {
- mappingServiceImpl.onGlobalContextUpdated(context);
+ mappingServiceImpl.onGlobalContextUpdated(schemaContext);
}
}
checkState(executor != null);
biBrokerImpl = new BrokerImpl();
biBrokerImpl.setExecutor(executor);
- biBrokerImpl.setRouter(new RpcRouterImpl("test"));
+ biBrokerImpl.setRouter(new SchemaAwareRpcBroker("/", this));
}
public void startBindingNotificationBroker() {
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.binding.test.connect.dom;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertTrue;
+
import java.math.BigInteger;
import java.util.Collections;
+import java.util.Set;
import java.util.concurrent.Future;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.controller.sal.binding.test.util.BindingBrokerTestFactory;
import org.opendaylight.controller.sal.binding.test.util.BindingTestContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlowRemoved;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yangtools.yang.binding.BaseIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import static junit.framework.Assert.*;
-
-import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
public static final NodeId NODE_B = new NodeId("b");
public static final NodeId NODE_C = new NodeId("c");
public static final NodeId NODE_D = new NodeId("d");
+
+ private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
+ private static final QName ADD_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "add-flow");
public static final InstanceIdentifier<Node> BA_NODE_A_ID = createBANodeIdentifier(NODE_A);
public static final InstanceIdentifier<Node> BA_NODE_B_ID = createBANodeIdentifier(NODE_B);
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_C_ID = createBINodeIdentifier(NODE_C);
public static final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier BI_NODE_D_ID = createBINodeIdentifier(NODE_D);
- private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id");
- private static final QName ADD_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "add-flow");
- private static final QName REMOVE_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "remove-flow");
- private static final QName UPDATE_FLOW_QNAME = QName.create(NodeFlowRemoved.QNAME, "update-flow");
+
@Before
public void setup() {
assertEquals(addFlowA, flowService.getReceivedAddFlows().get(BA_NODE_A_ID).iterator().next());
}
- public void bindingRpcInvoker_DomRoutedProviderTest() {
-
+ @Test
+ public void bindingRpcInvoker_DomRoutedProviderTest() throws Exception {
+ AddFlowOutputBuilder builder = new AddFlowOutputBuilder();
+ builder.setTransactionId(new TransactionId(BigInteger.valueOf(10)));
+ final AddFlowOutput output = builder.build();
+ org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration registration = biRpcRegistry.addRoutedRpcImplementation(ADD_FLOW_QNAME, new RpcImplementation() {
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ CompositeNode result = testContext.getBindingToDomMappingService().toDataDom(output);
+ return Rpcs.getRpcResult(true, result, ImmutableList.<RpcError>of());
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return ImmutableSet.of(ADD_FLOW_QNAME);
+ }
+ });
+ registration.registerPath(NodeContext.QNAME, BI_NODE_C_ID);
+
+ SalFlowService baFlowInvoker = baRpcRegistry.getRpcService(SalFlowService.class);
+ Future<RpcResult<AddFlowOutput>> baResult = baFlowInvoker.addFlow(addFlow(BA_NODE_C_ID).setPriority(500).build());
+ assertNotNull(baResult);
+ assertEquals(output,baResult.get().getResult());
}
private CompositeNode toDomRpcInput(DataObject addFlowA) {
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>concepts</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
override final registerCommitHandler(P path, DataCommitHandler<P, D> commitHandler) {\r
val registration = new DataCommitHandlerRegistrationImpl(path, commitHandler, this);\r
commitHandlers.put(path, registration)\r
- LOG.info("Registering Commit Handler {} for path: {}",commitHandler,path);\r
+ LOG.trace("Registering Commit Handler {} for path: {}",commitHandler,path);\r
for(listener : commitHandlerRegistrationListeners) {\r
try {\r
listener.instance.onRegister(registration);\r
protected final def removeCommitHandler(DataCommitHandlerRegistrationImpl<P, D> registration) {\r
commitHandlers.remove(registration.path, registration);\r
\r
- LOG.info("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
+ LOG.trace("Removing Commit Handler {} for path: {}",registration.instance,registration.path);\r
for(listener : commitHandlerRegistrationListeners) {\r
try {\r
listener.instance.onUnregister(registration);\r
\r
val transactionId = transaction.identifier;\r
\r
- log.info("Transaction: {} Started.",transactionId);\r
+ log.trace("Transaction: {} Started.",transactionId);\r
// requesting commits\r
val Iterable<DataCommitHandler<P, D>> commitHandlers = dataBroker.affectedCommitHandlers(affectedPaths);\r
val List<DataCommitTransaction<P, D>> handlerTransactions = new ArrayList();\r
dataBroker.failedTransactionsCount.andIncrement\r
return rollback(handlerTransactions, e);\r
}\r
- log.info("Transaction: {} Finished successfully.",transactionId);\r
+ log.trace("Transaction: {} Finished successfully.",transactionId);\r
dataBroker.finishedTransactionsCount.andIncrement;\r
return Rpcs.getRpcResult(true, TransactionStatus.COMMITED, Collections.emptySet());\r
\r
\r
public abstract class AbstractDataTransaction<P extends Path<P>, D> extends AbstractDataModification<P, D> {\r
\r
+ private static val LOG = LoggerFactory.getLogger(AbstractDataTransaction);
+
@Property\r
private val Object identifier;\r
\r
_identifier = identifier;\r
broker = dataBroker;\r
status = TransactionStatus.NEW;\r
+ LOG.debug("Transaction {} Allocated.", identifier);
\r
//listeners = new ListenerRegistry<>();\r
}\r
protected abstract def void onStatusChange(TransactionStatus status);\r
\r
public def changeStatus(TransactionStatus status) {\r
+ LOG.debug("Transaction {} transitioned from {} to {}", identifier, this.status, status);
this.status = status;\r
onStatusChange(status);\r
}\r
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>concepts</artifactId>
- <version>0.1.1-SNAPSHOT</version>
+ <version>0.6.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
package org.opendaylight.controller.sal.core.api;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangePublisher;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-public interface RpcProvisionRegistry extends BrokerService {
+public interface RpcProvisionRegistry extends BrokerService, RouteChangePublisher<RpcRoutingContext, InstanceIdentifier> {
/**
* Registers an implementation of the rpc.
*/
RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
throws IllegalArgumentException;
+
+ ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation);
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.core.api;
import java.util.EventListener;
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.core.api;
+
+import java.io.Serializable;
+
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+
+public class RpcRoutingContext implements Immutable, Serializable {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -9079324728075883325L;
+
+ private final QName context;
+ private final QName rpc;
+
+
+ private RpcRoutingContext(QName context, QName rpc) {
+ super();
+ this.context = context;
+ this.rpc = rpc;
+ }
+
+ public static final RpcRoutingContext create(QName context, QName rpc) {
+ return new RpcRoutingContext(context, rpc);
+ }
+
+ public QName getContext() {
+ return context;
+ }
+
+ public QName getRpc() {
+ return rpc;
+ }
+
+ @Override
+ public String toString() {
+ return "RpcRoutingContext [context=" + context + ", rpc=" + rpc + "]";
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((context == null) ? 0 : context.hashCode());
+ result = prime * result + ((rpc == null) ? 0 : rpc.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ RpcRoutingContext other = (RpcRoutingContext) obj;
+ if (context == null) {
+ if (other.context != null)
+ return false;
+ } else if (!context.equals(other.context))
+ return false;
+ if (rpc == null) {
+ if (other.rpc != null)
+ return false;
+ } else if (!rpc.equals(other.rpc))
+ return false;
+ return true;
+ }
+}
<configuration>
<instructions>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ <Export-Package>
+ org.opendaylight.controller.sal.dom.broker.spi
+ </Export-Package>
<Private-Package>
- org.opendaylight.controller.sal.dom.broker.*,
- org.opendaylight.controller.config.yang.md.sal.dom.impl
+ org.opendaylight.controller.sal.dom.broker,
+ org.opendaylight.controller.sal.dom.broker.impl,
+ org.opendaylight.controller.sal.dom.broker.osgi,
+ org.opendaylight.controller.config.yang.md.sal.dom.impl,
+ org.opendaylight.controller.config.yang.md.sal.dom.statistics,
+ org.opendaylight.yangtools.yang.util
</Private-Package>
<Import-Package>
*
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/config</source>
+ <source>src/main/xtend-gen</source>
</sources>
</configuration>
</execution>
public java.lang.AutoCloseable createInstance() {
SchemaServiceImpl newInstance = new SchemaServiceImpl();
newInstance.setContext(getBundleContext());
- newInstance.setParser(new YangParserImpl());
newInstance.start();
return newInstance;
}
+++ /dev/null
-package org.opendaylight.controller.sal.dom.broker;
-
-public class $ModuleInfo {
-
-
-}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker
-import org.osgi.framework.ServiceRegistration
-import org.opendaylight.controller.sal.core.api.model.SchemaService
+import java.util.Hashtable
import org.opendaylight.controller.sal.core.api.data.DataBrokerService
import org.opendaylight.controller.sal.core.api.data.DataProviderService
-import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore
+import org.opendaylight.controller.sal.core.api.data.DataStore
+import org.opendaylight.controller.sal.core.api.model.SchemaService
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
import org.opendaylight.controller.sal.core.api.mount.MountService
-import org.osgi.framework.BundleContext
-import java.util.Hashtable
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-import org.opendaylight.controller.sal.core.api.data.DataStore
import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
+import org.osgi.framework.BundleContext
+import org.osgi.framework.ServiceRegistration
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders
class BrokerConfigActivator implements AutoCloseable {
-
-
+
private static val ROOT = InstanceIdentifier.builder().toInstance();
@Property
private var DataBrokerImpl dataService;
-
+
private var ServiceRegistration<SchemaService> schemaReg;
private var ServiceRegistration<DataBrokerService> dataReg;
private var ServiceRegistration<DataProviderService> dataProviderReg;
private var ServiceRegistration<MountService> mountReg;
private var ServiceRegistration<MountProvisionService> mountProviderReg;
- private var SchemaServiceImpl schemaService;
+ private var SchemaService schemaService;
private var MountPointManagerImpl mountService;
-
+
SchemaAwareDataStoreAdapter wrappedStore
- public def void start(BrokerImpl broker,DataStore store,BundleContext context) {
+ public def void start(BrokerImpl broker, DataStore store, BundleContext context) {
val emptyProperties = new Hashtable<String, String>();
broker.setBundleContext(context);
-
- broker.setRouter(new RpcRouterImpl("Rpc router"))
- schemaService = new SchemaServiceImpl();
- schemaService.setContext(context);
- schemaService.setParser(new YangParserImpl());
- schemaService.start();
+
+ val serviceRef = context.getServiceReference(SchemaService);
+ schemaService = context.getService(serviceRef);
schemaReg = context.registerService(SchemaService, schemaService, emptyProperties);
-
+
+ broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders.fromSchemaService(schemaService)));
+
dataService = new DataBrokerImpl();
dataService.setExecutor(broker.getExecutor());
-
+
dataReg = context.registerService(DataBrokerService, dataService, emptyProperties);
dataProviderReg = context.registerService(DataProviderService, dataService, emptyProperties);
wrappedStore = new SchemaAwareDataStoreAdapter();
wrappedStore.changeDelegate(store);
wrappedStore.setValidationEnabled(false);
-
- context.registerService(SchemaServiceListener,wrappedStore,emptyProperties)
-
+
+ context.registerService(SchemaServiceListener, wrappedStore, emptyProperties)
+
dataService.registerConfigurationReader(ROOT, wrappedStore);
dataService.registerCommitHandler(ROOT, wrappedStore);
dataService.registerOperationalReader(ROOT, wrappedStore);
-
+
mountService = new MountPointManagerImpl();
mountService.setDataBroker(dataService);
-
+
mountReg = context.registerService(MountService, mountService, emptyProperties);
- mountProviderReg = context.registerService(MountProvisionService, mountService, emptyProperties);
+ mountProviderReg = context.registerService(MountProvisionService, mountService, emptyProperties);
}
override def close() {
mountReg?.unregister();
mountProviderReg?.unregister();
}
-
-}
\ No newline at end of file
+
+}
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry
import org.opendaylight.controller.sal.core.api.RpcImplementation
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable {
private static val log = LoggerFactory.getLogger(BrokerImpl);
override registerConsumer(Consumer consumer, BundleContext ctx) {
checkPredicates(consumer);
- log.info("Registering consumer " + consumer);
+ log.trace("Registering consumer " + consumer);
val session = newSessionFor(consumer, ctx);
consumer.onSessionInitiated(session);
sessions.add(session);
router.addRoutedRpcImplementation(rpcType,implementation);
}
+ override addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return router.addRpcRegistrationListener(listener);
+ }
+
+ override <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> registerRouteChangeListener(L listener) {
+ return router.registerRouteChangeListener(listener);
+ }
+
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration;
import org.opendaylight.controller.md.sal.common.api.data.DataReader;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
import org.opendaylight.controller.sal.common.DataStoreIdentifier;
import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.core.api.data.DataValidator;
import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance;
import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
-import org.opendaylight.controller.sal.dom.broker.impl.DataReaderRouter;
import org.opendaylight.controller.sal.dom.broker.impl.NotificationRouterImpl;
-import org.opendaylight.controller.sal.dom.broker.impl.RpcRouterImpl;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
import org.opendaylight.controller.sal.dom.broker.spi.NotificationRouter;
-import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.InstanceIdentifierBuilder;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class MountPointImpl implements MountProvisionInstance {
+public class MountPointImpl implements MountProvisionInstance, SchemaContextProvider {
- private final RpcRouter rpcs;
+ private final SchemaAwareRpcBroker rpcs;
private final DataBrokerImpl dataReader;
private final NotificationRouter notificationRouter;
private final DataReader<InstanceIdentifier,CompositeNode> readWrapper;
public MountPointImpl(InstanceIdentifier path) {
this.mountPath = path;
- rpcs = new RpcRouterImpl("");
+ rpcs = new SchemaAwareRpcBroker(path.toString(),this);
dataReader = new DataBrokerImpl();
notificationRouter = new NotificationRouterImpl();
readWrapper = new ReadWrapper();
@Override
public Future<RpcResult<CompositeNode>> rpc(QName type, CompositeNode input) {
- // TODO Auto-generated method stub
return null;
}
RegistrationListener<DataCommitHandlerRegistration<InstanceIdentifier, CompositeNode>> commitHandlerListener) {
return dataReader.registerCommitHandlerListener(commitHandlerListener);
}
+
+ @Override
+ public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return rpcs.registerRouteChangeListener(listener);
+ }
}
}
def registerMountPoint(MountPointImpl impl) {
- dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
- dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
+ //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper);
+ //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper);
}
private void sendNotification(CompositeNode notification) {
QName type = notification.getNodeType();
Collection<NotificationListener> toNotify = listeners.get(type);
- log.info("Publishing notification " + type);
+ log.trace("Publishing notification " + type);
if (toNotify == null) {
// No listeners were registered - returns.
.create();
private boolean closed = false;
-
+
public Registration<NotificationListener> addNotificationListener(QName notification,
NotificationListener listener) {
checkSessionState();
consumerListeners.put(notification, listener);
listeners.put(notification, listener);
- log.info("Registered listener for notification: " + notification);
+ log.trace("Registered listener for notification: " + notification);
return null; // Return registration Object.
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
package org.opendaylight.controller.sal.dom.broker;
-import java.io.IOException;
-import java.io.InputStream;
+import static com.google.common.base.Preconditions.checkState;
+
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Enumeration;
-import java.util.List;
-import java.util.Set;
-import java.util.zip.Checksum;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.osgi.util.tracker.BundleTracker;
-import org.osgi.util.tracker.BundleTrackerCustomizer;
-import org.osgi.util.tracker.ServiceTracker;
-import org.osgi.util.tracker.ServiceTrackerCustomizer;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser;
-import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.util.URLSchemaContextResolver;
import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.ServiceReference;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
-import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-
-import static com.google.common.base.Preconditions.*;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
public class SchemaServiceImpl implements //
+ SchemaContextProvider, //
SchemaService, //
ServiceTrackerCustomizer<SchemaServiceListener, SchemaServiceListener>, //
AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(SchemaServiceImpl.class);
private ListenerRegistry<SchemaServiceListener> listeners;
- private YangModelParser parser;
-
+
private BundleContext context;
private BundleScanner scanner = new BundleScanner();
- /**
- * Map of currently problematic yang files that should get fixed eventually
- * after all events are received.
- */
- private final Multimap<Bundle, URL> inconsistentBundlesToYangURLs = HashMultimap.create();
- private final Multimap<Bundle, URL> consistentBundlesToYangURLs = HashMultimap.create();
- private BundleTracker<Object> bundleTracker;
- private final YangStoreCache cache = new YangStoreCache();
+ private BundleTracker<ImmutableSet<Registration<URL>>> bundleTracker;
+
+ private final URLSchemaContextResolver contextResolver = new URLSchemaContextResolver();
private ServiceTracker<SchemaServiceListener, SchemaServiceListener> listenerTracker;
+ private boolean starting = true;
+
public ListenerRegistry<SchemaServiceListener> getListeners() {
return listeners;
}
this.listeners = listeners;
}
- public YangModelParser getParser() {
- return parser;
- }
-
- public void setParser(YangModelParser parser) {
- this.parser = parser;
- }
-
public BundleContext getContext() {
return context;
}
}
public void start() {
- checkState(parser != null);
checkState(context != null);
if (listeners == null) {
listeners = new ListenerRegistry<>();
}
- listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, this);
- bundleTracker = new BundleTracker<Object>(context, BundleEvent.RESOLVED | BundleEvent.UNRESOLVED, scanner);
+ listenerTracker = new ServiceTracker<>(context, SchemaServiceListener.class, SchemaServiceImpl.this);
+ bundleTracker = new BundleTracker<ImmutableSet<Registration<URL>>>(context, BundleEvent.RESOLVED
+ | BundleEvent.UNRESOLVED, scanner);
bundleTracker.open();
listenerTracker.open();
+ starting = false;
+ tryToUpdateSchemaContext();
}
- public SchemaContext getGlobalContext() {
- return getSchemaContextSnapshot();
+ @Override
+ public SchemaContext getSchemaContext() {
+ return getGlobalContext();
}
- public synchronized SchemaContext getSchemaContextSnapshot() {
- Optional<SchemaContext> yangStoreOpt = cache.getCachedSchemaContext(consistentBundlesToYangURLs);
- if (yangStoreOpt.isPresent()) {
- return yangStoreOpt.get();
- }
- SchemaContext snapshot = createSnapshot(parser, consistentBundlesToYangURLs);
- updateCache(snapshot);
- return snapshot;
+ public SchemaContext getGlobalContext() {
+ return contextResolver.getSchemaContext().orNull();
}
@Override
public void addModule(Module module) {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public SchemaContext getSessionContext() {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public void removeModule(Module module) {
- // TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
@Override
public void close() throws Exception {
- bundleTracker.close();
- // FIXME: Add listeners.close();
-
- }
-
- private synchronized boolean tryToUpdateState(Collection<URL> changedURLs, Multimap<Bundle, URL> proposedNewState,
- boolean adding) {
- Preconditions.checkArgument(!changedURLs.isEmpty(), "No change can occur when no URLs are changed");
-
- try {
- // consistent state
- // merge into
- SchemaContext snapshot = createSnapshot(parser, proposedNewState);
- consistentBundlesToYangURLs.clear();
- consistentBundlesToYangURLs.putAll(proposedNewState);
- inconsistentBundlesToYangURLs.clear();
- // update cache
- updateCache(snapshot);
- logger.info("SchemaService updated to new consistent state");
- logger.trace("SchemaService updated to new consistent state containing {}", consistentBundlesToYangURLs);
-
- // notifyListeners(changedURLs, adding);
- return true;
- } catch (Exception e) {
- // inconsistent state
- logger.debug(
- "SchemaService is falling back on last consistent state containing {}, inconsistent yang files {}",
- consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, e);
- return false;
+ if (bundleTracker != null) {
+ bundleTracker.close();
}
+ if (listenerTracker != null) {
+ listenerTracker.close();
+ }
+ // FIXME: Add listeners.close();
}
- private static Collection<InputStream> fromUrlsToInputStreams(Multimap<Bundle, URL> multimap) {
- return Collections2.transform(multimap.values(), new Function<URL, InputStream>() {
-
- @Override
- public InputStream apply(URL url) {
- try {
- return url.openStream();
- } catch (IOException e) {
- logger.warn("Unable to open stream from {}", url);
- throw new IllegalStateException("Unable to open stream from " + url, e);
- }
- }
- });
- }
-
- private static SchemaContext createSnapshot(YangModelParser parser, Multimap<Bundle, URL> multimap) {
- List<InputStream> models = new ArrayList<>(fromUrlsToInputStreams(multimap));
- Set<Module> modules = parser.parseYangModelsFromStreams(models);
- SchemaContext yangStoreSnapshot = parser.resolveSchemaContext(modules);
- return yangStoreSnapshot;
- }
-
- private void updateCache(SchemaContext snapshot) {
- cache.cacheYangStore(consistentBundlesToYangURLs, snapshot);
+ private void updateContext(SchemaContext snapshot) {
Object[] services = listenerTracker.getServices();
if (services != null) {
for (Object rawListener : services) {
}
}
- private class BundleScanner implements BundleTrackerCustomizer<Object> {
+ private class BundleScanner implements BundleTrackerCustomizer<ImmutableSet<Registration<URL>>> {
@Override
- public Object addingBundle(Bundle bundle, BundleEvent event) {
+ public ImmutableSet<Registration<URL>> addingBundle(Bundle bundle, BundleEvent event) {
- // Ignore system bundle:
- // system bundle might have config-api on classpath &&
- // config-api contains yang files =>
- // system bundle might contain yang files from that bundle
if (bundle.getBundleId() == 0) {
- return bundle;
+ return ImmutableSet.of();
}
Enumeration<URL> enumeration = bundle.findEntries("META-INF/yang", "*.yang", false);
- if (enumeration != null && enumeration.hasMoreElements()) {
- synchronized (this) {
- List<URL> addedURLs = new ArrayList<>();
- while (enumeration.hasMoreElements()) {
- URL url = enumeration.nextElement();
- addedURLs.add(url);
- }
- logger.trace("Bundle {} has event {}, bundle state {}, URLs {}", bundle, event, bundle.getState(),
- addedURLs);
- // test that yang store is consistent
- Multimap<Bundle, URL> proposedNewState = HashMultimap.create(consistentBundlesToYangURLs);
- proposedNewState.putAll(inconsistentBundlesToYangURLs);
- proposedNewState.putAll(bundle, addedURLs);
- boolean adding = true;
-
- if (tryToUpdateState(addedURLs, proposedNewState, adding) == false) {
- inconsistentBundlesToYangURLs.putAll(bundle, addedURLs);
- }
- }
+ Builder<Registration<URL>> builder = ImmutableSet.<Registration<URL>> builder();
+ while (enumeration != null && enumeration.hasMoreElements()) {
+ Registration<URL> reg = contextResolver.registerSource(enumeration.nextElement());
+ builder.add(reg);
+ }
+ ImmutableSet<Registration<URL>> urls = builder.build();
+ if(urls.isEmpty()) {
+ return urls;
}
- return bundle;
+ tryToUpdateSchemaContext();
+ return urls;
}
@Override
- public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+ public void modifiedBundle(Bundle bundle, BundleEvent event, ImmutableSet<Registration<URL>> object) {
logger.debug("Modified bundle {} {} {}", bundle, event, object);
}
*/
@Override
- public synchronized void removedBundle(Bundle bundle, BundleEvent event, Object object) {
- inconsistentBundlesToYangURLs.removeAll(bundle);
- Collection<URL> consistentURLsToBeRemoved = consistentBundlesToYangURLs.removeAll(bundle);
-
- if (consistentURLsToBeRemoved.isEmpty()) {
- return; // no change
- }
- boolean adding = false;
- // notifyListeners(consistentURLsToBeRemoved, adding);
- }
- }
-
- private static final class YangStoreCache {
-
- Set<URL> cachedUrls;
- SchemaContext cachedContextSnapshot;
-
- Optional<SchemaContext> getCachedSchemaContext(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = setFromMultimapValues(bundlesToYangURLs);
- if (cachedUrls != null && cachedUrls.equals(urls)) {
- Preconditions.checkState(cachedContextSnapshot != null);
- return Optional.of(cachedContextSnapshot);
+ public synchronized void removedBundle(Bundle bundle, BundleEvent event, ImmutableSet<Registration<URL>> urls) {
+ for (Registration<URL> url : urls) {
+ try {
+ url.close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
- return Optional.absent();
- }
-
- private static Set<URL> setFromMultimapValues(Multimap<Bundle, URL> bundlesToYangURLs) {
- Set<URL> urls = Sets.newHashSet(bundlesToYangURLs.values());
- Preconditions.checkState(bundlesToYangURLs.size() == urls.size());
- return urls;
- }
-
- void cacheYangStore(Multimap<Bundle, URL> urls, SchemaContext ctx) {
- this.cachedUrls = setFromMultimapValues(urls);
- this.cachedContextSnapshot = ctx;
+ tryToUpdateSchemaContext();
}
}
SchemaServiceListener listener = context.getService(reference);
SchemaContext _ctxContext = getGlobalContext();
- if (getContext() != null) {
+ if (_ctxContext != null) {
listener.onGlobalContextUpdated(_ctxContext);
}
return listener;
}
+ public synchronized void tryToUpdateSchemaContext() {
+ if(starting ) {
+ return;
+ }
+ Optional<SchemaContext> schema = contextResolver.tryToUpdateSchemaContext();
+ if(schema.isPresent()) {
+ updateContext(schema.get());
+ }
+ }
+
@Override
public void modifiedService(ServiceReference<SchemaServiceListener> reference, SchemaServiceListener service) {
// NOOP
private void sendNotification(CompositeNode notification) {
QName type = notification.getNodeType();
Collection<Registration<NotificationListener>> toNotify = listeners.get(type);
- log.info("Publishing notification " + type);
+ log.trace("Publishing notification " + type);
if (toNotify == null) {
// No listeners were registered - returns.
+++ /dev/null
-package org.opendaylight.controller.sal.dom.broker.impl
-
-import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter
-import org.opendaylight.yangtools.concepts.Identifiable
-import org.opendaylight.yangtools.yang.common.QName
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import static com.google.common.base.Preconditions.*;
-import java.util.Map
-import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration
-import java.util.concurrent.ConcurrentHashMap
-import java.util.Set
-import java.util.Collections
-import org.opendaylight.yangtools.concepts.AbstractObjectRegistration
-import org.opendaylight.controller.sal.core.api.RpcRegistrationListener
-import org.slf4j.LoggerFactory
-import org.opendaylight.yangtools.concepts.util.ListenerRegistry
-import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
-
-class RpcRouterImpl implements RpcRouter, Identifiable<String> {
-
- static val log = LoggerFactory.getLogger(RpcRouterImpl)
-
- Map<QName, RpcRegistration> implementations = new ConcurrentHashMap();
-
- @Property
- val Set<QName> supportedRpcs = Collections.unmodifiableSet(implementations.keySet);
-
- private val rpcRegistrationListeners = new ListenerRegistry<RpcRegistrationListener>();
-
- @Property
- val String identifier;
-
- new(String name) {
- _identifier = name;
- }
-
- override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
- checkNotNull(rpcType, "Rpc Type should not be null");
- checkNotNull(implementation, "Implementation should not be null.");
- val reg = new RoutedRpcRegistrationImpl(rpcType, implementation, this);
- implementations.put(rpcType, reg)
-
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
-
- return reg;
- }
-
- override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException {
- checkNotNull(rpcType, "Rpc Type should not be null");
- checkNotNull(implementation, "Implementation should not be null.");
- checkState(!implementations.containsKey(rpcType), "Provider for supplied rpc is already registered.");
- val reg = new RpcRegistrationImpl(rpcType, implementation, this);
- implementations.put(rpcType, reg)
-
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationAdded(rpcType);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
-
- return reg;
-
- }
-
- override invokeRpc(QName rpc, CompositeNode input) {
- checkNotNull(rpc, "Rpc Type should not be null");
-
- val impl = implementations.get(rpc);
- checkState(impl !== null, "Provider for supplied rpc is not registered.");
-
- return impl.instance.invokeRpc(rpc, input);
- }
-
- def remove(RpcRegistrationImpl impl) {
- val existing = implementations.get(impl.type);
- if (existing == impl) {
- implementations.remove(impl.type);
- }
- for (listener : rpcRegistrationListeners.listeners) {
- try {
- listener.instance.onRpcImplementationRemoved(impl.type);
- } catch (Exception e) {
- log.error("Unhandled exception during invoking listener", e);
- }
- }
- }
-
- override addRpcRegistrationListener(RpcRegistrationListener listener) {
- rpcRegistrationListeners.register(listener);
- }
-
-}
-
-class RpcRegistrationImpl extends AbstractObjectRegistration<RpcImplementation> implements RpcRegistration {
-
- @Property
- val QName type;
-
- @Property
- var RpcRouterImpl router;
-
- new(QName type, RpcImplementation instance, RpcRouterImpl router) {
- super(instance)
- _type = type
- _router = router
- }
-
- override protected removeRegistration() {
- router.remove(this);
- }
-}
-class RoutedRpcRegistrationImpl extends RpcRegistrationImpl implements RoutedRpcRegistration {
-
-
- new(QName type, RpcImplementation instance, RpcRouterImpl router) {
- super(type,instance,router)
- }
-
- override protected removeRegistration() {
- router.remove(this);
- }
- override registerPath(QName context, InstanceIdentifier path) {
- //
-
- }
-
- override unregisterPath(QName context, InstanceIdentifier path) {
- //
- }
-}
}
if (schema == null) {
- LOG.info("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
+ LOG.warn("Validation not performed for {}. Reason: YANG Schema not present.", modification.getIdentifier());
return;
}
}
--- /dev/null
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+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.impl.routing.RoutingUtils;
+import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration;
+import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
+import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter;
+import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.Identifiable;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+
+public class SchemaAwareRpcBroker implements RpcRouter, Identifiable<String> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SchemaAwareRpcBroker.class);
+
+ private static final QName CONTEXT_REFERENCE = QName.create("urn:opendaylight:yang:extension:yang-ext",
+ "2013-07-09", "context-reference");
+ private final ListenerRegistry<RpcRegistrationListener> rpcRegistrationListeners = new ListenerRegistry<>();
+ private final ListenerRegistry<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeChangeListeners = new ListenerRegistry<>();
+
+
+ private final String identifier;
+ private final ConcurrentMap<QName, RpcImplementation> implementations = new ConcurrentHashMap<>();
+ private RpcImplementation defaultImplementation;
+ private SchemaContextProvider schemaProvider;
+
+ public SchemaAwareRpcBroker(String identifier, SchemaContextProvider schemaProvider) {
+ super();
+ this.identifier = identifier;
+ this.schemaProvider = schemaProvider;
+ }
+
+ public RpcImplementation getDefaultImplementation() {
+ return defaultImplementation;
+ }
+
+ public void setDefaultImplementation(RpcImplementation defaultImplementation) {
+ this.defaultImplementation = defaultImplementation;
+ }
+
+ public SchemaContextProvider getSchemaProvider() {
+ return schemaProvider;
+ }
+
+ public void setSchemaProvider(SchemaContextProvider schemaProvider) {
+ this.schemaProvider = schemaProvider;
+ }
+
+ @Override
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ checkArgument(rpcType != null, "RPC Type should not be null");
+ checkArgument(implementation != null, "RPC Implementatoin should not be null");
+ return getOrCreateRoutedRpcRouter(rpcType).addRoutedRpcImplementation(rpcType, implementation);
+ }
+
+ private RoutedRpcSelector getOrCreateRoutedRpcRouter(QName rpcType) {
+ RoutedRpcSelector potential = getRoutedRpcRouter(rpcType);
+ if (potential != null) {
+ return potential;
+ }
+ synchronized (implementations) {
+ potential = getRoutedRpcRouter(rpcType);
+ if (potential != null) {
+ return potential;
+ }
+ RpcDefinition definition = findRpcDefinition(rpcType);
+ RoutingStrategy strategy = getRoutingStrategy(definition);
+ checkState(strategy instanceof RoutedRpcStrategy, "Rpc %s is not routed.", rpcType);
+ potential = new RoutedRpcSelector((RoutedRpcStrategy) strategy, this);
+ implementations.put(rpcType, potential);
+ return potential;
+ }
+ }
+
+ private RoutedRpcSelector getRoutedRpcRouter(QName rpcType) {
+ RpcImplementation potential = implementations.get(rpcType);
+ if (potential != null) {
+ checkState(potential instanceof RoutedRpcSelector, "Rpc %s is not routed.", rpcType);
+ return (RoutedRpcSelector) potential;
+ }
+ return null;
+
+ }
+
+ @Override
+ public RpcRegistration addRpcImplementation(QName rpcType, RpcImplementation implementation)
+ throws IllegalArgumentException {
+ checkArgument(rpcType != null, "RPC Type should not be null");
+ checkArgument(implementation != null, "RPC Implementatoin should not be null");
+ checkState(!hasRpcImplementation(rpcType), "Implementation already registered");
+ RpcDefinition definition = findRpcDefinition(rpcType);
+ checkArgument(!isRoutedRpc(definition), "RPC Type must not be routed.");
+ GlobalRpcRegistration reg = new GlobalRpcRegistration(rpcType, implementation, this);
+ return reg;
+ }
+
+ private boolean isRoutedRpc(RpcDefinition definition) {
+ return getRoutingStrategy(definition) instanceof RoutedRpcStrategy;
+ }
+
+ @Override
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener) {
+ return rpcRegistrationListeners.register(listener);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return ImmutableSet.copyOf(implementations.keySet());
+ }
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ return findRpcImplemention(rpc).invokeRpc(rpc, input);
+ }
+
+ private RpcImplementation findRpcImplemention(QName rpc) {
+ checkArgument(rpc != null, "Rpc name should not be null");
+ RpcImplementation potentialImpl = implementations.get(rpc);
+ if (potentialImpl != null) {
+ return potentialImpl;
+ }
+ potentialImpl = defaultImplementation;
+ checkState(potentialImpl != null, "Implementation is not available.");
+ return potentialImpl;
+ }
+
+ private boolean hasRpcImplementation(QName rpc) {
+ return implementations.containsKey(rpc);
+ }
+
+ private RpcDefinition findRpcDefinition(QName rpcType) {
+ checkArgument(rpcType != null, "Rpc name must be supplied.");
+ checkState(schemaProvider != null, "Schema Provider is not available.");
+ SchemaContext ctx = schemaProvider.getSchemaContext();
+ checkState(ctx != null, "YANG Schema Context is not available.");
+ Module module = ctx.findModuleByNamespaceAndRevision(rpcType.getNamespace(), rpcType.getRevision());
+ checkState(module != null, "YANG Module is not available.");
+ return findRpcDefinition(rpcType, module.getRpcs());
+ }
+
+ static private RpcDefinition findRpcDefinition(QName rpcType, Set<RpcDefinition> rpcs) {
+ checkState(rpcs != null, "Rpc schema is not available.");
+ for (RpcDefinition rpc : rpcs) {
+ if (rpcType.equals(rpc.getQName())) {
+ return rpc;
+ }
+ }
+ throw new IllegalArgumentException("Supplied Rpc Type is not defined.");
+ }
+
+ private RoutingStrategy getRoutingStrategy(RpcDefinition rpc) {
+ ContainerSchemaNode input = rpc.getInput();
+ if (input != null) {
+ for (DataSchemaNode schemaNode : input.getChildNodes()) {
+ Optional<QName> context = getRoutingContext(schemaNode);
+ if (context.isPresent()) {
+ return createRoutedStrategy(rpc, context.get(), schemaNode.getQName());
+ }
+ }
+ }
+ return createGlobalStrategy(rpc);
+ }
+
+ private static RoutingStrategy createRoutedStrategy(RpcDefinition rpc, QName context, QName leafNode) {
+ return new RoutedRpcStrategy(rpc.getQName(), context, leafNode);
+ }
+
+ private Optional<QName> getRoutingContext(DataSchemaNode schemaNode) {
+ for (UnknownSchemaNode extension : schemaNode.getUnknownSchemaNodes()) {
+ if (CONTEXT_REFERENCE.equals(extension.getNodeType())) {
+ return Optional.fromNullable(extension.getQName());
+ }
+ ;
+ }
+ return Optional.absent();
+ }
+
+ private static RoutingStrategy createGlobalStrategy(RpcDefinition rpc) {
+ GlobalRpcStrategy ret = new GlobalRpcStrategy(rpc.getQName());
+ return ret;
+ }
+
+ private static abstract class RoutingStrategy implements Identifiable<QName> {
+
+ private final QName identifier;
+
+ public RoutingStrategy(QName identifier) {
+ super();
+ this.identifier = identifier;
+ }
+
+ @Override
+ public QName getIdentifier() {
+ return identifier;
+ }
+ }
+
+ private static class GlobalRpcStrategy extends RoutingStrategy {
+
+ public GlobalRpcStrategy(QName identifier) {
+ super(identifier);
+ }
+ }
+
+ private static class RoutedRpcStrategy extends RoutingStrategy {
+
+ private final QName context;
+ private final QName leaf;
+
+ public RoutedRpcStrategy(QName identifier, QName ctx, QName leaf) {
+ super(identifier);
+ this.context = ctx;
+ this.leaf = leaf;
+ }
+
+ public QName getContext() {
+ return context;
+ }
+
+ public QName getLeaf() {
+ return leaf;
+ }
+ }
+
+ private static class RoutedRpcSelector implements RpcImplementation, AutoCloseable, Identifiable<QName> {
+
+ private final RoutedRpcStrategy strategy;
+ private final Set<QName> supportedRpcs;
+ private RpcImplementation defaultDelegate;
+ private final ConcurrentMap<InstanceIdentifier, RoutedRpcRegImpl> implementations = new ConcurrentHashMap<>();
+ private SchemaAwareRpcBroker router;
+
+ public RoutedRpcSelector(RoutedRpcStrategy strategy, SchemaAwareRpcBroker router) {
+ super();
+ this.strategy = strategy;
+ supportedRpcs = ImmutableSet.of(strategy.getIdentifier());
+ this.router = router;
+ }
+
+ @Override
+ public QName getIdentifier() {
+ return strategy.getIdentifier();
+ }
+
+ @Override
+ public void close() throws Exception {
+
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return supportedRpcs;
+ }
+
+ public RoutedRpcRegistration addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) {
+ return new RoutedRpcRegImpl(rpcType, implementation, this);
+ }
+
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+ CompositeNode inputContainer = input.getFirstCompositeByName(QName.create(rpc,"input"));
+ checkArgument(inputContainer != null, "Rpc payload must contain input element");
+ SimpleNode<?> routeContainer = inputContainer.getFirstSimpleByName(strategy.getLeaf());
+ checkArgument(routeContainer != null, "Leaf %s must be set with value", strategy.getLeaf());
+ Object route = routeContainer.getValue();
+ RpcImplementation potential = null;
+ if (route != null) {
+ RoutedRpcRegImpl potentialReg = implementations.get(route);
+ if (potentialReg != null) {
+ potential = potentialReg.getInstance();
+ }
+ }
+ if (potential == null) {
+ potential = defaultDelegate;
+ }
+ checkState(potential != null, "No implementation is available for rpc:%s path:%s", rpc, route);
+ return potential.invokeRpc(rpc, input);
+ }
+
+ public void addPath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
+ //checkArgument(strategy.getContext().equals(context),"Supplied context is not supported.");
+ RoutedRpcRegImpl previous = implementations.put(path, routedRpcRegImpl);
+ if (previous == null) {
+ router.notifyPathAnnouncement(context,strategy.getIdentifier(), path);
+ }
+
+ }
+
+ public void removePath(QName context, InstanceIdentifier path, RoutedRpcRegImpl routedRpcRegImpl) {
+ boolean removed = implementations.remove(path, routedRpcRegImpl);
+ if (removed) {
+ router.notifyPathWithdrawal(context, strategy.getIdentifier(), path);
+ }
+ }
+ }
+
+ private static class GlobalRpcRegistration extends AbstractObjectRegistration<RpcImplementation> implements
+ RpcRegistration {
+ private final QName type;
+ private SchemaAwareRpcBroker router;
+
+ public GlobalRpcRegistration(QName type, RpcImplementation instance, SchemaAwareRpcBroker router) {
+ super(instance);
+ this.type = type;
+ this.router = router;
+ }
+
+ @Override
+ public QName getType() {
+ return type;
+ }
+
+ @Override
+ protected void removeRegistration() {
+ if (router != null) {
+ router.remove(this);
+ router = null;
+ }
+ }
+ }
+
+ private static class RoutedRpcRegImpl extends AbstractObjectRegistration<RpcImplementation> implements
+ RoutedRpcRegistration {
+
+ private final QName type;
+ private RoutedRpcSelector router;
+
+ public RoutedRpcRegImpl(QName rpcType, RpcImplementation implementation, RoutedRpcSelector routedRpcSelector) {
+ super(implementation);
+ this.type = rpcType;
+ router = routedRpcSelector;
+ }
+
+ @Override
+ public void registerPath(QName context, InstanceIdentifier path) {
+ router.addPath(context, path, this);
+ }
+
+ @Override
+ public void unregisterPath(QName context, InstanceIdentifier path) {
+ router.removePath(context, path, this);
+ }
+
+ @Override
+ protected void removeRegistration() {
+
+ }
+
+ @Override
+ public QName getType() {
+ return type;
+ }
+
+ }
+
+ private void remove(GlobalRpcRegistration registration) {
+ implementations.remove(registration.getType(), registration);
+ }
+
+ private void notifyPathAnnouncement(QName context, QName identifier, InstanceIdentifier path) {
+ RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
+ RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.announcementChange(contextWrapped , path);
+ for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+ try {
+ routeListener.getInstance().onRouteChange(change);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking onRouteChange for {}",routeListener.getInstance(),e);
+
+ }
+ }
+
+ }
+
+
+
+ private void notifyPathWithdrawal(QName context,QName identifier, InstanceIdentifier path) {
+ RpcRoutingContext contextWrapped = RpcRoutingContext.create(context, identifier);
+ RouteChange<RpcRoutingContext, InstanceIdentifier> change = RoutingUtils.removalChange(contextWrapped , path);
+ for(ListenerRegistration<RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> routeListener : routeChangeListeners) {
+ try {
+ routeListener.getInstance().onRouteChange(change);
+ } catch (Exception e) {
+ LOG.error("Unhandled exception during invoking onRouteChange for {}",routeListener.getInstance(),e);
+ }
+ }
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+ L listener) {
+ return routeChangeListeners.registerWithType(listener);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public interface SchemaContextProvider {
+
+ SchemaContext getSchemaContext();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker.impl;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yangtools.concepts.Delegator;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class SchemaContextProviders {
+
+ public static final SchemaContextProvider fromSchemaService(SchemaService schemaService) {
+ if (schemaService instanceof SchemaContextProvider) {
+ return (SchemaContextProvider) schemaService;
+ }
+ return new SchemaServiceAdapter(schemaService);
+ }
+
+ private final static class SchemaServiceAdapter implements SchemaContextProvider, Delegator<SchemaService> {
+
+ private final SchemaService service;
+
+ public SchemaServiceAdapter(SchemaService service) {
+ super();
+ this.service = service;
+ }
+
+ @Override
+ public SchemaContext getSchemaContext() {
+ return service.getGlobalContext();
+ }
+
+ @Override
+ public SchemaService getDelegate() {
+ return service;
+ }
+
+ @Override
+ public String toString() {
+ return "SchemaServiceAdapter [service=" + service + "]";
+ }
+ }
+}
@Override
public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input);
-
- ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(RpcRegistrationListener listener);
}
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/config</source>
+ <source>src/main/xtend-gen</source>
</sources>
</configuration>
</execution>
request.addLeaf("version", revision.get());
}
- device.logger.info("Loading YANG schema source for {}:{}", moduleName, revision);
+ device.logger.trace("Loading YANG schema source for {}:{}", moduleName, revision);
RpcResult<CompositeNode> schemaReply = device.invokeRpc(GET_SCHEMA_QNAME, request.toInstance());
if (schemaReply.isSuccessful()) {
String schemaBody = getSchemaFromRpc(schemaReply.getResult());
if (schemaBody != null) {
- device.logger.info("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
+ device.logger.trace("YANG Schema successfully retrieved from remote for {}:{}", moduleName, revision);
return Optional.of(schemaBody);
}
}
- device.logger.info("YANG shcema was not successfully retrieved.");
+ device.logger.warn("YANG shcema was not successfully retrieved.");
return Optional.absent();
}
}
return null;
}
-
+
public static final boolean isSupportedFor(Set<QName> capabilities) {
return capabilities.contains(IETF_NETCONF_MONITORING);
}
import config { prefix config; revision-date 2013-04-05; }
import threadpool {prefix th;}
import netty {prefix netty;}
- import ietf-inet-types {prefix inet;}
import opendaylight-md-sal-dom {prefix dom;}
description
--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>sal-remote</artifactId>
+ <packaging>jar</packaging>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+ <properties>
+ <opendaylight.binding.version>0.6.0-SNAPSHOT</opendaylight.binding.version>
+ <opendaylight.yang.version>0.5.9-SNAPSHOT</opendaylight.yang.version>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${opendaylight.yang.version}</version>
+ <executions>
+ <execution>
+ <id>sal-remote</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>
+ org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
+ </codeGeneratorClass>
+ <outputBaseDir>
+ target/generated-sources/
+ </outputBaseDir>
+ </generator>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>target/site/models</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${opendaylight.binding.version}</version>
+ <type>jar</type>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>1.8</version>
+ <executions>
+ <execution>
+ <id>add-source</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>add-source</goal>
+ </goals>
+ <configuration>
+ <sources>
+ <source>${project.build.directory}/generated-sources/</source>
+ </sources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.restconf.service.impl;
+
+import java.util.concurrent.Future;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.BeginTransactionOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateDataChangeEventSubscriptionInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateDataChangeEventSubscriptionOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateNotificationStreamInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.CreateNotificationStreamOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.remote.rev140114.SalRemoteService;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class SalRemoteServiceImpl implements SalRemoteService {
+ @Override
+ public Future<RpcResult<BeginTransactionOutput>> beginTransaction() {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<CreateDataChangeEventSubscriptionOutput>> createDataChangeEventSubscription(CreateDataChangeEventSubscriptionInput input) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<CreateNotificationStreamOutput>> createNotificationStream(CreateNotificationStreamInput input) {
+ return null;
+ }
+}
--- /dev/null
+module sal-remote {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote";
+ prefix "sal-remote";
+
+
+ organization "Cisco Systems, Inc.";
+ contact "Martin Bobak <mbobak@cisco.com>";
+
+ description
+ "This module contains the definition of types related to
+ Internet Assigned Numbers Authority.
+
+ Copyright (c)2013 Cisco Systems, Inc. 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";
+
+ revision "2014-01-14" {
+ description
+ "Initial revision";
+ }
+
+
+ typedef q-name {
+ type string;
+ reference
+ "http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#QName";
+ }
+
+ rpc create-data-change-event-subscription {
+ input {
+ leaf path {
+ type instance-identifier;
+ description "Subtree path. ";
+ }
+ }
+ output {
+ leaf stream-name {
+ type string;
+ description "Notification stream name.";
+ }
+ }
+ }
+
+ notification data-changed-notification {
+ description "Data change notification.";
+ leaf data-change-event {
+ type instance-identifier;
+ }
+ }
+
+ rpc create-notification-stream {
+ input {
+ leaf-list notifications {
+ type q-name;
+ description "Notification QNames";
+ }
+ }
+ output {
+ leaf notification-stream-identifier {
+ type string;
+ description "Unique notification stream identifier, in which notifications will be propagated";
+ }
+ }
+ }
+
+ rpc begin-transaction{
+ output{
+ anyxml data-modification-transaction{
+ description "DataModificationTransaction xml";
+ }
+ }
+ }
+
+}
\ No newline at end of file
<groupId> org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
-
+ <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>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-module-junit4</artifactId>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-api-mockito</artifactId>
- </dependency>
- <dependency>
- <groupId>org.powermock</groupId>
- <artifactId>powermock-core</artifactId>
- </dependency>
-
</dependencies>
</Import-Package>
<Export-Package>
org.opendaylight.controller.config.yang.md.sal.remote.rpc,
- org.opendaylight.controller.sal.connector.remoterpc,
- org.opendaylight.controller.sal.connector.remoterpc.*,
+ org.opendaylight.controller.sal.connector.remoterpc.util,
+ org.opendaylight.controller.sal.connector.remoterpc.dto,
+ org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient,
+ org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcServer,
+ org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcProvider
</Export-Package>
<Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
</instructions>
*/
package org.opendaylight.controller.config.yang.md.sal.remote.rpc;
-import org.opendaylight.controller.sal.connector.remoterpc.Client;
-import org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcProvider;
-import org.opendaylight.controller.sal.connector.remoterpc.RoutingTableProvider;
-import org.opendaylight.controller.sal.connector.remoterpc.ServerImpl;
+import org.opendaylight.controller.sal.connector.remoterpc.*;
import org.opendaylight.controller.sal.core.api.Broker;
import org.osgi.framework.BundleContext;
public java.lang.AutoCloseable createInstance() {
Broker broker = getDomBrokerDependency();
- RoutingTableProvider provider = new RoutingTableProvider(bundleContext);
-
+
+
final int port = getPort() != null ? getPort() : ZEROMQ_ROUTER_PORT;
ServerImpl serverImpl = new ServerImpl(port);
- Client clientImpl = new Client();
+ ClientImpl clientImpl = new ClientImpl();
+
+ RoutingTableProvider provider = new RoutingTableProvider(bundleContext,serverImpl);
+
+
RemoteRpcProvider facade = new RemoteRpcProvider(serverImpl, clientImpl);
facade.setRoutingTableProvider(provider );
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+public class CapturedMessageHandler implements Runnable {
+
+ private Logger _logger = LoggerFactory.getLogger(CapturedMessageHandler.class);
+
+ private ZMQ.Socket socket;
+
+ public CapturedMessageHandler(ZMQ.Socket socket){
+ this.socket = socket;
+ }
+
+ @Override
+ public void run(){
+
+ try {
+ while (!Thread.currentThread().isInterrupted()){
+ String message = socket.recvStr();
+ _logger.debug("Captured [{}]", message);
+ }
+ } catch (Exception e) {
+ _logger.error("Exception raised [{}]", e.getMessage());
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.MessageWrapper;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.*;
-
-import static com.google.common.base.Preconditions.*;
-
-/**
- * An implementation of {@link RpcImplementation} that makes remote RPC calls
- */
-public class Client implements RemoteRpcClient {
-
- private final Logger _logger = LoggerFactory.getLogger(Client.class);
-
- private final LinkedBlockingQueue<MessageWrapper> requestQueue = new LinkedBlockingQueue<MessageWrapper>(100);
-
- private final ExecutorService pool = Executors.newSingleThreadExecutor();
- private final long TIMEOUT = 5000; // in ms
-
- private RoutingTableProvider routingTableProvider;
-
- public RoutingTableProvider getRoutingTableProvider() {
- return routingTableProvider;
- }
-
- public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
- this.routingTableProvider = routingTableProvider;
- }
-
- public LinkedBlockingQueue<MessageWrapper> getRequestQueue() {
- return requestQueue;
- }
-
- @Override
- public Set<QName> getSupportedRpcs() {
- // TODO: Find the entries from routing table
- return Collections.emptySet();
- }
-
- public void start() {
- pool.execute(new Sender(this));
-
- }
-
- public void stop() {
-
- _logger.debug("Client stopping...");
- Context.getInstance().getZmqContext().term();
- _logger.debug("ZMQ context terminated");
-
- pool.shutdown(); // intiate shutdown
- try {
- if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
- pool.shutdownNow();
- if (!pool.awaitTermination(10, TimeUnit.SECONDS))
- _logger.error("Client thread pool did not shut down");
- }
- } catch (InterruptedException e) {
- // (Re-)Cancel if current thread also interrupted
- pool.shutdownNow();
- // Preserve interrupt status
- Thread.currentThread().interrupt();
- }
- _logger.debug("Client stopped");
- }
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
-
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- String address = lookupRemoteAddress(routeId);
-
- Message request = new Message.MessageBuilder().type(Message.MessageType.REQUEST)
- .sender(Context.getInstance().getLocalUri()).recipient(address).route(routeId)
- .payload(XmlUtils.compositeNodeToXml(input)).build();
-
- List<RpcError> errors = new ArrayList<RpcError>();
-
- try (SocketPair pair = new SocketPair()) {
-
- MessageWrapper messageWrapper = new MessageWrapper(request, pair.getSender());
- process(messageWrapper);
- Message response = parseMessage(pair.getReceiver());
-
- CompositeNode payload = XmlUtils.xmlToCompositeNode((String) response.getPayload());
-
- return Rpcs.getRpcResult(true, payload, errors);
-
- } catch (Exception e) {
- collectErrors(e, errors);
- return Rpcs.getRpcResult(false, null, errors);
- }
-
- }
-
- public void process(MessageWrapper msg) throws TimeoutException, InterruptedException {
- _logger.debug("Processing message [{}]", msg);
-
- boolean success = requestQueue.offer(msg, TIMEOUT, TimeUnit.MILLISECONDS);
- if (!success)
- throw new TimeoutException("Queue is full");
- }
-
- /**
- * Block on socket for reply
- *
- * @param receiver
- * @return
- */
- private Message parseMessage(ZMQ.Socket receiver) throws IOException, ClassNotFoundException {
- return (Message) Message.deserialize(receiver.recv());
- }
-
- /**
- * Find address for the given route identifier in routing table
- *
- * @param routeId
- * route identifier
- * @return remote network address
- */
- private String lookupRemoteAddress(RpcRouter.RouteIdentifier routeId) {
- checkNotNull(routeId, "route must not be null");
-
- Optional<RoutingTable<String, String>> routingTable = routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
-
- Set<String> addresses = routingTable.get().getRoutes(routeId.toString());
- checkNotNull(addresses, "Address not found for route [%s]", routeId);
- checkState(addresses.size() == 1, "Multiple remote addresses found for route [%s], \nonly 1 expected", routeId); // its
- // a
- // global
- // service.
-
- String address = addresses.iterator().next();
- checkNotNull(address, "Address not found for route [%s]", routeId);
-
- return address;
- }
-
- private void collectErrors(Exception e, List<RpcError> errors) {
- if (e == null)
- return;
- if (errors == null)
- errors = new ArrayList<RpcError>();
-
- errors.add(RpcErrors.getRpcError(null, null, null, null, e.getMessage(), null, e.getCause()));
- for (Throwable t : e.getSuppressed()) {
- errors.add(RpcErrors.getRpcError(null, null, null, null, t.getMessage(), null, t));
- }
- }
-
- @Override
- public void close() throws Exception {
- stop();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import com.google.common.base.Optional;
+import org.opendaylight.controller.sal.common.util.RpcErrors;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.connector.api.RpcRouter;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
+import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
+import org.opendaylight.controller.sal.core.api.RpcImplementation;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+/**
+ * An implementation of {@link RpcImplementation} that makes
+ * remote RPC calls
+ */
+public class ClientImpl implements RemoteRpcClient {
+
+ private final Logger _logger = LoggerFactory.getLogger(ClientImpl.class);
+
+ private ZMQ.Context context = ZMQ.context(1);
+ private ClientRequestHandler handler;
+ private RoutingTableProvider routingTableProvider;
+
+ public ClientImpl(){
+ handler = new ClientRequestHandler(context);
+ start();
+ }
+
+ public ClientImpl(ClientRequestHandler handler){
+ this.handler = handler;
+ start();
+ }
+
+ public RoutingTableProvider getRoutingTableProvider() {
+ return routingTableProvider;
+ }
+
+ public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
+ this.routingTableProvider = routingTableProvider;
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs(){
+ //TODO: Find the entries from routing table
+ return Collections.emptySet();
+ }
+
+ @Override
+ public void start() {/*NOOPS*/}
+
+ @Override
+ public void stop() {
+ closeZmqContext();
+ handler.close();
+ _logger.info("Stopped");
+ }
+
+ @Override
+ public void close(){
+ stop();
+ }
+
+ /**
+ * Finds remote server that can execute this rpc and sends a message to it
+ * requesting execution.
+ * The call blocks until a response from remote server is received. Its upto
+ * the client of this API to implement a timeout functionality.
+ *
+ * @param rpc remote service to be executed
+ * @param input payload for the remote service
+ * @return
+ */
+ @Override
+ public RpcResult<CompositeNode> invokeRpc(QName rpc, CompositeNode input) {
+
+ RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+ routeId.setType(rpc);
+
+ String address = lookupRemoteAddress(routeId);
+
+ Message request = new Message.MessageBuilder()
+ .type(Message.MessageType.REQUEST)
+ .sender(Context.getInstance().getLocalUri())
+ .recipient(address)
+ .route(routeId)
+ .payload(XmlUtils.compositeNodeToXml(input))
+ .build();
+
+ List<RpcError> errors = new ArrayList<RpcError>();
+
+ try{
+ Message response = handler.handle(request);
+ CompositeNode payload = null;
+
+ if ( response != null )
+ payload = XmlUtils.xmlToCompositeNode((String) response.getPayload());
+
+ return Rpcs.getRpcResult(true, payload, errors);
+
+ } catch (Exception e){
+ collectErrors(e, errors);
+ return Rpcs.getRpcResult(false, null, errors);
+ }
+
+ }
+
+ /**
+ * Find address for the given route identifier in routing table
+ * @param routeId route identifier
+ * @return remote network address
+ */
+ private String lookupRemoteAddress(RpcRouter.RouteIdentifier routeId){
+ checkNotNull(routeId, "route must not be null");
+
+ Optional<RoutingTable<String, String>> routingTable = routingTableProvider.getRoutingTable();
+ checkNotNull(routingTable.isPresent(), "Routing table is null");
+
+ Set<String> addresses = routingTable.get().getRoutes(routeId.toString());
+ checkNotNull(addresses, "Address not found for route [%s]", routeId);
+ checkState(addresses.size() == 1,
+ "Multiple remote addresses found for route [%s], \nonly 1 expected", routeId); //its a global service.
+
+ String address = addresses.iterator().next();
+ checkNotNull(address, "Address not found for route [%s]", routeId);
+
+ return address;
+ }
+
+ private void collectErrors(Exception e, List<RpcError> errors){
+ if (e == null) return;
+ if (errors == null) errors = new ArrayList<RpcError>();
+
+ errors.add(RpcErrors.getRpcError(null, null, null, null, e.getMessage(), null, e.getCause()));
+ for (Throwable t : e.getSuppressed()) {
+ errors.add(RpcErrors.getRpcError(null, null, null, null, t.getMessage(), null, t));
+ }
+ }
+
+ /**
+ * Closes ZMQ Context. It tries to gracefully terminate the context. If
+ * termination takes more than a second, its forcefully shutdown.
+ */
+ private void closeZmqContext() {
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ FutureTask zmqTermination = new FutureTask(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ if (context != null)
+ context.term();
+ _logger.debug("ZMQ Context terminated");
+ } catch (Exception e) {
+ _logger.debug("ZMQ Context termination threw exception [{}]. Continuing shutdown...", e);
+ }
+ }
+ }, null);
+
+ exec.execute(zmqTermination);
+
+ try {
+ zmqTermination.get(1L, TimeUnit.SECONDS);
+ } catch (Exception e) {/*ignore and continue with shutdown*/}
+
+ exec.shutdownNow();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ */
+class ClientRequestHandler implements AutoCloseable{
+
+ private Logger _logger = LoggerFactory.getLogger(ClientRequestHandler.class);
+ private final String DEFAULT_NAME = "remoterpc-client-worker";
+ private final String INPROC_PROTOCOL_PREFIX = "inproc://";
+ private final String TCP_PROTOCOL_PREFIX = "tcp://";
+
+ private ZMQ.Context context;
+
+ /*
+ * Worker thread pool. Each thread runs a ROUTER-DEALER pair
+ */
+ private ExecutorService workerPool;
+
+ /*
+ * Set of remote servers this client is currently connected to
+ */
+ private Map<String, String> connectedServers;
+
+ protected ClientRequestHandler(ZMQ.Context context) {
+ this.context = context;
+ connectedServers = new ConcurrentHashMap<String, String>();
+ start();
+ }
+
+ /**
+ * Starts a pool of worker as needed. A worker thread that has not been used for 5 min
+ * is terminated and removed from the pool. If thread dies due to an exception, its
+ * restarted.
+ */
+ private void start(){
+
+ workerPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+ 5L, TimeUnit.MINUTES,
+ new SynchronousQueue<Runnable>()){
+
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ if (isTerminating() || isTerminated() || isShutdown())
+ return;
+
+ Worker worker = (Worker) r;
+ Preconditions.checkState( worker != null );
+ String remoteServerAddress = worker.getRemoteServerAddress();
+ connectedServers.remove(remoteServerAddress);
+
+ if ( t != null ){
+ _logger.debug("Exception caught while terminating worker [{},{}]. " +
+ "Restarting worker...", t.getClass(), t.getMessage());
+
+ connectedServers.put(remoteServerAddress, remoteServerAddress);
+ this.execute(r);
+ }
+ super.afterExecute(r, null);
+ }
+ };
+ }
+
+ public Message handle(Message request) throws IOException, ClassNotFoundException, InterruptedException {
+
+ String remoteServerAddress = request.getRecipient();
+ //if we already have router-dealer bridge setup for this address the send request
+ //otherwise first create the bridge and then send request
+ if ( connectedServers.containsKey(remoteServerAddress) )
+ return sendMessage(request, remoteServerAddress);
+ else{
+ workerPool.execute(new Worker(remoteServerAddress));
+ connectedServers.put(remoteServerAddress, remoteServerAddress);
+ //give little time for sockets to get initialized
+ //TODO: Add socket ping-pong message to ensure socket init rather than thread.sleep.
+ Thread.sleep(1000);
+ return sendMessage(request, remoteServerAddress);
+ }
+ }
+
+ private Message sendMessage(Message request, String address) throws IOException, ClassNotFoundException {
+ Message response = null;
+ ZMQ.Socket socket = context.socket(ZMQ.REQ);
+
+ try {
+ socket.connect( INPROC_PROTOCOL_PREFIX + address);
+ socket.send(Message.serialize(request));
+ _logger.debug("Request sent. Waiting for reply...");
+ byte[] reply = socket.recv(0);
+ _logger.debug("Response received");
+ response = (Message) Message.deserialize(reply);
+ } finally {
+ socket.close();
+ }
+ return response;
+ }
+
+ /**
+ * This gets called automatically if used with try-with-resources
+ */
+ @Override
+ public void close(){
+ workerPool.shutdown();
+ _logger.info("Request Handler closed");
+ }
+
+ /**
+ * Total number of workers in the pool. Number of workers represent
+ * number of remote servers {@link org.opendaylight.controller.sal.connector.remoterpc.ClientImpl} is connected to.
+ *
+ * @return worker count
+ */
+ public int getWorkerCount(){
+
+ if (workerPool == null) return 0;
+
+ return ((ThreadPoolExecutor)workerPool).getActiveCount();
+ }
+ /**
+ * Handles RPC request
+ */
+ private class Worker implements Runnable {
+ private String name;
+ private String remoteServer; //<servername:rpc-port>
+
+ public Worker(String address){
+ this.name = DEFAULT_NAME + "[" + address + "]";
+ this.remoteServer = address;
+ }
+
+ public String getRemoteServerAddress(){
+ return this.remoteServer;
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName(name);
+ _logger.debug("Starting ... ");
+
+ ZMQ.Socket router = context.socket(ZMQ.ROUTER);
+ ZMQ.Socket dealer = context.socket(ZMQ.DEALER);
+
+ try {
+ int success = router.bind(INPROC_PROTOCOL_PREFIX + remoteServer);
+ Preconditions.checkState(-1 != success, "Could not bind to " + remoteServer);
+
+ dealer.connect(TCP_PROTOCOL_PREFIX + remoteServer);
+
+ _logger.info("Worker started for [{}]", remoteServer);
+
+ //TODO: Add capture handler
+ //This code will block until the zmq context is terminated.
+ ZMQ.proxy(router, dealer, null);
+
+ } catch (Exception e) {
+ _logger.debug("Ignoring exception [{}, {}]", e.getClass(), e.getMessage());
+ } finally {
+ try {
+ router.close();
+ dealer.close();
+ } catch (Exception x) {
+ _logger.debug("Exception while closing socket [{}]", x);
+ }
+ _logger.debug("Closing...");
+ }
+ }
+ }
+}
public class Context {
private ZMQ.Context zmqContext = ZMQ.context(1);
private String uri;
+ private final String DEFAULT_RPC_PORT = "5554";
private static Context _instance = new Context();
public String getLocalUri(){
uri = (uri != null) ? uri
- : new StringBuilder("tcp://").append(getIpAddress()).append(":")
+ : new StringBuilder().append(getIpAddress()).append(":")
.append(getRpcPort()).toString();
return uri;
public String getRpcPort(){
String rpcPort = (System.getProperty("rpc.port") != null)
? System.getProperty("rpc.port")
- : "5554";
+ : DEFAULT_RPC_PORT;
return rpcPort;
}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.controller.sal.connector.remoterpc;
import org.opendaylight.controller.sal.core.api.RpcImplementation;
-package org.opendaylight.controller.sal.connector.remoterpc;
+/*
+ * 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
+ */
-import java.util.Collection;
-import java.util.Set;
-import java.util.concurrent.ExecutorService;
+package org.opendaylight.controller.sal.connector.remoterpc;
-import org.opendaylight.controller.sal.connector.remoterpc.Client;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.Provider.ProviderFunctionality;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import java.util.Collection;
+import java.util.Set;
+
public class RemoteRpcProvider implements
RemoteRpcServer,
RemoteRpcClient,
Provider {
private final ServerImpl server;
- private final Client client;
+ private final ClientImpl client;
private RoutingTableProvider provider;
@Override
}
- public RemoteRpcProvider(ServerImpl server, Client client) {
+ public RemoteRpcProvider(ServerImpl server, ClientImpl client) {
this.server = server;
this.client = client;
}
public void setBrokerSession(ProviderSession session) {
server.setBrokerSession(session);
}
- public void setServerPool(ExecutorService serverPool) {
- server.setServerPool(serverPool);
- }
+// public void setServerPool(ExecutorService serverPool) {
+// server.setServerPool(serverPool);
+// }
public void start() {
- client.setRoutingTableProvider(provider);
- server.setRoutingTableProvider(provider);
+ //when listener was being invoked and addRPCImplementation was being
+ //called the client was null.
+ server.setClient(client);
server.start();
client.start();
+
+
}
- public void onRouteUpdated(String key, Set values) {
- server.onRouteUpdated(key, values);
- }
- public void onRouteDeleted(String key) {
- server.onRouteDeleted(key);
- }
-
+
@Override
public Collection<ProviderFunctionality> getProviderFunctionality() {
client.close();
}
-
-
-
@Override
public void stop() {
server.stop();
-package org.opendaylight.controller.sal.connector.remoterpc;
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.connector.remoterpc;
public interface RemoteRpcServer extends AutoCloseable {
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.controller.sal.connector.remoterpc;
+import com.google.common.base.Optional;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
-import com.google.common.base.Optional;
-
public class RoutingTableProvider implements AutoCloseable {
@SuppressWarnings("rawtypes")
final ServiceTracker<RoutingTable,RoutingTable> tracker;
+
+ private RoutingTableImpl routingTableImpl = null;
+
+ final private RouteChangeListener routeChangeListener;
- public RoutingTableProvider(BundleContext ctx) {
+ public RoutingTableProvider(BundleContext ctx,RouteChangeListener rcl) {
@SuppressWarnings("rawtypes")
ServiceTracker<RoutingTable, RoutingTable> rawTracker = new ServiceTracker<>(ctx, RoutingTable.class, null);
tracker = rawTracker;
tracker.open();
+
+ routeChangeListener = rcl;
}
public Optional<RoutingTable<String, String>> getRoutingTable() {
@SuppressWarnings("unchecked")
RoutingTable<String,String> tracked = tracker.getService();
+
+ if(tracked instanceof RoutingTableImpl){
+ if(routingTableImpl != tracked){
+ routingTableImpl= (RoutingTableImpl)tracked;
+ routingTableImpl.setRouteChangeListener(routeChangeListener);
+ }
+ }
+
return Optional.fromNullable(tracked);
}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.MessageWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A class encapsulating {@link ZMQ.Socket} of type {@link ZMQ.REQ}.
- * It adds following capabilities:
- * <li> Retry logic - Tries 3 times before giving up
- * <li> Request times out after {@link TIMEOUT} property
- * <li> The limitation of {@link ZMQ.REQ}/{@link ZMQ.REP} pair is that no 2 requests can be sent before
- * the response for the 1st request is received. To overcome that, this socket queues all messages until
- * the previous request has been responded.
- */
-public class RpcSocket {
-
- // Constants
- public static final int TIMEOUT = 2000;
- public static final int QUEUE_SIZE = 10;
- public static final int NUM_RETRIES = 3;
- private static final Logger log = LoggerFactory.getLogger(RpcSocket.class);
-
- private ZMQ.Socket socket;
- private ZMQ.Poller poller;
- private String address;
- private SocketState state;
- private long sendTime;
- private int retriesLeft;
- private LinkedBlockingQueue<MessageWrapper> inQueue;
-
-
- public RpcSocket(String address, ZMQ.Poller poller) {
- this.socket = null;
- this.state = new IdleSocketState();
- this.sendTime = -1;
- this.retriesLeft = NUM_RETRIES;
- this.inQueue = new LinkedBlockingQueue<MessageWrapper>(QUEUE_SIZE);
- this.address = address;
- this.poller = poller;
- createSocket();
- }
-
- public ZMQ.Socket getSocket() {
- return socket;
- }
-
- public String getAddress() {
- return address;
- }
-
- public int getRetriesLeft() {
- return retriesLeft;
- }
-
- public void setRetriesLeft(int retriesLeft) {
- this.retriesLeft = retriesLeft;
- }
-
- public SocketState getState() {
- return state;
- }
-
- public void setState(SocketState state) {
- this.state = state;
- }
-
- public int getQueueSize() {
- return inQueue.size();
- }
-
- public MessageWrapper removeCurrentRequest() {
- return inQueue.poll();
- }
-
- public boolean hasTimedOut() {
- return (System.currentTimeMillis() - sendTime > RpcSocket.TIMEOUT);
- }
-
- public void send(MessageWrapper request) throws TimeoutException {
- try {
- boolean success = inQueue.offer(request, TIMEOUT, TimeUnit.MILLISECONDS);
- if (!success) {
- throw new TimeoutException("send :: Queue is full");
- }
- process();
- }
- catch (InterruptedException e) {
- log.error("send : Thread interrupted while attempting to add request to inQueue", e);
- }
- }
-
- public MessageWrapper receive() {
- Message response = parseMessage();
- MessageWrapper messageWrapper = inQueue.poll(); //remove the message from queue
- MessageWrapper responseMessageWrapper = new MessageWrapper(response, messageWrapper.getReceiveSocket());
-
- state = new IdleSocketState();
- retriesLeft = NUM_RETRIES;
- return responseMessageWrapper;
- }
-
- public void process() {
- if (getQueueSize() > 0) //process if there's message in the queue
- state.process(this);
- }
-
- // Called by IdleSocketState & BusySocketState
- public void sendMessage() {
- //Get the message from queue without removing it. For retries
- MessageWrapper messageWrapper = inQueue.peek();
- if (messageWrapper != null) {
- Message message = messageWrapper.getMessage();
- try {
- socket.send(Message.serialize(message));
- }
- catch (IOException e) {
- log.debug("Message send failed [{}]", message);
- log.debug("Exception [{}]", e);
- }
- sendTime = System.currentTimeMillis();
- }
- }
-
- public Message parseMessage() {
- Message parsedMessage = null;
- byte[] bytes = socket.recv();
- log.debug("Received bytes:[{}]", bytes.length);
- try {
- parsedMessage = (Message)Message.deserialize(bytes);
- }
- catch (IOException|ClassNotFoundException e) {
- log.debug("parseMessage : Deserializing received bytes failed", e);
- }
-
- return parsedMessage;
- }
-
- public void recycleSocket() {
- close();
- }
-
- public void close() {
- socket.setLinger(10);
- socket.close();
- }
-
- private void createSocket() {
- socket = Context.getInstance().getZmqContext().socket(ZMQ.REQ);
- socket.connect(address);
- poller.register(socket, ZMQ.Poller.POLLIN);
- state = new IdleSocketState();
- }
-
-
- /**
- * Represents the state of a {@link org.opendaylight.controller.sal.connector.remoterpc.RpcSocket}
- */
- public static interface SocketState {
-
- /* The processing actions to be performed in this state
- */
- public void process(RpcSocket socket);
- }
-
- /**
- * Represents the idle state of a {@link org.opendaylight.controller.sal.connector.remoterpc.RpcSocket}
- */
- public static class IdleSocketState implements SocketState {
-
- @Override
- public void process(RpcSocket socket) {
- socket.sendMessage();
- socket.setState(new BusySocketState());
- socket.setRetriesLeft(socket.getRetriesLeft()-1);
- }
- }
-
- /**
- * Represents the busy state of a {@link org.opendaylight.controller.sal.connector.remoterpc.RpcSocket}
- */
- public static class BusySocketState implements SocketState {
-
- private static Logger log = LoggerFactory.getLogger(BusySocketState.class);
-
- @Override
- public void process(RpcSocket socket) {
- if (socket.hasTimedOut()) {
- if (socket.getRetriesLeft() > 0) {
- log.debug("process : Request timed out, retrying now...");
- socket.sendMessage();
- socket.setRetriesLeft(socket.getRetriesLeft() - 1);
- }
- else {
- // No more retries for current request, so stop processing the current request
- MessageWrapper message = socket.removeCurrentRequest();
- if (message != null) {
- log.error("Unable to process rpc request [{}]", message);
- socket.setState(new IdleSocketState());
- socket.setRetriesLeft(NUM_RETRIES);
- }
- }
- }
- // Else no timeout, so allow processing to continue
- }
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.MessageWrapper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-import static com.google.common.base.Preconditions.*;
-
-/**
- * Main server thread for sending requests.
- */
-public class Sender implements Runnable{
-
- private final static Logger _logger = LoggerFactory.getLogger(Sender.class);
- private final Client client;
-
-
-
-
- public Sender(Client client) {
- super();
- this.client = client;
- }
-
-@Override
- public void run() {
- _logger.info("Starting...");
-
- try (SocketManager socketManager = new SocketManager()){
- while (!Thread.currentThread().isInterrupted()) {
-
- //read incoming messages from blocking queue
- MessageWrapper request = pollForRequest();
-
- if (request != null) {
- processRequest(socketManager, request);
- }
-
- flushSockets(socketManager);
- pollForResponse(socketManager);
- processResponse(socketManager);
-
- }
- } catch(Exception t){
- _logger.error("Exception: [{}]", t);
- _logger.error("Stopping...");
- }
- }
-
- private void processResponse(SocketManager socketManager) {
- for (int i = 0; i < socketManager.getPoller().getSize(); i++) {
- // If any sockets get a response, process it
- if (socketManager.getPoller().pollin(i)) {
- Optional<RpcSocket> socket = socketManager.getManagedSocketFor(
- socketManager.getPoller().getItem(i).getSocket());
-
- checkState(socket.isPresent(), "Managed socket not found");
-
- MessageWrapper response = socket.get().receive();
- _logger.debug("Received rpc response [{}]", response.getMessage());
-
- //TODO: handle exception and introduce timeout on receiver side
- try {
- response.getReceiveSocket().send(Message.serialize(response.getMessage()));
- } catch (IOException e) {
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
- }
- }
- }
- }
-
- private void processRequest(SocketManager socketManager, MessageWrapper request) throws TimeoutException {
-
- if ((request.getMessage() == null) ||
- (request.getMessage().getRecipient() == null)) {
- //invalid message. log and drop
- _logger.error("Invalid request [{}]", request);
- return;
- }
-
- RpcSocket socket =
- socketManager.getManagedSocket(request.getMessage().getRecipient());
-
- socket.send(request);
- }
-
- private void flushSockets(SocketManager socketManager){
- for (RpcSocket socket : socketManager.getManagedSockets()){
- socket.process();
- }
- }
-
- private MessageWrapper pollForRequest(){
- return client.getRequestQueue().poll();
- }
-
- private void pollForResponse(SocketManager socketManager){
- try{
- socketManager.getPoller().poll(10); //poll every 10ms
- }catch (Throwable t) { /*Ignore and continue*/ }
- }
-}
-
-
-/*
-SCALA
-
-package org.opendaylight.controller.sal.connector.remoterpc
-
- import org.slf4j.{LoggerFactory, Logger}
- import scala.collection.JavaConverters._
- import scala.Some
- import org.opendaylight.controller.sal.connector.remoterpc.dto.{MessageWrapper, Message}
-*/
-/**
- * Main server thread for sending requests. This does not maintain any state. If the
- * thread dies, it will be restarted
- */
-/*class Sender extends Runnable {
- private val _logger: Logger = LoggerFactory.getLogger(Sender.this.getClass())
-
- override def run = {
- _logger.info("Sender starting...")
- val socketManager = new SocketManager()
-
- try {
- while (!Thread.currentThread().isInterrupted) {
- //read incoming messages from blocking queue
- val request: MessageWrapper = Client.requestQueue.poll()
-
- if (request != null) {
- if ((request.message != null) &&
- (request.message.getRecipient != null)) {
-
- val socket = socketManager.getManagedSocket(request.message.getRecipient)
- socket.send(request)
- } else {
- //invalid message. log and drop
- _logger.error("Invalid request [{}]", request)
- }
- }
-
- socketManager.getManagedSockets().asScala.map(s => s.process)
-
- // Poll all sockets for responses every 1 sec
- poll(socketManager)
-
- // If any sockets get a response, process it
- for (i <- 0 until socketManager.poller.getSize) {
- if (socketManager.poller.pollin(i)) {
- val socket = socketManager.getManagedSocketFor(socketManager.poller.getItem(i).getSocket)
-
- socket match {
- case None => //{
- _logger.error("Could not find a managed socket for zmq socket")
- throw new IllegalStateException("Could not find a managed socket for zmq socket")
- //}
- case Some(s) => {
- val response = s.receive()
- _logger.debug("Received rpc response [{}]", response.message)
- response.receiveSocket.send(Message.serialize(response.message))
- }
- }
- }
- }
-
- }
- } catch{
- case e:Exception => {
- _logger.debug("Sender stopping due to exception")
- e.printStackTrace()
- }
- } finally {
- socketManager.stop
- }
- }
-
- def poll(socketManager:SocketManager) = {
- try{
- socketManager.poller.poll(10)
- }catch{
- case t:Throwable => //ignore and continue
- }
- }
-}
-
-
-// def newThread(r: Runnable): Thread = {
-// val t = new RequestHandler()
-// t.setUncaughtExceptionHandler(new RequestProcessorExceptionHandler)
-// t
-// }
-
-
-
-/**
- * Restarts the request processing server in the event of unforeseen exceptions
- */
-//private class RequestProcessorExceptionHandler extends UncaughtExceptionHandler {
-// def uncaughtException(t: Thread, e: Throwable) = {
-// _logger.error("Exception caught during request processing [{}]", e)
-// _logger.info("Restarting request processor server...")
-// RequestProcessor.start()
-// }
package org.opendaylight.controller.sal.connector.remoterpc;
import com.google.common.base.Optional;
-
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message.MessageType;
import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.controller.sal.core.api.RpcRoutingContext;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zeromq.ZMQ;
-import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.Enumeration;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
/**
- * ZeroMq based implementation of RpcRouter TODO: 1. Make rpc request handling
- * async and non-blocking. Note zmq socket is not thread safe 2. Read properties
- * from config file using existing(?) ODL properties framework
+ * ZeroMq based implementation of RpcRouter. It implements RouteChangeListener of RoutingTable
+ * so that it gets route change notifications from routing table.
*/
-public class ServerImpl implements RemoteRpcServer, RouteChangeListener<String, Set> {
+public class ServerImpl implements RemoteRpcServer, RouteChangeListener<String, String> {
- private Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
+ private Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
- private ExecutorService serverPool;
+ private ExecutorService serverPool;
+ protected ServerRequestHandler handler;
- // private RoutingTable<RpcRouter.RouteIdentifier, String> routingTable;
- private RoutingTableProvider routingTable;
- private Set<QName> remoteServices;
- private ProviderSession brokerSession;
- private ZMQ.Context context;
- private ZMQ.Socket replySocket;
+ private Set<QName> remoteServices;
+ private ProviderSession brokerSession;
+ private ZMQ.Context context;
- private final RpcListener listener = new RpcListener();
+ private final RpcListener listener = new RpcListener();
- private final String localUri = Context.getInstance().getLocalUri();
+ private final String HANDLER_INPROC_ADDRESS = "inproc://rpc-request-handler";
+ private final int HANDLER_WORKER_COUNT = 2;
+ private final int HWM = 200;//high water mark on sockets
+ private volatile State status = State.STOPPED;
- private final int rpcPort;
+ private String serverAddress;
+ private int port;
- private RpcImplementation client;
+ private ClientImpl client;
- public RpcImplementation getClient() {
- return client;
- }
+ private RoutingTableProvider routingTableProvider;
- public void setClient(RpcImplementation client) {
- this.client = client;
- }
+ public static enum State {
+ STARTING, STARTED, STOPPED;
+ }
- // Prevent instantiation
- public ServerImpl(int rpcPort) {
- this.rpcPort = rpcPort;
- }
+ public ServerImpl(int port) {
+ this.port = port;
+ this.serverAddress = new StringBuilder(findIpAddress()).
+ append(":").
+ append(port).
+ toString();
+ }
- public void setBrokerSession(ProviderSession session) {
- this.brokerSession = session;
- }
+ public RoutingTableProvider getRoutingTableProvider() {
+ return routingTableProvider;
+ }
- public ExecutorService getServerPool() {
- return serverPool;
- }
+ public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
+ this.routingTableProvider = routingTableProvider;
+ }
- public void setServerPool(ExecutorService serverPool) {
- this.serverPool = serverPool;
- }
+ public ClientImpl getClient(){
+ return this.client;
+ }
- public void start() {
- context = ZMQ.context(1);
- serverPool = Executors.newSingleThreadExecutor();
- remoteServices = new HashSet<QName>();
+ public void setClient(ClientImpl client) {
+ this.client = client;
+ }
- // Start listening rpc requests
- serverPool.execute(receive());
+ public State getStatus() {
+ return this.status;
+ }
- brokerSession.addRpcRegistrationListener(listener);
- // routingTable.registerRouteChangeListener(routeChangeListener);
+ public Optional<ServerRequestHandler> getHandler() {
+ return Optional.fromNullable(this.handler);
+ }
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- for (QName rpc : currentlySupported) {
- listener.onRpcImplementationAdded(rpc);
- }
+ public void setBrokerSession(ProviderSession session) {
+ this.brokerSession = session;
+ }
- _logger.debug("RPC Server started [{}]", localUri);
- }
+ public Optional<ProviderSession> getBrokerSession() {
+ return Optional.fromNullable(this.brokerSession);
+ }
- public void stop() {
- // TODO: un-subscribe
+ public Optional<ZMQ.Context> getZmqContext() {
+ return Optional.fromNullable(this.context);
+ }
- // if (context != null)
- // context.term();
- //
- // _logger.debug("ZMQ Context is terminated.");
+ public String getServerAddress() {
+ return serverAddress;
+ }
- if (serverPool != null)
- serverPool.shutdown();
+ public String getHandlerAddress() {
+ return HANDLER_INPROC_ADDRESS;
+ }
- _logger.debug("Thread pool is closed.");
- }
+ /**
+ *
+ */
+ public void start() {
+ Preconditions.checkState(State.STOPPED == this.getStatus(),
+ "Remote RPC Server is already running");
- private Runnable receive() {
- return new Runnable() {
- public void run() {
-
- // Bind to RPC reply socket
- replySocket = context.socket(ZMQ.REP);
- replySocket.bind("tcp://*:" + Context.getInstance().getRpcPort());
-
- // Poller enables listening on multiple sockets using a single
- // thread
- ZMQ.Poller poller = new ZMQ.Poller(1);
- poller.register(replySocket, ZMQ.Poller.POLLIN);
- try {
- // TODO: Add code to restart the thread after exception
- while (!Thread.currentThread().isInterrupted()) {
-
- poller.poll();
-
- if (poller.pollin(0)) {
- handleRpcCall();
- }
- }
- } catch (Exception e) {
- // log and continue
- _logger.error("Unhandled exception [{}]", e);
- } finally {
- poller.unregister(replySocket);
- replySocket.close();
- }
-
- }
- };
- }
+ status = State.STARTING;
+ context = ZMQ.context(1);
+ remoteServices = new HashSet<QName>();//
+ serverPool = Executors.newSingleThreadExecutor();//main server thread
+ serverPool.execute(receive()); // Start listening rpc requests
+ brokerSession.addRpcRegistrationListener(listener);
- /**
- * @throws InterruptedException
- * @throws ExecutionException
- */
- private void handleRpcCall() {
+ announceLocalRpcs();
- Message request = parseMessage(replySocket);
+ registerRemoteRpcs();
- _logger.debug("Received rpc request [{}]", request);
+ status = State.STARTED;
+ _logger.info("Remote RPC Server started [{}]", getServerAddress());
+ }
- // Call broker to process the message then reply
- Future<RpcResult<CompositeNode>> rpc = null;
- RpcResult<CompositeNode> result = null;
- try {
- rpc = brokerSession.rpc((QName) request.getRoute().getType(),
- XmlUtils.xmlToCompositeNode((String) request.getPayload()));
+ public void stop(){
+ close();
+ }
- result = (rpc != null) ? rpc.get() : null;
+ /**
+ *
+ */
+ @Override
+ public void close() {
- } catch (Exception e) {
- _logger.debug("Broker threw [{}]", e);
- }
+ if (State.STOPPED == this.getStatus()) return; //do nothing
+
+ unregisterLocalRpcs();
- CompositeNode payload = (result != null) ? result.getResult() : null;
+ if (serverPool != null)
+ serverPool.shutdown();
- Message response = new Message.MessageBuilder().type(MessageType.RESPONSE).sender(localUri)
- .route(request.getRoute()).payload(XmlUtils.compositeNodeToXml(payload)).build();
+ closeZmqContext();
- _logger.debug("Sending rpc response [{}]", response);
+ status = State.STOPPED;
+ _logger.info("Remote RPC Server stopped");
+ }
+
+ /**
+ * Closes ZMQ Context. It tries to gracefully terminate the context. If
+ * termination takes more than a second, its forcefully shutdown.
+ */
+ private void closeZmqContext() {
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ FutureTask zmqTermination = new FutureTask(new Runnable() {
+ @Override
+ public void run() {
try {
- replySocket.send(Message.serialize(response));
+ if (context != null)
+ context.term();
+ _logger.debug("ZMQ Context terminated gracefully!");
} catch (Exception e) {
- _logger.debug("rpc response send failed for message [{}]", response);
- _logger.debug("{}", e);
+ _logger.debug("ZMQ Context termination threw exception [{}]. Continuing shutdown...", e);
}
+ }
+ }, null);
+
+ exec.execute(zmqTermination);
+
+ try {
+ zmqTermination.get(5L, TimeUnit.SECONDS);
+ } catch (Exception e) {/*ignore and continue with shutdown*/}
+
+ exec.shutdownNow();
+ }
+
+ /**
+ * Main listener thread that spawns {@link ServerRequestHandler} as workers.
+ *
+ * @return
+ */
+ private Runnable receive() {
+ return new Runnable() {
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName("remote-rpc-server");
+ _logger.debug("Remote RPC Server main thread starting...");
+
+ //socket clients connect to (frontend)
+ ZMQ.Socket clients = context.socket(ZMQ.ROUTER);
+
+ //socket RequestHandlers connect to (backend)
+ ZMQ.Socket workers = context.socket(ZMQ.DEALER);
+
+ try (SocketPair capturePair = new SocketPair();
+ ServerRequestHandler requestHandler = new ServerRequestHandler(context,
+ brokerSession,
+ HANDLER_WORKER_COUNT,
+ HANDLER_INPROC_ADDRESS,
+ getServerAddress());) {
+
+ handler = requestHandler;
+ clients.setHWM(HWM);
+ clients.bind("tcp://*:" + port);
+ workers.setHWM(HWM);
+ workers.bind(HANDLER_INPROC_ADDRESS);
+ //start worker threads
+ _logger.debug("Remote RPC Server worker threads starting...");
+ requestHandler.start();
+ //start capture thread
+ // handlerPool.execute(new CaptureHandler(capturePair.getReceiver()));
+ // Connect work threads to client threads via a queue
+ ZMQ.proxy(clients, workers, null);//capturePair.getSender());
+ } catch (Exception e) {
+ _logger.debug("Unhandled exception [{}, {}]", e.getClass(), e.getMessage());
+ } finally {
+ if (clients != null) clients.close();
+ if (workers != null) workers.close();
+ _logger.info("Remote RPC Server stopped");
+ }
+ }
+ };
+ }
+
+ /**
+ * Register the remote RPCs from the routing table into broker
+ */
+ private void registerRemoteRpcs(){
+ Optional<RoutingTable<String, String>> routingTableOptional = routingTableProvider.getRoutingTable();
+
+ Preconditions.checkState(routingTableOptional.isPresent(), "Routing table is absent");
+
+ Set<Map.Entry> remoteRoutes =
+ routingTableProvider.getRoutingTable().get().getAllRoutes();
+
+ //filter out all entries that contains local address
+ //we dont want to register local RPCs as remote
+ Predicate<Map.Entry> notLocalAddressFilter = new Predicate<Map.Entry>(){
+ public boolean apply(Map.Entry remoteRoute){
+ return !getServerAddress().equalsIgnoreCase((String)remoteRoute.getValue());
+ }
+ };
+
+ //filter the entries created by current node
+ Set<Map.Entry> filteredRemoteRoutes = Sets.filter(remoteRoutes, notLocalAddressFilter);
+
+ for (Map.Entry route : filteredRemoteRoutes){
+ onRouteUpdated((String) route.getKey(), "");//value is not needed by broker
+ }
+ }
+
+ /**
+ * Un-Register the local RPCs from the routing table
+ */
+ private void unregisterLocalRpcs(){
+ Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
+ for (QName rpc : currentlySupported) {
+ listener.onRpcImplementationRemoved(rpc);
+ }
+ }
+
+ /**
+ * Publish all the locally registered RPCs in the routing table
+ */
+ private void announceLocalRpcs(){
+ Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
+ for (QName rpc : currentlySupported) {
+ listener.onRpcImplementationAdded(rpc);
+ }
+ }
+
+ /**
+ * @param key
+ * @param value
+ */
+ @Override
+ public void onRouteUpdated(String key, String value) {
+ RouteIdentifierImpl rId = new RouteIdentifierImpl();
+ try {
+ _logger.debug("Updating key/value {}-{}", key, value);
+ brokerSession.addRpcImplementation(
+ (QName) rId.fromString(key).getType(), client);
+
+ //TODO: Check with Tony for routed rpc
+ //brokerSession.addRoutedRpcImplementation((QName) rId.fromString(key).getRoute(), client);
+ } catch (Exception e) {
+ _logger.info("Route update failed {}", e);
}
+ }
+
+ /**
+ * @param key
+ */
+ @Override
+ public void onRouteDeleted(String key) {
+ //TODO: Broker session needs to be updated to support this
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Finds IPv4 address of the local VM
+ * TODO: This method is non-deterministic. There may be more than one IPv4 address. Cant say which
+ * address will be returned. Read IP from a property file or enhance the code to make it deterministic.
+ * Should we use IP or hostname?
+ *
+ * @return
+ */
+ private String findIpAddress() {
+ String hostAddress = null;
+ Enumeration e = null;
+ try {
+ e = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e1) {
+ e1.printStackTrace();
+ }
+ while (e.hasMoreElements()) {
- /**
- * @param socket
- * @return
- */
- private Message parseMessage(ZMQ.Socket socket) {
+ NetworkInterface n = (NetworkInterface) e.nextElement();
- Message msg = null;
- try {
- byte[] bytes = socket.recv();
- _logger.debug("Received bytes:[{}]", bytes.length);
- msg = (Message) Message.deserialize(bytes);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- return msg;
+ Enumeration ee = n.getInetAddresses();
+ while (ee.hasMoreElements()) {
+ InetAddress i = (InetAddress) ee.nextElement();
+ if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
+ hostAddress = i.getHostAddress();
+ }
}
+ return hostAddress;
+
+ }
+
+ /**
+ * Listener for rpc registrations
+ */
+ private class RpcListener implements RpcRegistrationListener {
@Override
- public void onRouteUpdated(String key, Set values) {
- RouteIdentifierImpl rId = new RouteIdentifierImpl();
- try {
- _logger.debug("Updating key/value {}-{}", key, values);
- brokerSession.addRpcImplementation((QName) rId.fromString(key).getType(), client);
+ public void onRpcImplementationAdded(QName name) {
- } catch (Exception e) {
- _logger.info("Route update failed {}", e);
- }
+ //if the service name exists in the set, this notice
+ //has bounced back from the broker. It should be ignored
+ if (remoteServices.contains(name))
+ return;
+
+ _logger.debug("Adding registration for [{}]", name);
+ RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+ routeId.setType(name);
+
+ RoutingTable<String, String> routingTable = getRoutingTable();
+
+ try {
+ routingTable.addGlobalRoute(routeId.toString(), getServerAddress());
+ _logger.debug("Route added [{}-{}]", name, getServerAddress());
+
+ } catch (RoutingTableException | SystemException e) {
+ //TODO: This can be thrown when route already exists in the table. Broker
+ //needs to handle this.
+ _logger.error("Unhandled exception while adding global route to routing table [{}]", e);
+
+ }
}
@Override
- public void onRouteDeleted(String key) {
- // TODO: Broker session needs to be updated to support this
- throw new UnsupportedOperationException();
+ public void onRpcImplementationRemoved(QName name) {
+
+ _logger.debug("Removing registration for [{}]", name);
+ RouteIdentifierImpl routeId = new RouteIdentifierImpl();
+ routeId.setType(name);
+
+ RoutingTable<String, String> routingTable = getRoutingTable();
+
+ try {
+ routingTable.removeGlobalRoute(routeId.toString());
+ } catch (RoutingTableException | SystemException e) {
+ _logger.error("Route delete failed {}", e);
+ }
}
-
- /**
- * Listener for rpc registrations
- */
- private class RpcListener implements RpcRegistrationListener {
-
-
-
- @Override
- public void onRpcImplementationAdded(QName name) {
-
- // if the service name exists in the set, this notice
- // has bounced back from the broker. It should be ignored
- if (remoteServices.contains(name))
- return;
-
- _logger.debug("Adding registration for [{}]", name);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(name);
-
- try {
- routingTable.getRoutingTable().get().addGlobalRoute(routeId.toString(), localUri);
- _logger.debug("Route added [{}-{}]", name, localUri);
- } catch (RoutingTableException | SystemException e) {
- // TODO: This can be thrown when route already exists in the
- // table. Broker
- // needs to handle this.
- _logger.error("Unhandled exception while adding global route to routing table [{}]", e);
-
- }
- }
- @Override
- public void onRpcImplementationRemoved(QName name) {
+ private RoutingTable<String, String> getRoutingTable(){
+ Optional<RoutingTable<String, String>> routingTable =
+ routingTableProvider.getRoutingTable();
- _logger.debug("Removing registration for [{}]", name);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(name);
+ checkNotNull(routingTable.isPresent(), "Routing table is null");
- try {
- routingTable.getRoutingTable().get().removeGlobalRoute(routeId.toString());
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route delete failed {}", e);
- }
- }
+ return routingTable.get();
}
+ }
+
+ /*
+ * Listener for Route changes in broker. Broker notifies this listener in the event
+ * of any change (add/delete). Listener then updates the routing table.
+ */
+ private class BrokerRouteChangeListener
+ implements org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener<RpcRoutingContext, InstanceIdentifier>{
@Override
- public void close() throws Exception {
- stop();
- }
+ public void onRouteChange(RouteChange<RpcRoutingContext, InstanceIdentifier> routeChange) {
- public void setRoutingTableProvider(RoutingTableProvider provider) {
- this.routingTable = provider;
}
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ *
+ */
+public class ServerRequestHandler implements AutoCloseable{
+
+ private Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class);
+ private final String DEFAULT_NAME = "remote-rpc-worker";
+ private String dealerAddress;
+ private String serverAddress;
+ private int workerCount;
+ private ZMQ.Context context;
+ private Broker.ProviderSession broker;
+
+ private RequestHandlerThreadPool workerPool;
+ private final AtomicInteger threadId = new AtomicInteger();
+
+ public ServerRequestHandler(ZMQ.Context context,
+ Broker.ProviderSession session,
+ int workerCount,
+ String dealerAddress,
+ String serverAddress) {
+ this.context = context;
+ this.dealerAddress = dealerAddress;
+ this.serverAddress = serverAddress;
+ this.broker = session;
+ this.workerCount = workerCount;
+ }
+
+ public ThreadPoolExecutor getWorkerPool(){
+ return workerPool;
+ }
+
+ public void start(){
+ workerPool = new RequestHandlerThreadPool(
+ workerCount, workerCount,
+ 0L, TimeUnit.MILLISECONDS,
+ new LinkedBlockingQueue<Runnable>());
+ //unbound is ok. Task will never be submitted
+
+ for (int i=0;i<workerCount;i++){
+ workerPool.execute(new Worker(threadId.incrementAndGet()));
+ }
+ }
+
+ /**
+ * This gets called automatically if used with try-with-resources
+ * @throws Exception
+ */
+ @Override
+ public void close() throws Exception {
+ if (workerPool != null)
+ workerPool.shutdown();
+ _logger.info("Request Handler closed");
+ }
+
+ /**
+ * Worker to handles RPC request
+ */
+ private class Worker implements Runnable {
+ private String name;
+
+ public Worker(int id){
+ this.name = DEFAULT_NAME + "-" + id;
+ }
+
+ @Override
+ public void run() {
+ Thread.currentThread().setName(name);
+ _logger.debug("Starting... ");
+ ZMQ.Socket socket = null;
+
+ try {
+ socket = context.socket(ZMQ.REP);
+ socket.connect(dealerAddress);
+
+ while (!Thread.currentThread().isInterrupted()) {
+
+ Message request = parseMessage(socket);
+ _logger.debug("Received rpc request [{}]", request);
+
+ if (request != null) {
+ // Call broker to process the message then reply
+ Future<RpcResult<CompositeNode>> rpc = null;
+ RpcResult<CompositeNode> result = null;
+
+ //TODO Call this in a new thread with timeout
+ try {
+ rpc = broker.rpc(
+ (QName) request.getRoute().getType(),
+ XmlUtils.xmlToCompositeNode((String) request.getPayload()));
+
+ result = (rpc != null) ? rpc.get() : null;
+
+ } catch (Exception e) {
+ _logger.debug("Broker threw [{}]", e);
+ }
+
+ CompositeNode payload = (result != null) ? result.getResult() : null;
+
+ Message response = new Message.MessageBuilder()
+ .type(Message.MessageType.RESPONSE)
+ .sender(serverAddress)
+ .route(request.getRoute())
+ .payload(XmlUtils.compositeNodeToXml(payload))
+ .build();
+
+ _logger.debug("Sending rpc response [{}]", response);
+
+ try {
+ socket.send(Message.serialize(response));
+ } catch (Exception e) {
+ _logger.debug("rpc response send failed for message [{}]", response);
+ _logger.debug("{}", e);
+ }
+ }
+ }
+ } catch (Exception e) {
+ printException(e);
+ } finally {
+ closeSocket(socket);
+ }
+ }
+
+ /**
+ * @param socket
+ * @return
+ */
+ private Message parseMessage(ZMQ.Socket socket) throws Exception {
+ byte[] bytes = socket.recv(); //this blocks
+ _logger.debug("Received bytes:[{}]", bytes.length);
+ return (Message) Message.deserialize(bytes);
+ }
+
+ private void printException(Exception e) {
+ try (StringWriter s = new StringWriter();
+ PrintWriter p = new PrintWriter(s)) {
+ e.printStackTrace(p);
+ _logger.debug(s.toString());
+ } catch (IOException e1) {/*Ignore and continue*/ }
+ }
+
+ private void closeSocket(ZMQ.Socket socket) {
+ try {
+ if (socket != null) socket.close();
+ } catch (Exception x) {
+ _logger.debug("Exception while closing socket [{}]", x);
+ } finally {
+ if (socket != null) socket.close();
+ }
+ _logger.debug("Closing...");
+ }
+ }
+
+
+ /**
+ *
+ */
+ public class RequestHandlerThreadPool extends ThreadPoolExecutor{
+
+ public RequestHandlerThreadPool(int corePoolSize,
+ int maximumPoolSize,
+ long keepAliveTime,
+ TimeUnit unit,
+ BlockingQueue<Runnable> workQueue) {
+ super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
+ }
+
+ @Override
+ protected void afterExecute(Runnable r, Throwable t) {
+ if (isTerminating() || isTerminated() || isShutdown())
+ return;
+
+ if ( t != null ){
+ _logger.debug("Exception caught while terminating worker [{},{}]", t.getClass(), t.getMessage());
+ }
+
+ this.execute(new Worker(threadId.incrementAndGet()));
+ super.afterExecute(r, null);
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-import java.net.UnknownHostException;
-import java.util.Collection;
-import java.util.concurrent.ConcurrentHashMap;
-
-
-/**
- * Manages creation of {@link RpcSocket} and their registration with {@link ZMQ.Poller}
- */
-public class SocketManager implements AutoCloseable{
- private static final Logger log = LoggerFactory.getLogger(SocketManager.class);
-
- /*
- * RpcSockets mapped by network address its connected to
- */
- private ConcurrentHashMap<String, RpcSocket> managedSockets = new ConcurrentHashMap<String, RpcSocket>();
-
- private ZMQ.Poller _poller = new ZMQ.Poller(2); //randomly selected size. Poller grows automatically
-
- /**
- * Returns a {@link RpcSocket} for the given address
- * @param address network address with port eg: 10.199.199.20:5554
- * @return
- */
- public RpcSocket getManagedSocket(String address) throws IllegalArgumentException {
- //Precondition
- if (!address.matches("(tcp://)(.*)(:)(\\d*)")) {
- throw new IllegalArgumentException("Address must of format 'tcp://<ip address>:<port>' but is " + address);
- }
-
- if (!managedSockets.containsKey(address)) {
- log.debug("{} Creating new socket for {}", Thread.currentThread().getName());
- RpcSocket socket = new RpcSocket(address, _poller);
- managedSockets.put(address, socket);
- }
-
- return managedSockets.get(address);
- }
-
- /**
- * Returns a {@link RpcSocket} for the given {@link ZMQ.Socket}
- * @param socket
- * @return
- */
- public Optional<RpcSocket> getManagedSocketFor(ZMQ.Socket socket) {
- for (RpcSocket rpcSocket : managedSockets.values()) {
- if (rpcSocket.getSocket().equals(socket)) {
- return Optional.of(rpcSocket);
- }
- }
- return Optional.absent();
- }
-
- /**
- * Return a collection of all managed sockets
- * @return
- */
- public Collection<RpcSocket> getManagedSockets() {
- return managedSockets.values();
- }
-
- /**
- * Returns the {@link ZMQ.Poller}
- * @return
- */
- public ZMQ.Poller getPoller() {
- return _poller;
- }
-
- /**
- * This should be called when stopping the server to close all the sockets
- * @return
- */
- @Override
- public void close() throws Exception {
- log.debug("Stopping...");
- for (RpcSocket socket : managedSockets.values()) {
- socket.close();
- }
- managedSockets.clear();
- log.debug("Stopped");
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc.dto;
-
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.*;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-public class CompositeNodeImpl implements CompositeNode, Serializable {
-
- private QName key;
- private List<Node<?>> children;
-
- @Override
- public List<Node<?>> getChildren() {
- return children;
- }
-
- @Override
- public List<CompositeNode> getCompositesByName(QName children) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public List<CompositeNode> getCompositesByName(String children) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<SimpleNode<?>> getSimpleNodesByName(QName children) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<SimpleNode<?>> getSimpleNodesByName(String children) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public CompositeNode getFirstCompositeByName(QName container) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public SimpleNode<?> getFirstSimpleByName(QName leaf) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public MutableCompositeNode asMutable() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public QName getKey() {
- return key; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<Node<?>> setValue(List<Node<?>> value) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public int size() {
- return 0; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public boolean isEmpty() {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public boolean containsKey(Object key) {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public boolean containsValue(Object value) {
- return false; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<Node<?>> get(Object key) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<Node<?>> put(QName key, List<Node<?>> value) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<Node<?>> remove(Object key) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void putAll(Map<? extends QName, ? extends List<Node<?>>> m) {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void clear() {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public Set<QName> keySet() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public Collection<List<Node<?>>> values() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public Set<Entry<QName, List<Node<?>>>> entrySet() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public QName getNodeType() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public CompositeNode getParent() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public List<Node<?>> getValue() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public ModifyAction getModificationAction() {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.connector.remoterpc.dto;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-import java.io.Serializable;
-
-public class RpcRequestImpl implements RpcRouter.RpcRequest<QName, QName, InstanceIdentifier, Object>,Serializable {
-
- private RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier;
- private Object payload;
-
- @Override
- public RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> getRoutingInformation() {
- return routeIdentifier;
- }
-
- public void setRouteIdentifier(RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier) {
- this.routeIdentifier = routeIdentifier;
- }
-
- @Override
- public Object getPayload() {
- return payload;
- }
-
- public void setPayload(Object payload) {
- this.payload = payload;
- }
-
-}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.controller.sal.connector.remoterpc.util;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc
-
-import org.opendaylight.yangtools.yang.data.api.CompositeNode
-import org.opendaylight.yangtools.yang.common.{RpcError, RpcResult, QName}
-import org.opendaylight.controller.sal.core.api.RpcImplementation
-import java.util
-import java.util.{UUID, Collections}
-import org.zeromq.ZMQ
-import org.opendaylight.controller.sal.common.util.{RpcErrors, Rpcs}
-import org.slf4j.LoggerFactory
-import org.opendaylight.controller.sal.connector.remoterpc.dto.{MessageWrapper, RouteIdentifierImpl, Message}
-import Message.MessageType
-import java.util.concurrent._
-import java.lang.InterruptedException
-
-
-/**
- * An implementation of {@link RpcImplementation} that makes
- * remote RPC calls
- */
-class Client extends RemoteRpcClient {
-
- private val _logger = LoggerFactory.getLogger(this.getClass);
-
- val requestQueue = new LinkedBlockingQueue[MessageWrapper](100)
- val pool: ExecutorService = Executors.newSingleThreadExecutor()
- private val TIMEOUT = 5000 //in ms
- var routingTableProvider: RoutingTableProvider = null
-
-
- def getInstance = this
-
-
- def setRoutingTableProvider(provider : RoutingTableProvider) = {
- routingTableProvider = provider;
- }
-
- def getSupportedRpcs: util.Set[QName] = {
- Collections.emptySet()
- }
-
- def invokeRpc(rpc: QName, input: CompositeNode): RpcResult[CompositeNode] = {
-
- val routeId = new RouteIdentifierImpl()
- routeId.setType(rpc)
-
- //lookup address for the rpc request
- val routingTable = routingTableProvider.getRoutingTable()
- require( routingTable != null, "Routing table not found. Exiting" )
-
- val addresses:util.Set[String] = routingTable.getRoutes(routeId.toString)
- require(addresses != null, "Address not found for rpc " + rpc);
- require(addresses.size() == 1) //its a global service.
-
- val address = addresses.iterator().next()
- require(address != null, "Address is null")
-
- //create in-process "pair" socket and pass it to sender thread
- //Sender replies on this when result is available
- val inProcAddress = "inproc://" + UUID.randomUUID()
- val receiver = Context.zmqContext.socket(ZMQ.PAIR)
- receiver.bind(inProcAddress);
-
- val sender = Context.zmqContext.socket(ZMQ.PAIR)
- sender.connect(inProcAddress)
-
- val requestMessage = new Message.MessageBuilder()
- .`type`(MessageType.REQUEST)
- //.sender("tcp://localhost:8081")
- .recipient(address)
- .route(routeId)
- .payload(input)
- .build()
-
- _logger.debug("Queuing up request and expecting response on [{}]", inProcAddress)
-
- val messageWrapper = new MessageWrapper(requestMessage, sender)
- val errors = new util.ArrayList[RpcError]
-
- try {
- process(messageWrapper)
- val response = parseMessage(receiver)
-
- return Rpcs.getRpcResult(
- true, response.getPayload.asInstanceOf[CompositeNode], Collections.emptySet())
-
- } catch {
- case e: Exception => {
- errors.add(RpcErrors.getRpcError(null,null,null,null,e.getMessage,null,e.getCause))
- return Rpcs.getRpcResult(false, null, errors)
- }
- } finally {
- receiver.close();
- sender.close();
- }
-
- }
-
- /**
- * Block on socket for reply
- * @param receiver
- * @return
- */
- private def parseMessage(receiver:ZMQ.Socket): Message = {
- val bytes = receiver.recv()
- return Message.deserialize(bytes).asInstanceOf[Message]
- }
-
- def start() = {
- pool.execute(new Sender)
- }
-
- def process(msg: MessageWrapper) = {
- _logger.debug("Processing message [{}]", msg)
- val success = requestQueue.offer(msg, TIMEOUT, TimeUnit.MILLISECONDS)
-
- if (!success) throw new TimeoutException("Queue is full");
-
- }
-
- def stop() = {
- pool.shutdown() //intiate shutdown
- _logger.debug("Client stopping...")
- // Context.zmqContext.term();
- // _logger.debug("ZMQ context terminated")
-
- try {
-
- if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {
- pool.shutdownNow();
- if (!pool.awaitTermination(10, TimeUnit.SECONDS))
- _logger.error("Client thread pool did not shut down");
- }
- } catch {
- case ie:InterruptedException =>
- // (Re-)Cancel if current thread also interrupted
- pool.shutdownNow();
- // Preserve interrupt status
- Thread.currentThread().interrupt();
- }
- _logger.debug("Client stopped")
- }
-
- def close() = {
- stop();
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import com.google.common.base.Optional;
+import junit.framework.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
+import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ *
+ */
+public class ClientImplTest {
+ RoutingTableProvider routingTableProvider;
+ ClientImpl client;
+ ClientRequestHandler mockHandler;
+
+ @Before
+ public void setUp() throws Exception {
+
+ //mock routing table
+ routingTableProvider = mock(RoutingTableProvider.class);
+ RoutingTable<String, String> mockRoutingTable = new MockRoutingTable<String, String>();
+ Optional<RoutingTable<String, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
+ when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
+
+ //mock ClientRequestHandler
+ mockHandler = mock(ClientRequestHandler.class);
+
+ client = new ClientImpl(mockHandler);
+ client.setRoutingTableProvider(routingTableProvider);
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+
+ }
+
+ @Test
+ public void getRoutingTableProvider_Call_ShouldReturnMockProvider() throws Exception {
+ Assert.assertEquals(routingTableProvider, client.getRoutingTableProvider());
+
+ }
+
+ @Test
+ public void testStart() throws Exception {
+
+ }
+
+ @Test
+ public void testStop() throws Exception {
+
+ }
+
+ @Test
+ public void testClose() throws Exception {
+
+ }
+
+ @Test
+ public void invokeRpc_NormalCall_ShouldReturnSuccess() throws Exception {
+
+ when(mockHandler.handle(any(Message.class))).
+ thenReturn(MessagingUtil.createEmptyMessage());
+
+ RpcResult<CompositeNode> result = client.invokeRpc(null, null);
+
+ Assert.assertTrue(result.isSuccessful());
+ Assert.assertTrue(result.getErrors().isEmpty());
+ Assert.assertNull(result.getResult());
+ }
+
+ @Test
+ public void invokeRpc_HandlerThrowsException_ShouldReturnError() throws Exception {
+
+ when(mockHandler.handle(any(Message.class))).
+ thenThrow(new IOException());
+
+ RpcResult<CompositeNode> result = client.invokeRpc(null, null);
+
+ Assert.assertFalse(result.isSuccessful());
+ Assert.assertFalse(result.getErrors().isEmpty());
+ Assert.assertNull(result.getResult());
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import junit.framework.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import java.io.IOException;
+import java.util.concurrent.*;
+
+/**
+ *
+ */
+public class ClientRequestHandlerTest {
+
+ private final Logger _logger = LoggerFactory.getLogger(ClientRequestHandlerTest.class);
+
+ ZMQ.Context context;
+ ExecutorService serverThread;
+ final String SERVER_ADDRESS = "localhost:5553";
+
+ ClientRequestHandler handler;
+
+ @Before
+ public void setUp() throws Exception {
+ context = ZMQ.context(1);
+ serverThread = Executors.newCachedThreadPool();
+ handler = new ClientRequestHandler(context);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ serverThread.shutdown();
+ MessagingUtil.closeZmqContext(context);
+ handler.close();
+ }
+
+ @Test
+ public void handle_SingleRemote_ShouldReturnResponse() throws Exception {
+ serverThread.execute(MessagingUtil.startReplyServer(context, SERVER_ADDRESS, 1));
+ Message request = new Message();
+ request.setRecipient(SERVER_ADDRESS);
+ Message response = handleMessageWithTimeout(request);
+ Assert.assertNotNull(response);
+ //should be connected to only 1 remote server
+ Assert.assertEquals(1, handler.getWorkerCount());
+ Assert.assertEquals(response.getRecipient(), SERVER_ADDRESS);
+ }
+
+ // @Test
+ public void handle_MultiRemote_ShouldReturnResponses() throws Exception {
+ ExecutorService threadPool = Executors.newCachedThreadPool();
+ final int port = 5555;
+ String serverAddress = null;
+ for (int i = 0; i < 5; i++) {
+ serverAddress = "localhost:" + (port + i);
+ serverThread.execute(MessagingUtil.startReplyServer(context, serverAddress, 1));
+ threadPool.execute(createEmptyMessageTaskAndHandle(handler, serverAddress));
+ }
+ Thread.currentThread().sleep(5000);//wait for all messages to get processed
+ //should be connected to 5 remote server
+ Assert.assertEquals(5, handler.getWorkerCount());
+ }
+
+ private Runnable createEmptyMessageTaskAndHandle(final ClientRequestHandler handler, final String serverAddress) {
+
+ return new Runnable() {
+ @Override
+ public void run() {
+ Message request = new Message();
+ request.setRecipient(serverAddress);
+ try {
+ Message response = handleMessageWithTimeout(request);
+ Assert.assertNotNull(response);
+ Assert.assertEquals(response.getRecipient(), serverAddress);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ private Message handleMessageWithTimeout(final Message request) {
+ Message response = null;
+
+ FutureTask task = new FutureTask(new Callable<Message>() {
+
+ @Override
+ public Message call() {
+ try {
+ return handler.handle(request);
+ } catch (Exception e) {
+ _logger.debug("Client handler failed to handle request. Exception is [{}]", e);
+ }
+ return null;
+ }
+ });
+
+ serverThread.execute(task);
+
+ try {
+ response = (Message) task.get(5L, TimeUnit.SECONDS); //wait for max 5 sec for server to respond
+ } catch (Exception e) {/*ignore and continue*/}
+
+ return response;
+ }
+
+}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import junit.framework.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.MessageWrapper;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-
-import java.util.concurrent.TimeoutException;
-
-public class ClientTest {
-
- Client client;
-
- @Before
- public void setup(){
- client = new Client();
- client.getRequestQueue().clear();
- }
-
- @Test
- public void testStop() throws Exception {
-
- }
-
- @Test
- public void testPool() throws Exception {
-
- }
-
- @Test
- public void process_AddAMessage_ShouldAddToQueue() throws Exception {
- client.process(getEmptyMessageWrapper());
- Assert.assertEquals(1, client.getRequestQueue().size());
- }
-
- /**
- * Queue size is 100. Adding 101 message should time out in 2 sec
- * if server does not process it
- * @throws Exception
- */
- @Test(expected = TimeoutException.class)
- public void process_Add101Message_ShouldThrow() throws Exception {
- for (int i=0;i<101;i++){
- client.process(getEmptyMessageWrapper());
- }
- }
-
- @Test
- public void testStart() throws Exception {
- }
-
- private MessageWrapper getEmptyMessageWrapper(){
- return new MessageWrapper(new Message(), null);
- }
-}
--- /dev/null
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
+import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Mock implementation of routing table
+ */
+public class MockRoutingTable<K, V> implements RoutingTable {
+
+
+ @Override
+ public void addRoute(Object o, Object o2) throws RoutingTableException, SystemException {
+
+ }
+
+ @Override
+ public void addGlobalRoute(Object o, Object o2) throws RoutingTableException, SystemException {
+
+ }
+
+ @Override
+ public void removeRoute(Object o, Object o2) {
+
+ }
+
+ @Override
+ public void removeGlobalRoute(Object o) throws RoutingTableException, SystemException {
+
+ }
+
+ @Override
+ public Set getRoutes(Object o) {
+ Set<String> routes = new HashSet<String>();
+ routes.add("localhost:5554");
+ return routes;
+ }
+
+ @Override
+ public Set<Map.Entry> getAllRoutes() {
+ return Collections.emptySet();
+ }
+
+ @Override
+ public Object getARoute(Object o) {
+ return null;
+ }
+
+ @Override
+ public void registerRouteChangeListener(RouteChangeListener routeChangeListener) {
+
+ }
+}
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.controller.sal.connector.remoterpc;
import java.net.URI;
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import junit.framework.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.MessageWrapper;
-import org.powermock.api.mockito.PowerMockito;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-import org.zeromq.ZMQ;
-
-import java.util.concurrent.TimeoutException;
-
-import static org.mockito.Mockito.doNothing;
-
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(RpcSocket.class)
-public class RpcSocketTest {
- RpcSocket rpcSocket = new RpcSocket("tcp://localhost:5554", new ZMQ.Poller(1));
- RpcSocket spy = PowerMockito.spy(rpcSocket);
-
- @Test
- public void testCreateSocket() throws Exception {
- Assert.assertEquals("tcp://localhost:5554", spy.getAddress());
- Assert.assertEquals(ZMQ.REQ, spy.getSocket().getType());
- }
-
- @Test(expected = TimeoutException.class)
- public void send_WhenQueueGetsFull_ShouldThrow() throws Exception {
-
- doNothing().when(spy).process();
-
- //10 is queue size
- for (int i=0;i<10;i++){
- spy.send(getEmptyMessageWrapper());
- }
-
- //sending 11th message should throw
- spy.send(getEmptyMessageWrapper());
- }
-
- @Test
- public void testHasTimedOut() throws Exception {
- spy.send(getEmptyMessageWrapper());
- Assert.assertFalse(spy.hasTimedOut());
- Thread.sleep(1000);
- Assert.assertFalse(spy.hasTimedOut());
- Thread.sleep(1000);
- Assert.assertTrue(spy.hasTimedOut());
- }
-
- @Test
- public void testProcess() throws Exception {
- PowerMockito.doNothing().when(spy, "sendMessage");
- spy.send(getEmptyMessageWrapper());
-
- //Next message should get queued
- spy.send(getEmptyMessageWrapper());
-
- //queue size should be 2
- Assert.assertEquals(2, spy.getQueueSize());
-
-
- spy.process();
- //sleep for 2 secs (timeout)
- //message send would be retried
- Thread.sleep(2000);
- spy.process();
- Thread.sleep(2000);
- spy.process();
- Thread.sleep(2000);
- spy.process(); //retry fails, next message will get picked up
- Assert.assertEquals(1, spy.getQueueSize());
- }
-
- @Test
- public void testProcessStateTransitions() throws Exception {
- PowerMockito.doNothing().when(spy, "sendMessage");
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- spy.send(getEmptyMessageWrapper());
- Assert.assertEquals(1, spy.getQueueSize());
- Thread.sleep(200);
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
- Thread.sleep(1800);
-
- //1st timeout, 2nd try
- spy.process();
- Thread.sleep(200);
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
- Thread.sleep(1800);
-
- //2nd timeout, 3rd try
- spy.process();
- Thread.sleep(200);
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
- Thread.sleep(1800);
-
- //3rd timeout, no more tries => remove
- spy.process();
- Thread.sleep(200);
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- Assert.assertEquals(0, spy.getQueueSize());
- }
-
- @Test
- public void testParseMessage() throws Exception {
- // Write an integration test for parseMessage
- }
-
- @Test
- public void testRecycleSocket() throws Exception {
- // This will need to be updated in the future...for now, recycleSocket() calls close()
- Assert.assertTrue(spy.getSocket().base().check_tag());
- spy.close();
- Assert.assertEquals(10, spy.getSocket().getLinger());
- Assert.assertFalse(spy.getSocket().base().check_tag());
- }
-
- @Test
- public void testClose() throws Exception {
- Assert.assertTrue(spy.getSocket().base().check_tag());
- spy.close();
- Assert.assertEquals(10, spy.getSocket().getLinger());
- Assert.assertFalse(spy.getSocket().base().check_tag());
- }
-
- @Test
- public void testReceive() throws Exception {
- PowerMockito.doReturn(null).when(spy, "parseMessage");
- PowerMockito.doNothing().when(spy, "process");
- spy.send(getEmptyMessageWrapper());
-
- //There should be 1 message waiting in the queue
- Assert.assertEquals(1, spy.getQueueSize());
-
- spy.receive();
- //This should complete message processing
- //The message should be removed from the queue
- Assert.assertEquals(0, spy.getQueueSize());
- Assert.assertEquals(RpcSocket.NUM_RETRIES, spy.getRetriesLeft());
-
- }
-
- @Test
- public void testReceiveStateTransitions() throws Exception {
- PowerMockito.doReturn(null).when(spy, "parseMessage");
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- spy.send(getEmptyMessageWrapper());
-
- //There should be 1 message waiting in the queue
- Assert.assertEquals(1, spy.getQueueSize());
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
-
- spy.receive();
- //This should complete message processing
- //The message should be removed from the queue
- Assert.assertEquals(0, spy.getQueueSize());
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- }
-
- private MessageWrapper getEmptyMessageWrapper(){
- return new MessageWrapper(new Message(), null);
- }
-
- @Test
- public void testProcessReceiveSequence() throws Exception {
- PowerMockito.doNothing().when(spy, "sendMessage");
- PowerMockito.doReturn(null).when(spy, "parseMessage");
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- spy.send(getEmptyMessageWrapper());
- spy.send(getEmptyMessageWrapper());
- Assert.assertEquals(2, spy.getQueueSize());
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
-
-
- Thread.sleep(2000);
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
- spy.receive();
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- Assert.assertEquals(1, spy.getQueueSize());
-
- spy.process();
- Assert.assertTrue(spy.getState() instanceof RpcSocket.BusySocketState);
- spy.receive();
- Assert.assertTrue(spy.getState() instanceof RpcSocket.IdleSocketState);
- Assert.assertEquals(0, spy.getQueueSize());
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+
+import com.google.common.base.Optional;
+import junit.framework.Assert;
+import org.junit.*;
+import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
+import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.RpcRegistrationListener;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.zeromq.ZMQ;
+import zmq.Ctx;
+import zmq.SocketBase;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ServerImplTest {
+
+ private static ZMQ.Context context;
+ private ServerImpl server;
+ private Broker.ProviderSession brokerSession;
+ private RoutingTableProvider routingTableProvider;
+ private RpcRegistrationListener listener;
+
+ ExecutorService pool;
+
+ //Server configuration
+ private final int HANDLER_COUNT = 2;
+ private final int HWM = 200;
+ private final int port = 5554;
+ //server address
+ private final String SERVER_ADDRESS = "tcp://localhost:5554";
+
+ //@BeforeClass
+ public static void init() {
+ context = ZMQ.context(1);
+ }
+
+ //@AfterClass
+ public static void destroy() {
+ MessagingUtil.closeZmqContext(context);
+ }
+
+ @Before
+ public void setup() throws InterruptedException {
+ context = ZMQ.context(1);
+ brokerSession = mock(Broker.ProviderSession.class);
+ routingTableProvider = mock(RoutingTableProvider.class);
+ listener = mock(RpcRegistrationListener.class);
+
+ server = new ServerImpl(port);
+ server.setBrokerSession(brokerSession);
+ server.setRoutingTableProvider(routingTableProvider);
+
+ RoutingTable<String, String> mockRoutingTable = new MockRoutingTable<String, String>();
+ Optional<RoutingTable<String, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
+ when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
+
+ when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
+ when(brokerSession.getSupportedRpcs()).thenReturn(Collections.EMPTY_SET);
+ when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null);
+ server.start();
+ Thread.sleep(5000);//wait for server to start
+ }
+
+ @After
+ public void tearDown() throws InterruptedException {
+
+ if (pool != null)
+ pool.shutdown();
+
+ if (server != null)
+ server.stop();
+
+ MessagingUtil.closeZmqContext(context);
+
+ Thread.sleep(5000);//wait for server to stop
+ Assert.assertEquals(ServerImpl.State.STOPPED, server.getStatus());
+ }
+
+ @Test
+ public void getRoutingTableProvider_Call_ShouldReturnRoutingTable() throws Exception {
+ Assert.assertNotNull(server.getRoutingTableProvider());
+ }
+
+ @Test
+ public void getBrokerSession_Call_ShouldReturnBrokerSession() throws Exception {
+ Optional<Broker.ProviderSession> mayBeBroker = server.getBrokerSession();
+
+ if (mayBeBroker.isPresent())
+ Assert.assertEquals(brokerSession, mayBeBroker.get());
+ else
+ Assert.fail("Broker does not exist in Remote RPC Server");
+
+ }
+
+ @Test
+ public void start_Call_ShouldSetServerStatusToStarted() throws Exception {
+ Assert.assertEquals(ServerImpl.State.STARTED, server.getStatus());
+
+ }
+
+ @Test
+ public void start_Call_ShouldCreateNZmqSockets() throws Exception {
+ final int EXPECTED_COUNT = 2 + HANDLER_COUNT; //1 ROUTER + 1 DEALER + HANDLER_COUNT
+
+ Optional<ZMQ.Context> mayBeContext = server.getZmqContext();
+ if (mayBeContext.isPresent())
+ Assert.assertEquals(EXPECTED_COUNT, findSocketCount(mayBeContext.get()));
+ else
+ Assert.fail("ZMQ Context does not exist in Remote RPC Server");
+ }
+
+ @Test
+ public void start_Call_ShouldCreate1ServerThread() {
+ final String SERVER_THREAD_NAME = "remote-rpc-server";
+ final int EXPECTED_COUNT = 1;
+ List<Thread> serverThreads = findThreadsWithName(SERVER_THREAD_NAME);
+ Assert.assertEquals(EXPECTED_COUNT, serverThreads.size());
+ }
+
+ @Test
+ public void start_Call_ShouldCreateNHandlerThreads() {
+ //final String WORKER_THREAD_NAME = "remote-rpc-worker";
+ final int EXPECTED_COUNT = HANDLER_COUNT;
+
+ Optional<ServerRequestHandler> serverRequestHandlerOptional = server.getHandler();
+ if (serverRequestHandlerOptional.isPresent()){
+ ServerRequestHandler handler = serverRequestHandlerOptional.get();
+ ThreadPoolExecutor workerPool = handler.getWorkerPool();
+ Assert.assertEquals(EXPECTED_COUNT, workerPool.getPoolSize());
+ } else {
+ Assert.fail("Server is in illegal state. ServerHandler does not exist");
+ }
+
+ }
+
+ @Test
+ public void testStop() throws Exception {
+
+ }
+
+ @Test
+ public void testOnRouteUpdated() throws Exception {
+
+ }
+
+ @Test
+ public void testOnRouteDeleted() throws Exception {
+
+ }
+
+ private int findSocketCount(ZMQ.Context context)
+ throws NoSuchFieldException, IllegalAccessException {
+ Field ctxField = context.getClass().getDeclaredField("ctx");
+ ctxField.setAccessible(true);
+ Ctx ctx = Ctx.class.cast(ctxField.get(context));
+
+ Field socketListField = ctx.getClass().getDeclaredField("sockets");
+ socketListField.setAccessible(true);
+ List<SocketBase> sockets = List.class.cast(socketListField.get(ctx));
+
+ return sockets.size();
+ }
+
+ private List<Thread> findThreadsWithName(String name) {
+ Thread[] threads = new Thread[Thread.activeCount()];
+ Thread.enumerate(threads);
+
+ List<Thread> foundThreads = new ArrayList();
+ for (Thread t : threads) {
+ if (t.getName().startsWith(name))
+ foundThreads.add(t);
+ }
+
+ return foundThreads;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc;
+
+import junit.framework.Assert;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil;
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.zeromq.ZMQ;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.mockito.Mockito.mock;
+
+public class ServerRequestHandlerTest {
+
+ ServerRequestHandler handler;
+ ZMQ.Context context;
+ ExecutorService executorService = Executors.newCachedThreadPool();
+ private int workerCount = 2;
+ private String mockDealerAddress = "inproc://rpc-request-handler";
+ private String mockServerIp = "localhost";
+ private int mockServerPort = 5554;
+
+ @Before
+ public void setUp() throws Exception {
+ context = ZMQ.context(1);
+ String mockServerAddress = mockServerIp + ":" + mockServerPort;
+ Broker.ProviderSession mockSession = mock(Broker.ProviderSession.class);
+ handler = new ServerRequestHandler(context, mockSession, workerCount, mockDealerAddress, mockServerAddress);
+ handler.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ executorService.shutdown();
+ MessagingUtil.closeZmqContext(context);
+ handler.close();
+ }
+
+ @Test
+ public void testStart() throws Exception {
+ //should start workers == workerCount
+ Assert.assertEquals(workerCount, handler.getWorkerPool().getPoolSize());
+
+ //killing a thread should recreate another one
+
+ //start router-dealer bridge
+ executorService.execute(MessagingUtil.createRouterDealerBridge(context, mockDealerAddress, mockServerPort));
+ Thread.sleep(1000); //give sometime for socket initialization
+
+ //this will kill the thread
+ final String WORKER_THREAD_NAME = "remote-rpc-worker";
+ interruptAThreadWithName(WORKER_THREAD_NAME);
+
+ //send 4 message to router
+ for (int i = 0; i < 4; i++)
+ executorService.execute(MessagingUtil.sendAnEmptyMessage(context, "tcp://" + mockServerIp + ":" + mockServerPort));
+
+ //worker pool size should not change.
+ Assert.assertEquals(workerCount, handler.getWorkerPool().getPoolSize());
+
+ Thread.sleep(10000); //wait for processing to complete
+ }
+
+ @Test
+ public void testClose() throws Exception {
+
+ }
+
+ /**
+ * Interrupts the first thread found whose name starts with the provided name
+ *
+ * @param name
+ */
+ private void interruptAThreadWithName(String name) {
+ List<Thread> workerThreads = findThreadsWithName(name);
+ if (workerThreads.size() > 0) workerThreads.get(0).interrupt();
+ }
+
+ /**
+ * Find all threads that start with the given name
+ *
+ * @param name
+ * @return
+ */
+ private List<Thread> findThreadsWithName(String name) {
+ Thread[] threads = new Thread[Thread.activeCount()];
+ Thread.enumerate(threads);
+
+ List<Thread> foundThreads = new ArrayList();
+ for (Thread t : threads) {
+ if (t.getName().startsWith(name))
+ foundThreads.add(t);
+ }
+
+ return foundThreads;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import com.google.common.base.Optional;
-import junit.framework.Assert;
-import org.junit.After;
-import org.junit.Before;
-import org.zeromq.ZMQ;
-import org.opendaylight.controller.sal.connector.remoterpc.SocketManager;
-import org.opendaylight.controller.sal.connector.remoterpc.RpcSocket;
-import org.opendaylight.controller.sal.connector.remoterpc.Context;
-import org.junit.Test;
-
-public class SocketManagerTest {
-
- SocketManager manager;
-
- @Before
- public void setup(){
- manager = new SocketManager();
- }
-
- @After
- public void tearDown() throws Exception {
- manager.close();
- }
-
- @Test
- public void getManagedSockets_When2NewAdded_ShouldContain2() throws Exception {
-
- //Prepare data
- manager.getManagedSocket("tcp://localhost:5554");
- manager.getManagedSocket("tcp://localhost:5555");
-
- Assert.assertTrue( 2 == manager.getManagedSockets().size());
- }
-
- @Test
- public void getManagedSockets_When2NewAddedAnd1Existing_ShouldContain2() throws Exception {
-
- //Prepare data
- manager.getManagedSocket("tcp://localhost:5554");
- manager.getManagedSocket("tcp://localhost:5555");
- manager.getManagedSocket("tcp://localhost:5554"); //ask for the first one
-
- Assert.assertTrue( 2 == manager.getManagedSockets().size());
- }
-
- @Test
- public void getManagedSocket_WhenPassedAValidAddress_ShouldReturnARpcSocket() throws Exception {
- String testAddress = "tcp://localhost:5554";
- RpcSocket rpcSocket = manager.getManagedSocket(testAddress);
- Assert.assertEquals(testAddress, rpcSocket.getAddress());
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void getManagedSocket_WhenPassedInvalidHostAddress_ShouldThrow() throws Exception {
- String testAddress = "tcp://nonexistenthost:5554";
- RpcSocket rpcSocket = manager.getManagedSocket(testAddress);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void getManagedSocket_WhenPassedInvalidAddress_ShouldThrow() throws Exception {
- String testAddress = "xxx";
- RpcSocket rpcSocket = manager.getManagedSocket(testAddress);
- }
-
- @Test
- public void getManagedSocket_WhenPassedAValidZmqSocket_ShouldReturnARpcSocket() throws Exception {
- //Prepare data
- String firstAddress = "tcp://localhost:5554";
- RpcSocket firstRpcSocket = manager.getManagedSocket(firstAddress);
- ZMQ.Socket firstZmqSocket = firstRpcSocket.getSocket();
-
- String secondAddress = "tcp://localhost:5555";
- RpcSocket secondRpcSocket = manager.getManagedSocket(secondAddress);
- ZMQ.Socket secondZmqSocket = secondRpcSocket.getSocket();
-
- Assert.assertEquals(firstRpcSocket, manager.getManagedSocketFor(firstZmqSocket).get());
- Assert.assertEquals(secondRpcSocket, manager.getManagedSocketFor(secondZmqSocket).get());
- }
-
- @Test
- public void getManagedSocket_WhenPassedNonManagedZmqSocket_ShouldReturnNone() throws Exception {
- ZMQ.Socket nonManagedSocket = Context.getInstance().getZmqContext().socket(ZMQ.REQ);
- nonManagedSocket.connect("tcp://localhost:5000");
-
- //Prepare data
- String firstAddress = "tcp://localhost:5554";
- RpcSocket firstRpcSocket = manager.getManagedSocket(firstAddress);
- ZMQ.Socket firstZmqSocket = firstRpcSocket.getSocket();
-
- Assert.assertSame(Optional.<RpcSocket>absent(), manager.getManagedSocketFor(nonManagedSocket) );
- Assert.assertSame(Optional.<RpcSocket>absent(), manager.getManagedSocketFor(null) );
- }
-
- @Test
- public void stop_WhenCalled_ShouldEmptyManagedSockets() throws Exception {
- manager.getManagedSocket("tcp://localhost:5554");
- manager.getManagedSocket("tcp://localhost:5555");
- Assert.assertTrue( 2 == manager.getManagedSockets().size());
-
- manager.close();
- Assert.assertTrue( 0 == manager.getManagedSockets().size());
- }
-
- @Test
- public void poller_WhenCalled_ShouldReturnAnInstanceOfPoller() throws Exception {
- Assert.assertTrue (manager.getPoller() instanceof ZMQ.Poller);
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.sal.connector.remoterpc.utils;
+
+import junit.framework.Assert;
+import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.zeromq.ZMQ;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+public class MessagingUtil {
+
+ private static final Logger _logger = LoggerFactory.getLogger(MessagingUtil.class);
+
+ public static Runnable startReplyServer(final ZMQ.Context context,
+ final String serverAddress,
+ final int numRequests /*number of requests after which server shuts down*/) {
+ return new Runnable() {
+
+ @Override
+ public void run() {
+ final ZMQ.Socket socket = context.socket(ZMQ.REP);
+ try {
+ int returnCode = socket.bind("tcp://" + serverAddress);
+ Assert.assertNotSame(-1, returnCode);
+ _logger.info(" Starting reply server[{}] for test...", serverAddress);
+
+ //for (int i=0;i<numRequests;i++) {
+ while (!Thread.currentThread().isInterrupted()) {
+ byte[] bytes = socket.recv();
+ _logger.debug(" Got request ");
+ socket.send(bytes);
+ _logger.debug(" Sent response ");
+ }
+ } catch (Exception x) {
+ StringWriter w = new StringWriter();
+ PrintWriter p = new PrintWriter(w);
+ x.printStackTrace(p);
+ _logger.debug(w.toString());
+ } finally {
+ socket.close();
+ _logger.info("Shutting down reply server");
+ }
+ }
+ };
+ }
+
+ public static Runnable createRouterDealerBridge(final ZMQ.Context context, final String dealerAddress, final int routerPort) {
+ return new Runnable() {
+ @Override
+ public void run() {
+ ZMQ.Socket router = null;
+ ZMQ.Socket dealer = null;
+ try {
+ router = context.socket(ZMQ.ROUTER);
+ dealer = context.socket(ZMQ.DEALER);
+ router.bind("tcp://*:" + routerPort);
+ dealer.bind(dealerAddress);
+ ZMQ.proxy(router, dealer, null);
+ } catch (Exception e) {/*Ignore*/} finally {
+ if (router != null) router.close();
+ if (dealer != null) dealer.close();
+ }
+ }
+ };
+ }
+
+ public static Runnable sendAnEmptyMessage(final ZMQ.Context context, final String serverAddress)
+ throws IOException, ClassNotFoundException, InterruptedException {
+
+ return new Runnable() {
+ @Override
+ public void run() {
+ final ZMQ.Socket socket = context.socket(ZMQ.REQ);
+ try {
+
+ socket.connect(serverAddress);
+ System.out.println(Thread.currentThread().getName() + " Sending message");
+ try {
+ socket.send(Message.serialize(new Message()));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ byte[] bytes = socket.recv();
+ Message response = null;
+ try {
+ response = (Message) Message.deserialize(bytes);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+ System.out.println(Thread.currentThread().getName() + " Got response " + response);
+ } catch (Exception x) {
+ x.printStackTrace();
+ } finally {
+ socket.close();
+ }
+ }
+ };
+ }
+
+ public static Message createEmptyMessage() {
+ return new Message();
+ }
+
+ /**
+ * Closes ZMQ Context. It tries to gracefully terminate the context. If
+ * termination takes more than a second, its forcefully shutdown.
+ */
+ public static void closeZmqContext(final ZMQ.Context context) {
+ if (context == null) return;
+
+ ExecutorService exec = Executors.newSingleThreadExecutor();
+ FutureTask zmqTermination = new FutureTask(new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ if (context != null)
+ context.term();
+ _logger.debug("ZMQ Context terminated gracefully!");
+ } catch (Exception e) {/*Ignore and continue shutdown*/}
+ }
+ }, null);
+
+ exec.execute(zmqTermination);
+
+ try {
+ zmqTermination.get(1L, TimeUnit.SECONDS);
+ } catch (Exception e) {
+ _logger.debug("ZMQ Context terminated forcefully!");
+ }
+
+ exec.shutdownNow();
+ }
+}
--- /dev/null
+<configuration scan="true">
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+ </pattern>
+ </encoder>
+ </appender>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT" />
+ </root>
+</configuration>
import org.opendaylight.controller.sal.common.util.RpcErrors;
import org.opendaylight.controller.sal.common.util.Rpcs;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.CompositeNodeImpl;
import org.opendaylight.controller.sal.core.api.AbstractProvider;
import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration;
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>yang-ext</artifactId>
- <version>2013.09.07.1</version>
+ <version>2013.09.07.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.yangtools.model</groupId>
<artifactId>opendaylight-l2-types</artifactId>
- <version>2013.08.27.1</version>
+ <version>2013.08.27.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.opendaylight.controller.sal.connector.remoterpc.Client;
+
import org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient;
-import org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcServer;
-import org.opendaylight.controller.sal.connector.remoterpc.ServerImpl;
+
import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
import org.opendaylight.controller.sal.core.api.Broker;
-import org.opendaylight.controller.sample.zeromq.provider.ExampleProvider;
import org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer;
+import org.opendaylight.controller.sample.zeromq.provider.ExampleProvider;
+
import org.opendaylight.controller.test.sal.binding.it.TestHelper;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
-import org.osgi.framework.ServiceRegistration;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zeromq.ZMQ;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.baseModelBundles;
import static org.opendaylight.controller.test.sal.binding.it.TestHelper.bindingAwareSalBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.configMinumumBundles;
-import static org.opendaylight.controller.test.sal.binding.it.TestHelper.mdSalCoreBundles;
+
import static org.ops4j.pax.exam.CoreOptions.*;
@RunWith(PaxExam.class)
_logger.debug("Provider sends announcement [{}]", "heartbeat");
provider.announce(QNAME);
- ServiceReference routerRef = ctx.getServiceReference(Client.class);
- Client router = (Client) ctx.getService(routerRef);
+ ServiceReference routerRef = ctx.getServiceReference(RemoteRpcClient.class);
+ RemoteRpcClient router = (RemoteRpcClient) ctx.getService(routerRef);
_logger.debug("Found router[{}]", router);
_logger.debug("Invoking RPC [{}]", QNAME);
for (int i = 0; i < 3; i++) {
}
}
}
+
private String stateToString(int state) {
switch (state) {
case Bundle.ACTIVE:
@Configuration
public Option[] config() {
return options(systemProperty("osgi.console").value("2401"),
- systemProperty("rpc.port").value("5555"),
- mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), //
- mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
- mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
- mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
-
- //mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-common").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
- mavenBundle(ODL, "sal-common-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-util").versionAsInProject(), //
- mavenBundle(ODL, "sal-core-api").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-broker-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-core-spi").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-connector-api").versionAsInProject(), //
-
-
-
- baseModelBundles(),
- bindingAwareSalBundles(),
- TestHelper.bindingIndependentSalBundles(),
- TestHelper.configMinumumBundles(),
- TestHelper.mdSalCoreBundles(),
-
- //Added the consumer
- mavenBundle(SAMPLE, "sal-remoterpc-connector-test-consumer").versionAsInProject(), //
- //**** These two bundles below are NOT successfully resolved -- some of their dependencies must be missing
- //**** This causes the "Message" error to occur, the class cannot be found
- mavenBundle(SAMPLE, "sal-remoterpc-connector-test-provider").versionAsInProject(), //
- mavenBundle(ODL, "sal-remoterpc-connector").versionAsInProject(), //
-
- mavenBundle(ODL, "zeromq-routingtable.implementation").versionAsInProject(),
- mavenBundle(YANG, "concepts").versionAsInProject(),
- mavenBundle(YANG, "yang-binding").versionAsInProject(), //
- mavenBundle(YANG, "yang-common").versionAsInProject(), //
- mavenBundle(YANG, "yang-data-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-data-impl").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-parser-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-parser-impl").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
- mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), //
- mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
- mavenBundle("com.google.guava", "guava").versionAsInProject(), //
- mavenBundle("org.zeromq", "jeromq").versionAsInProject(),
- mavenBundle("com.fasterxml.jackson.core", "jackson-annotations").versionAsInProject(),
- mavenBundle("com.fasterxml.jackson.core", "jackson-core").versionAsInProject(),
- mavenBundle("com.fasterxml.jackson.core", "jackson-databind").versionAsInProject(),
- //routingtable dependencies
- systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
- // List framework bundles
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.console").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.util").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.osgi.services").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime").versionAsInProject(),
- mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell").versionAsInProject(),
- // List logger bundles
-
- mavenBundle("org.opendaylight.controller", "clustering.services")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.controller", "clustering.stub")
- .versionAsInProject(),
-
-
- // List all the bundles on which the test case depends
- mavenBundle("org.opendaylight.controller", "sal")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.controller", "sal.implementation")
- .versionAsInProject(),
- mavenBundle("org.jboss.spec.javax.transaction",
- "jboss-transaction-api_1.1_spec").versionAsInProject(),
- mavenBundle("org.apache.commons", "commons-lang3")
- .versionAsInProject(),
- mavenBundle("org.apache.felix",
- "org.apache.felix.dependencymanager")
- .versionAsInProject(),
-
- junitBundles()
+ systemProperty("rpc.port").value("5555"),
+ mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(), //
+ mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(), //
+ mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(), //
+ mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(), //
+
+ //mavenBundle(ODL, "sal-binding-broker-impl").versionAsInProject().update(), //
+ mavenBundle(ODL, "sal-common").versionAsInProject(), //
+ mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
+ mavenBundle(ODL, "sal-common-impl").versionAsInProject(), //
+ mavenBundle(ODL, "sal-common-util").versionAsInProject(), //
+ mavenBundle(ODL, "sal-core-api").versionAsInProject().update(), //
+ mavenBundle(ODL, "sal-broker-impl").versionAsInProject(), //
+ mavenBundle(ODL, "sal-core-spi").versionAsInProject().update(), //
+ mavenBundle(ODL, "sal-connector-api").versionAsInProject(), //
+
+
+ baseModelBundles(),
+ bindingAwareSalBundles(),
+ TestHelper.bindingIndependentSalBundles(),
+ TestHelper.configMinumumBundles(),
+ TestHelper.mdSalCoreBundles(),
+
+ //Added the consumer
+ mavenBundle(SAMPLE, "sal-remoterpc-connector-test-consumer").versionAsInProject(), //
+ //**** These two bundles below are NOT successfully resolved -- some of their dependencies must be missing
+ //**** This causes the "Message" error to occur, the class cannot be found
+ mavenBundle(SAMPLE, "sal-remoterpc-connector-test-provider").versionAsInProject(), //
+ mavenBundle(ODL, "sal-remoterpc-connector").versionAsInProject(), //
+
+ mavenBundle(ODL, "zeromq-routingtable.implementation").versionAsInProject(),
+ mavenBundle(YANG, "concepts").versionAsInProject(),
+ mavenBundle(YANG, "yang-binding").versionAsInProject(), //
+ mavenBundle(YANG, "yang-common").versionAsInProject(), //
+ mavenBundle(YANG, "yang-data-api").versionAsInProject(), //
+ mavenBundle(YANG, "yang-data-impl").versionAsInProject(), //
+ mavenBundle(YANG, "yang-model-api").versionAsInProject(), //
+ mavenBundle(YANG, "yang-parser-api").versionAsInProject(), //
+ mavenBundle(YANG, "yang-parser-impl").versionAsInProject(), //
+ mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
+ mavenBundle(YANG + ".thirdparty", "xtend-lib-osgi").versionAsInProject(), //
+ mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
+ mavenBundle("com.google.guava", "guava").versionAsInProject(), //
+ mavenBundle("org.zeromq", "jeromq").versionAsInProject(),
+ mavenBundle("org.codehaus.jackson", "jackson-mapper-asl").versionAsInProject(),
+ mavenBundle("org.codehaus.jackson", "jackson-core-asl").versionAsInProject(),
+ //routingtable dependencies
+ systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),
+ // List framework bundles
+ mavenBundle("equinoxSDK381", "org.eclipse.equinox.console").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.eclipse.equinox.util").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.eclipse.osgi.services").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime").versionAsInProject(),
+ mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell").versionAsInProject(),
+ // List logger bundles
+
+ mavenBundle("org.opendaylight.controller", "clustering.services")
+ .versionAsInProject(),
+ mavenBundle("org.opendaylight.controller", "clustering.stub")
+ .versionAsInProject(),
+
+
+ // List all the bundles on which the test case depends
+ mavenBundle("org.opendaylight.controller", "sal")
+ .versionAsInProject(),
+ mavenBundle("org.opendaylight.controller", "sal.implementation")
+ .versionAsInProject(),
+ mavenBundle("org.jboss.spec.javax.transaction",
+ "jboss-transaction-api_1.1_spec").versionAsInProject(),
+ mavenBundle("org.apache.commons", "commons-lang3")
+ .versionAsInProject(),
+ mavenBundle("org.apache.felix",
+ "org.apache.felix.dependencymanager")
+ .versionAsInProject(),
+
+ junitBundles()
);
}
import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException;
import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.CompositeNodeImpl;
import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl;
import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
import org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer;
_logger.info("Invoking RPC");
ExampleConsumer consumer = getConsumer();
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, new CompositeNodeImpl());
+ RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
_logger.info("Result [{}]", result.isSuccessful());
return stringify(result);
_logger.debug("Could not get routing table impl reference");
return "Could not get routingtable referen ";
}
- RoutingTable routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
+ RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
if (routingTable == null) {
_logger.info("Could not get routing table service");
return "Could not get routing table service";
_logger.error("error in adding routing identifier" + e.getMessage());
}
- Set<String> routes = routingTable.getRoutes(rii.toString());
+ String result = routingTable.dumpRoutingTableCache();
- StringBuilder stringBuilder = new StringBuilder();
- for (String route : routes) {
- stringBuilder.append(route);
- }
- _logger.info("Result [{}] routes added for route" + rii + stringBuilder.toString());
- return stringBuilder.toString();
+
+ _logger.info("Result [{}] routes added for route" + rii + result);
+
+ return result;
}
@GET
public org.opendaylight.yangtools.yang.data.api.InstanceIdentifier getRoute() {
return InstanceIdentifier.of(instance);
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ RoutingIdentifierImpl that = (RoutingIdentifierImpl) o;
+
+ if (!QNAME.equals(that.QNAME)) return false;
+ if (!instance.equals(that.instance)) return false;
+ if (!namespace.equals(that.namespace)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = namespace.hashCode();
+ result = 31 * result + QNAME.hashCode();
+ result = 31 * result + instance.hashCode();
+ return result;
+ }
}
}
override readConfigurationData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Configuration via Restconf: {}", path)
+ LOG.trace("Read Configuration via Restconf: {}", path)
return dataService.readConfigurationData(path);
}
def readConfigurationDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Configuration via Restconf: {}", path)
+ LOG.trace("Read Configuration via Restconf: {}", path)
return mountPoint.readConfigurationData(path);
}
override readOperationalData(InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Operational via Restconf: {}", path)
+ LOG.trace("Read Operational via Restconf: {}", path)
return dataService.readOperationalData(path);
}
def readOperationalDataBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path) {
checkPreconditions
- LOG.info("Read Operational via Restconf: {}", path)
+ LOG.trace("Read Operational via Restconf: {}", path)
return mountPoint.readOperationalData(path);
}
def commitConfigurationDataPut(InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
val transaction = dataService.beginTransaction;
- LOG.info("Put Configuration via Restconf: {}", path)
+ LOG.trace("Put Configuration via Restconf: {}", path)
transaction.putConfigurationData(path, payload);
return transaction.commit
}
def commitConfigurationDataPutBehindMountPoint(MountInstance mountPoint, InstanceIdentifier path, CompositeNode payload) {
checkPreconditions
val transaction = mountPoint.beginTransaction;
- LOG.info("Put Configuration via Restconf: {}", path)
+ LOG.trace("Put Configuration via Restconf: {}", path)
transaction.putConfigurationData(path, payload);
return transaction.commit
}
val transaction = dataService.beginTransaction;
transaction.putConfigurationData(path, payload);
if (payload == transaction.createdConfigurationData.get(path)) {
- LOG.info("Post Configuration via Restconf: {}", path)
+ LOG.trace("Post Configuration via Restconf: {}", path)
return transaction.commit
}
- LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ LOG.trace("Post Configuration via Restconf was not executed because data already exists: {}", path)
return null;
}
val transaction = mountPoint.beginTransaction;
transaction.putConfigurationData(path, payload);
if (payload == transaction.createdConfigurationData.get(path)) {
- LOG.info("Post Configuration via Restconf: {}", path)
+ LOG.trace("Post Configuration via Restconf: {}", path)
return transaction.commit
}
- LOG.info("Post Configuration via Restconf was not executed because data already exists: {}", path)
+ LOG.trace("Post Configuration via Restconf was not executed because data already exists: {}", path)
return null;
}
package org.opendaylight.controller.sal.restconf.impl.json.to.cnsn.test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import javax.ws.rs.WebApplicationException;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.sal.rest.impl.JsonToCompositeNodeProvider;
import org.opendaylight.controller.sal.restconf.impl.CompositeNodeWrapper;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
assertEquals("iden_local", ((QName) lf14.getValue()).getLocalName());
assertEquals("identity:module", ((QName) lf14.getValue()).getNamespace().toString());
}
+
+ @Ignore
+ @Test
+ public void loadDataAugmentedSchemaMoreEqualNamesTest() {
+ boolean exceptionCaught = false;
+ try {
+ loadAndNormalizeData("/common/augment/json/dataa.json", "/common/augment/yang", "cont", "main");
+ loadAndNormalizeData("/common/augment/json/datab.json", "/common/augment/yang", "cont", "main");
+ } catch (ResponseException e) {
+ exceptionCaught = true;
+ }
+
+ assertFalse(exceptionCaught);
+ }
private void simpleTest(String jsonPath, String yangPath, String topLevelElementName, String namespace,
String moduleName) {
+ CompositeNode compNode = loadAndNormalizeData(jsonPath, yangPath, topLevelElementName, moduleName);
+ verifyCompositeNode(compNode, namespace);
+ }
+
+ private CompositeNode loadAndNormalizeData(String jsonPath, String yangPath, String topLevelElementName, String moduleName) {
CompositeNode compositeNode = TestUtils.readInputToCnSn(jsonPath, false, JsonToCompositeNodeProvider.INSTANCE);
assertNotNull(compositeNode);
CompositeNode compNode = ((CompositeNodeWrapper) compositeNode).unwrap();
assertEquals(topLevelElementName, compNode.getNodeType().getLocalName());
- verifyCompositeNode(compNode, namespace);
+ return compNode;
}
private void verityMultipleItemsInList(CompositeNode compositeNode) {
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
+import org.opendaylight.controller.sal.restconf.impl.InstanceIdWithSchemaNode;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class RestGetAugmentedElementWhenEqualNamesTest {
+
+ @Ignore
+ @Test
+ public void getDataWithUrlMountPoint() throws UnsupportedEncodingException, URISyntaxException,
+ FileNotFoundException {
+ boolean exceptionCaught = false;
+
+ SchemaContext schemaContextTestModule = TestUtils.loadSchemaContext("/common/augment/yang");
+ ControllerContext controllerContext = ControllerContext.getInstance();
+ controllerContext.setSchemas(schemaContextTestModule);
+
+ try {
+ InstanceIdWithSchemaNode instanceIdentifierA = controllerContext
+ .toInstanceIdentifier("main:cont/augment-main-a:cont1");
+ InstanceIdWithSchemaNode instanceIdentifierB = controllerContext
+ .toInstanceIdentifier("main:cont/augment-main-b:cont1");
+
+ assertEquals("ns:augment:main:a", instanceIdentifierA.getSchemaNode().getQName().getNamespace().toString());
+ assertEquals("ns:augment:main:b", instanceIdentifierB.getSchemaNode().getQName().getNamespace());
+ } catch (ResponseException e) {
+ exceptionCaught = true;
+ }
+
+ assertFalse(exceptionCaught);
+
+ }
+
+}
--- /dev/null
+package org.opendaylight.controller.sal.restconf.impl.xml.to.cnsn.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Set;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.sal.rest.impl.XmlToCompositeNodeProvider;
+import org.opendaylight.controller.sal.restconf.impl.ResponseException;
+import org.opendaylight.controller.sal.restconf.impl.test.TestUtils;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+
+public class XmlAugmentedElementToCnSnTest {
+
+ @Ignore
+ @Test
+ public void loadDataAugmentedSchemaMoreEqualNamesTest() {
+ boolean exceptionCaught = false;
+ try {
+ loadAndNormalizeData("/common/augment/xml/dataa.xml", "/common/augment/yang", "main","cont");
+ loadAndNormalizeData("/common/augment/xml/datab.xml", "/common/augment/yang", "main","cont");
+ } catch (ResponseException e) {
+ exceptionCaught = true;
+ }
+
+ assertFalse(exceptionCaught);
+ }
+
+
+ private void loadAndNormalizeData(String xmlPath, String yangPath, String topLevelElementName, String moduleName) {
+ CompositeNode compNode = TestUtils.readInputToCnSn(xmlPath, false,
+ XmlToCompositeNodeProvider.INSTANCE);
+ assertNotNull(compNode);
+ Set<Module> modules = TestUtils.loadModulesFrom(yangPath);
+
+ assertNotNull(modules);
+ TestUtils.normalizeCompositeNode(compNode, modules, topLevelElementName + ":" + moduleName);
+ }
+
+
+}
--- /dev/null
+{
+ "main:cont":{
+ "augment-main-a:cont1":{
+ "lf11":"lf11 value from a"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "main:cont":{
+ "augment-main-b:cont1":{
+ "lf11":"lf11 value from b"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<cont xmlns="ns:main">
+ <cont1 xmlns="ns:augment:main:a">
+ <lf11>lf11 value for a</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+<cont xmlns="ns:main">
+ <cont1 xmlns="ns:augment:main:b">
+ <lf11>lf11 value for b</lf11>
+ </cont1>
+</cont>
\ No newline at end of file
--- /dev/null
+module augment-main-a {
+ namespace "ns:augment:main:a";
+ prefix "aumaa";
+
+
+ import main {prefix mn; revision-date 2014-01-21;}
+
+
+ revision "2014-01-21" {
+ }
+
+ augment "/mn:cont" {
+ container cont1 {
+ leaf lf11 {
+ type string;
+ }
+ }
+ }
+
+}
--- /dev/null
+module augment-main-b {
+ namespace "ns:augment:main:b";
+ prefix "aumab";
+
+
+ import main {prefix mn; revision-date 2014-01-21;}
+
+
+ revision "2014-01-21" {
+ }
+
+ augment "/mn:cont" {
+ container cont1 {
+ leaf lf11 {
+ type string;
+ }
+ }
+ }
+
+}
--- /dev/null
+module main {
+ namespace "ns:main";
+ prefix "ma";
+
+ revision "2014-01-21" {
+ }
+
+ container cont {
+ }
+}
\ No newline at end of file
--- /dev/null
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>sal-restconf-broker</artifactId>
+ <packaging>jar</packaging>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
+ </scm>
+ <properties>
+ <opendaylight.binding.version>0.6.0-SNAPSHOT</opendaylight.binding.version>
+ <opendaylight.yang.version>0.5.9-SNAPSHOT</opendaylight.yang.version>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-remote</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>restconf-client-api</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.net.URL;
+import java.util.concurrent.Future;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.common.DataStoreIdentifier;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.restconf.client.api.RestconfClientContext;
+import org.opendaylight.yangtools.restconf.client.api.RestconfClientContextFactory;
+import org.opendaylight.yangtools.restconf.client.api.UnsupportedProtocolException;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DataBrokerServiceImpl implements DataBrokerService {
+
+ private static final Logger logger = LoggerFactory.getLogger(DataBrokerServiceImpl.class.toString());
+ private final RestconfClientContext restconfClientContext;
+ private final RestconfClientContextFactory restconfClientContextFactory = null;
+
+ public DataBrokerServiceImpl(URL baseUrl) throws UnsupportedProtocolException {
+ this.restconfClientContext = restconfClientContextFactory.getRestconfClientContext(baseUrl);
+ }
+ @Override
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, Class<T> rootType) {
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getData(DataStoreIdentifier store, T filter) {
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, Class<T> rootType) {
+ return null;
+ }
+
+ @Override
+ public <T extends DataRoot> T getCandidateData(DataStoreIdentifier store, T filter) {
+ return null;
+ }
+
+ @Override
+ public RpcResult<DataRoot> editCandidateData(DataStoreIdentifier store, DataRoot changeSet) {
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<Void>> commit(DataStoreIdentifier store) {
+ return null;
+ }
+
+ @Override
+ public DataObject getData(InstanceIdentifier<? extends DataObject> data) {
+ return null;
+ }
+
+ @Override
+ public DataObject getConfigurationData(InstanceIdentifier<?> data) {
+ return null;
+ }
+
+ @Override
+ public DataModificationTransaction beginTransaction() {
+ //TODO implementation using sal-remote
+ return null;
+ }
+
+ @Override
+ public void registerChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+
+ }
+
+ @Override
+ public void unregisterChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener changeListener) {
+
+ }
+
+ @Override
+ public DataObject readConfigurationData(InstanceIdentifier<? extends DataObject> path) {
+ //TODO implementation using restconf-client
+ return null;
+
+ }
+
+ @Override
+ public DataObject readOperationalData(InstanceIdentifier<? extends DataObject> path) {
+ //TODO implementation using restconf-client
+ return null;
+ }
+
+ @Override
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(InstanceIdentifier<? extends DataObject> path, DataChangeListener listener) {
+ //TODO implementation using restconf-client
+ return null;
+ }
+
+
+
+
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.impl;
+
+import org.opendaylight.controller.sal.binding.api.NotificationListener;
+import org.opendaylight.controller.sal.binding.api.NotificationService;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+public class NotificationServiceImpl implements NotificationService {
+ @Override
+ public <T extends Notification> void addNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
+
+ }
+
+ @Override
+ public void addNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+
+ }
+
+ @Override
+ public void removeNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+
+ }
+
+ @Override
+ public <T extends Notification> void removeNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
+
+ }
+
+ @Override
+ public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(Class<T> notificationType, NotificationListener<T> listener) {
+ //TODO implementation using sal-remote
+ return null;
+ }
+
+ @Override
+ public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
+ //TODO implementation using sal-remote
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.impl;
+
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcConsumerRegistryImpl implements RpcConsumerRegistry {
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> module) {
+ //TODO implementation using restconf-client
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.restconf.broker;
+
+
+import org.opendaylight.controller.sal.core.api.Broker;
+import org.opendaylight.controller.sal.core.api.Consumer;
+import org.opendaylight.controller.sal.core.api.Provider;
+import org.osgi.framework.BundleContext;
+
+public class SalRemoteServiceBroker implements Broker,AutoCloseable {
+
+ @Override
+ public void close() throws Exception {
+
+ }
+
+ @Override
+ public ConsumerSession registerConsumer(Consumer cons, BundleContext context) {
+ return null;
+ }
+
+ @Override
+ public ProviderSession registerProvider(Provider prov, BundleContext context) {
+ return null;
+ }
+}
RpcResult<Void> result = getToastService().makeToast(toastInput.build()).get();
if (result.isSuccessful()) {
- log.info("Toast was successfuly finished");
+ log.trace("Toast was successfuly finished");
} else {
- log.info("Toast was not successfuly finished");
+ log.warn("Toast was not successfuly finished");
}
return result.isSuccessful();
} catch (InterruptedException | ExecutionException e) {
- log.info("Error occured during toast creation");
+ log.warn("Error occured during toast creation");
}
return false;
}
-
+
@Override
@Deprecated
protected void startImpl(BundleContext context) {
@Override
public void onNotification(ToastDone notification) {
- log.info("ToastDone Notification Received: {} ",notification.getToastStatus());
+ log.trace("ToastDone Notification Received: {} ",notification.getToastStatus());
}
@Override
public Future<RpcResult<Void>> makeToast(MakeToastInput input) {
// TODO Auto-generated method stub
- log.info("makeToast - Received input for toast");
+ log.trace("makeToast - Received input for toast");
logToastInput(input);
if (currentTask != null) {
return inProgressError();
private void logToastInput(MakeToastInput input) {
String toastType = input.getToasterToastType().getName();
String toastDoneness = input.getToasterDoneness().toString();
- log.info("Toast: {} doneness: {}", toastType, toastDoneness);
+ log.trace("Toast: {} doneness: {}", toastType, toastDoneness);
}
private class MakeToastTask implements Callable<RpcResult<Void>> {
ToastDoneBuilder notifyBuilder = new ToastDoneBuilder();
notifyBuilder.setToastStatus(ToastStatus.Done);
notificationProvider.notify(notifyBuilder.build());
- log.info("Toast Done");
+ log.trace("Toast Done");
logToastInput(toastRequest);
currentTask = null;
return Rpcs.<Void> getRpcResult(true, null, Collections.<RpcError> emptySet());
+++ /dev/null
-/*
- * Copyright IBM Corporation, 2013. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.md.statistics.manager;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.aggregate.flow.statistics.AggregateFlowStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.group.features.GroupFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.statistics.reply.GroupStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.MeterFeatures;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericTableStatistics;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.NodeConnectorStatistics;
-
-public class NodeStatistics {
-
- private NodeRef targetNode;
-
- private List<GroupStats> groupStatistics;
-
- private List<MeterStats> meterStatistics;
-
- private List<GroupDescStats> groupDescStats;
-
- private List<MeterConfigStats> meterConfigStats;
-
- private GroupFeatures groupFeatures;
-
- private MeterFeatures meterFeatures;
-
- private final Map<Short,Map<Flow,GenericStatistics>> flowAndStatsMap=
- new HashMap<Short,Map<Flow,GenericStatistics>>();
-
- private final Map<Short,AggregateFlowStatistics> tableAndAggregateFlowStatsMap =
- new HashMap<Short,AggregateFlowStatistics>();
-
- private final Map<NodeConnectorId,NodeConnectorStatistics> nodeConnectorStats =
- new ConcurrentHashMap<NodeConnectorId,NodeConnectorStatistics>();
-
- private final Map<Short,GenericTableStatistics> flowTableAndStatisticsMap =
- new HashMap<Short,GenericTableStatistics>();
-
- private final Map<NodeConnectorId,Map<QueueId,GenericQueueStatistics>> NodeConnectorAndQueuesStatsMap =
- new HashMap<NodeConnectorId,Map<QueueId,GenericQueueStatistics>>();
-
- public NodeStatistics(){
-
- }
-
- public NodeRef getTargetNode() {
- return targetNode;
- }
-
- public void setTargetNode(NodeRef targetNode) {
- this.targetNode = targetNode;
- }
-
- public List<GroupStats> getGroupStatistics() {
- return groupStatistics;
- }
-
- public void setGroupStatistics(List<GroupStats> groupStatistics) {
- this.groupStatistics = groupStatistics;
- }
-
- public List<MeterStats> getMeterStatistics() {
- return meterStatistics;
- }
-
- public void setMeterStatistics(List<MeterStats> meterStatistics) {
- this.meterStatistics = meterStatistics;
- }
-
- public List<GroupDescStats> getGroupDescStats() {
- return groupDescStats;
- }
-
- public void setGroupDescStats(List<GroupDescStats> groupDescStats) {
- this.groupDescStats = groupDescStats;
- }
-
- public List<MeterConfigStats> getMeterConfigStats() {
- return meterConfigStats;
- }
-
- public void setMeterConfigStats(List<MeterConfigStats> meterConfigStats) {
- this.meterConfigStats = meterConfigStats;
- }
-
- public GroupFeatures getGroupFeatures() {
- return groupFeatures;
- }
-
- public void setGroupFeatures(GroupFeatures groupFeatures) {
- this.groupFeatures = groupFeatures;
- }
-
- public MeterFeatures getMeterFeatures() {
- return meterFeatures;
- }
-
- public void setMeterFeatures(MeterFeatures meterFeatures) {
- this.meterFeatures = meterFeatures;
- }
-
- public Map<Short,Map<Flow,GenericStatistics>> getFlowAndStatsMap() {
- return flowAndStatsMap;
- }
-
- public Map<Short, GenericTableStatistics> getFlowTableAndStatisticsMap() {
- return flowTableAndStatisticsMap;
- }
-
- public Map<Short, AggregateFlowStatistics> getTableAndAggregateFlowStatsMap() {
- return tableAndAggregateFlowStatsMap;
- }
- public Map<NodeConnectorId, NodeConnectorStatistics> getNodeConnectorStats() {
- return nodeConnectorStats;
- }
-
- public Map<NodeConnectorId, Map<QueueId, GenericQueueStatistics>> getNodeConnectorAndQueuesStatsMap() {
- return NodeConnectorAndQueuesStatsMap;
- }
-}
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.desc.stats.reply.GroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+
+/**
+ * Main responsibility of this class to clean up all the stale statistics data
+ * associated to Flow,Meter,Group,Queue.
+ * @author avishnoi@in.ibm.com
+ *
+ */
+public class NodeStatisticsAger {
+
+ private final int NUMBER_OF_WAIT_CYCLES =2;
+
+ private final StatisticsProvider statisticsProvider;
+
+ private final NodeKey targetNodeKey;
+
+ private final Map<GroupDescStats,Date> groupDescStatsUpdate
+ = new ConcurrentHashMap<GroupDescStats,Date>();
+
+ private final Map<MeterConfigStats,Date> meterConfigStatsUpdate
+ = new ConcurrentHashMap<MeterConfigStats,Date>();
+
+ private final Map<FlowEntry,Date> flowStatsUpdate
+ = new ConcurrentHashMap<FlowEntry,Date>();
+
+ private final Map<QueueEntry,Date> queuesStatsUpdate
+ = new ConcurrentHashMap<QueueEntry,Date>();
+
+ public NodeStatisticsAger(StatisticsProvider statisticsProvider, NodeKey nodeKey){
+ this.targetNodeKey = nodeKey;
+ this.statisticsProvider = statisticsProvider;
+ }
+
+ public class FlowEntry{
+ private final Short tableId;
+ private final Flow flow;
+
+ public FlowEntry(Short tableId, Flow flow){
+ this.tableId = tableId;
+ this.flow = flow;
+ }
+
+ public Short getTableId() {
+ return tableId;
+ }
+
+ public Flow getFlow() {
+ return flow;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + ((flow == null) ? 0 : flow.hashCode());
+ result = prime * result + ((tableId == null) ? 0 : tableId.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ FlowEntry other = (FlowEntry) obj;
+ if (!getOuterType().equals(other.getOuterType()))
+ return false;
+ if (flow == null) {
+ if (other.flow != null)
+ return false;
+ } else if (!flow.equals(other.flow))
+ return false;
+ if (tableId == null) {
+ if (other.tableId != null)
+ return false;
+ } else if (!tableId.equals(other.tableId))
+ return false;
+ return true;
+ }
+
+ private NodeStatisticsAger getOuterType() {
+ return NodeStatisticsAger.this;
+ }
+
+ }
+
+ public class QueueEntry{
+ private final NodeConnectorId nodeConnectorId;
+ private final QueueId queueId;
+ public QueueEntry(NodeConnectorId ncId, QueueId queueId){
+ this.nodeConnectorId = ncId;
+ this.queueId = queueId;
+ }
+ public NodeConnectorId getNodeConnectorId() {
+ return nodeConnectorId;
+ }
+ public QueueId getQueueId() {
+ return queueId;
+ }
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + ((nodeConnectorId == null) ? 0 : nodeConnectorId.hashCode());
+ result = prime * result + ((queueId == null) ? 0 : queueId.hashCode());
+ return result;
+ }
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof QueueEntry)) {
+ return false;
+ }
+ QueueEntry other = (QueueEntry) obj;
+ if (!getOuterType().equals(other.getOuterType())) {
+ return false;
+ }
+ if (nodeConnectorId == null) {
+ if (other.nodeConnectorId != null) {
+ return false;
+ }
+ } else if (!nodeConnectorId.equals(other.nodeConnectorId)) {
+ return false;
+ }
+ if (queueId == null) {
+ if (other.queueId != null) {
+ return false;
+ }
+ } else if (!queueId.equals(other.queueId)) {
+ return false;
+ }
+ return true;
+ }
+ private NodeStatisticsAger getOuterType() {
+ return NodeStatisticsAger.this;
+ }
+ }
+
+ public NodeKey getTargetNodeKey() {
+ return targetNodeKey;
+ }
+
+ public Map<GroupDescStats, Date> getGroupDescStatsUpdate() {
+ return groupDescStatsUpdate;
+ }
+
+ public Map<MeterConfigStats, Date> getMeterConfigStatsUpdate() {
+ return meterConfigStatsUpdate;
+ }
+
+ public Map<FlowEntry, Date> getFlowStatsUpdate() {
+ return flowStatsUpdate;
+ }
+
+ public Map<QueueEntry, Date> getQueuesStatsUpdate() {
+ return queuesStatsUpdate;
+ }
+
+ public void updateGroupDescStats(List<GroupDescStats> list){
+ Date expiryTime = getExpiryTime();
+ for(GroupDescStats groupDescStats : list)
+ this.groupDescStatsUpdate.put(groupDescStats, expiryTime);
+ }
+
+ public void updateMeterConfigStats(List<MeterConfigStats> list){
+ Date expiryTime = getExpiryTime();
+ for(MeterConfigStats meterConfigStats: list)
+ this.meterConfigStatsUpdate.put(meterConfigStats, expiryTime);
+ }
+
+ public void updateFlowStats(FlowEntry flowEntry){
+ this.flowStatsUpdate.put(flowEntry, getExpiryTime());
+ }
+ public void updateQueueStats(QueueEntry queueEntry){
+ this.queuesStatsUpdate.put(queueEntry, getExpiryTime());
+ }
+
+ private Date getExpiryTime(){
+ Date expires = new Date();
+ expires.setTime(expires.getTime()+StatisticsProvider.STATS_THREAD_EXECUTION_TIME*NUMBER_OF_WAIT_CYCLES);
+ return expires;
+ }
+
+ public void cleanStaleStatistics(){
+ //Clean stale statistics related to group
+ for (Iterator<GroupDescStats> it = this.groupDescStatsUpdate.keySet().iterator();it.hasNext();){
+ GroupDescStats groupDescStats = it.next();
+ Date now = new Date();
+ Date expiryTime = this.groupDescStatsUpdate.get(groupDescStats);
+ if(now.after(expiryTime)){
+ cleanGroupStatsFromDataStore(groupDescStats );
+ it.remove();
+ }
+ }
+
+ //Clean stale statistics related to meter
+ for (Iterator<MeterConfigStats> it = this.meterConfigStatsUpdate.keySet().iterator();it.hasNext();){
+ MeterConfigStats meterConfigStats = it.next();
+ Date now = new Date();
+ Date expiryTime = this.meterConfigStatsUpdate.get(meterConfigStats);
+ if(now.after(expiryTime)){
+ cleanMeterStatsFromDataStore(meterConfigStats);
+ it.remove();
+ }
+ }
+
+ //Clean stale statistics related to flow
+ for (Iterator<FlowEntry> it = this.flowStatsUpdate.keySet().iterator();it.hasNext();){
+ FlowEntry flowEntry = it.next();
+ Date now = new Date();
+ Date expiryTime = this.flowStatsUpdate.get(flowEntry);
+ if(now.after(expiryTime)){
+ cleanFlowStatsFromDataStore(flowEntry);
+ it.remove();
+ }
+ }
+
+ //Clean stale statistics related to queue
+ for (Iterator<QueueEntry> it = this.queuesStatsUpdate.keySet().iterator();it.hasNext();){
+ QueueEntry queueEntry = it.next();
+ Date now = new Date();
+ Date expiryTime = this.queuesStatsUpdate.get(queueEntry);
+ if(now.after(expiryTime)){
+ cleanQueueStatsFromDataStore(queueEntry);
+ it.remove();
+ }
+ }
+
+ }
+
+ private void cleanQueueStatsFromDataStore(QueueEntry queueEntry) {
+ InstanceIdentifier<?> queueRef
+ = InstanceIdentifier.builder(Nodes.class)
+ .child(Node.class, this.targetNodeKey)
+ .child(NodeConnector.class, new NodeConnectorKey(queueEntry.getNodeConnectorId()))
+ .augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class, new QueueKey(queueEntry.getQueueId()))
+ .augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance();
+ cleanStaleStatisticsFromDataStore(queueRef);
+ }
+
+ private void cleanFlowStatsFromDataStore(FlowEntry flowEntry) {
+ InstanceIdentifier<?> flowRef
+ = InstanceIdentifier.builder(Nodes.class).child(Node.class, this.targetNodeKey)
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(flowEntry.getTableId()))
+ .child(Flow.class,flowEntry.getFlow().getKey())
+ .augmentation(FlowStatisticsData.class).toInstance();
+
+ cleanStaleStatisticsFromDataStore(flowRef);
+
+ }
+
+ private void cleanMeterStatsFromDataStore(MeterConfigStats meterConfigStats) {
+ InstanceIdentifierBuilder<Meter> meterRef
+ = InstanceIdentifier.builder(Nodes.class).child(Node.class,this.targetNodeKey)
+ .augmentation(FlowCapableNode.class)
+ .child(Meter.class,new MeterKey(meterConfigStats.getMeterId()));
+
+ InstanceIdentifier<?> nodeMeterConfigStatsAugmentation = meterRef.augmentation(NodeMeterConfigStats.class).toInstance();
+
+ cleanStaleStatisticsFromDataStore(nodeMeterConfigStatsAugmentation);
+
+ InstanceIdentifier<?> nodeMeterStatisticsAugmentation = meterRef.augmentation(NodeMeterStatistics.class).toInstance();
+
+ cleanStaleStatisticsFromDataStore(nodeMeterStatisticsAugmentation);
+
+ }
+
+ private void cleanGroupStatsFromDataStore(GroupDescStats groupDescStats) {
+ InstanceIdentifierBuilder<Group> groupRef
+ = InstanceIdentifier.builder(Nodes.class).child(Node.class,this.targetNodeKey)
+ .augmentation(FlowCapableNode.class)
+ .child(Group.class,new GroupKey(groupDescStats.getGroupId()));
+
+ InstanceIdentifier<?> nodeGroupDescStatsAugmentation = groupRef.augmentation(NodeGroupDescStats.class).toInstance();
+
+ cleanStaleStatisticsFromDataStore(nodeGroupDescStatsAugmentation);
+
+ InstanceIdentifier<?> nodeGroupStatisticsAugmentation = groupRef.augmentation(NodeGroupStatistics.class).toInstance();
+
+ cleanStaleStatisticsFromDataStore(nodeGroupStatisticsAugmentation);
+ }
+
+ private void cleanStaleStatisticsFromDataStore(InstanceIdentifier<? extends DataObject> ii){
+ if(ii != null){
+ DataModificationTransaction it = this.statisticsProvider.startChange();
+ it.removeOperationalData(ii);
+ it.commit();
+ }
+ }
+}
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.osgi.framework.BundleContext;
pSession = session;
DataProviderService dps = session.<DataProviderService>getSALService(DataProviderService.class);
StatisticsManagerActivator.statsProvider.setDataService(dps);
+ DataBrokerService dbs = session.<DataBrokerService>getSALService(DataBrokerService.class);
+ StatisticsManagerActivator.statsProvider.setDataBrokerService(dbs);
NotificationProviderService nps = session.<NotificationProviderService>getSALService(NotificationProviderService.class);
StatisticsManagerActivator.statsProvider.setNotificationService(nps);
StatisticsManagerActivator.statsProvider.start();
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.opendaylight.controller.md.statistics.manager.MultipartMessageManager.StatsRequestType;
import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.sal.binding.api.data.DataBrokerService;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAggregateFlowStatisticsFromFlowTableForAllFlowsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetAllFlowsStatisticsFromAllFlowTablesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsFromFlowTableOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.GetFlowTablesStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetAllGroupStatisticsOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GetGroupDescriptionOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.OpendaylightGroupStatisticsService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.GetAllMeterConfigStatisticsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetAllQueuesStatisticsFromAllPortsOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.GetQueueStatisticsFromGivenPortOutput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.OpendaylightQueueStatisticsService;
import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.NotificationListener;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * Following are main responsibilities of the class:
+ * 1) Invoke statistics request thread to send periodic statistics request to all the
+ * flow capable switch connected to the controller. It sends statistics request for
+ * Group,Meter,Table,Flow,Queue,Aggregate stats.
+ *
+ * 2) Invoke statistics ager thread, to clean up all the stale statistics data from
+ * operational data store.
+ *
+ * @author avishnoi@in.ibm.com
+ *
+ */
public class StatisticsProvider implements AutoCloseable {
public final static Logger spLogger = LoggerFactory.getLogger(StatisticsProvider.class);
private DataProviderService dps;
+
+ private DataBrokerService dbs;
private NotificationProviderService nps;
private final MultipartMessageManager multipartMessageManager = new MultipartMessageManager();
+ private StatisticsUpdateHandler statsUpdateHandler;
+
private Thread statisticsRequesterThread;
+ private Thread statisticsAgerThread;
+
private final InstanceIdentifier<Nodes> nodesIdentifier = InstanceIdentifier.builder(Nodes.class).toInstance();
- private final int STATS_THREAD_EXECUTION_TIME= 50000;
+ public static final int STATS_THREAD_EXECUTION_TIME= 30000;
//Local caching of stats
- private final ConcurrentMap<NodeId,NodeStatistics> statisticsCache =
- new ConcurrentHashMap<NodeId,NodeStatistics>();
+ private final ConcurrentMap<NodeId,NodeStatisticsAger> statisticsCache =
+ new ConcurrentHashMap<NodeId,NodeStatisticsAger>();
public DataProviderService getDataService() {
return this.dps;
this.dps = dataService;
}
+ public DataBrokerService getDataBrokerService() {
+ return this.dbs;
+ }
+
+ public void setDataBrokerService(final DataBrokerService dataBrokerService) {
+ this.dbs = dataBrokerService;
+ }
+
public NotificationProviderService getNotificationService() {
return this.nps;
}
Registration<NotificationListener> registerNotificationListener = nps.registerNotificationListener(this.updateCommiter);
this.listenerRegistration = registerNotificationListener;
+ statsUpdateHandler = new StatisticsUpdateHandler(StatisticsProvider.this);
+
+ registerDataStoreUpdateListener(this.getDataBrokerService());
+
// Get Group/Meter statistics service instance
groupStatsService = StatisticsManagerActivator.getProviderContext().
getRpcService(OpendaylightGroupStatisticsService.class);
statisticsRequesterThread.start();
+ statisticsAgerThread = new Thread( new Runnable(){
+
+ @Override
+ public void run() {
+ while(true){
+ try {
+ for(NodeStatisticsAger nodeStatisticsAger : statisticsCache.values()){
+ nodeStatisticsAger.cleanStaleStatistics();
+ }
+
+ Thread.sleep(STATS_THREAD_EXECUTION_TIME);
+ }catch (Exception e){
+ spLogger.error("Exception occurred while sending stats request : {}",e);
+ }
+ }
+ }
+ });
+
+ spLogger.debug("Statistics ager thread started with timer interval : {}",STATS_THREAD_EXECUTION_TIME);
+
+ statisticsAgerThread.start();
+
spLogger.info("Statistics Provider started.");
}
+ private void registerDataStoreUpdateListener(DataBrokerService dbs) {
+ //Register for flow updates
+ InstanceIdentifier<? extends DataObject> pathFlow = InstanceIdentifier.builder(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class)
+ .child(Flow.class).toInstance();
+ dbs.registerDataChangeListener(pathFlow, statsUpdateHandler);
+
+ //Register for meter updates
+ InstanceIdentifier<? extends DataObject> pathMeter = InstanceIdentifier.builder(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class)
+ .child(Meter.class).toInstance();
+
+ dbs.registerDataChangeListener(pathMeter, statsUpdateHandler);
+
+ //Register for group updates
+ InstanceIdentifier<? extends DataObject> pathGroup = InstanceIdentifier.builder(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class)
+ .child(Group.class).toInstance();
+ dbs.registerDataChangeListener(pathGroup, statsUpdateHandler);
+
+ //Register for queue updates
+ InstanceIdentifier<? extends DataObject> pathQueue = InstanceIdentifier.builder(Nodes.class).child(Node.class)
+ .child(NodeConnector.class)
+ .augmentation(FlowCapableNodeConnector.class)
+ .child(Queue.class).toInstance();
+ dbs.registerDataChangeListener(pathQueue, statsUpdateHandler);
+ }
+
protected DataModificationTransaction startChange() {
DataProviderService dps = this.getDataService();
}
}
- private void sendAllFlowTablesStatisticsRequest(NodeRef targetNodeRef) throws InterruptedException, ExecutionException {
+ public void sendAllFlowTablesStatisticsRequest(NodeRef targetNodeRef) throws InterruptedException, ExecutionException {
final GetFlowTablesStatisticsInputBuilder input =
new GetFlowTablesStatisticsInputBuilder();
}
- private void sendAllFlowsStatsFromAllTablesRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendAllFlowsStatsFromAllTablesRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetAllFlowsStatisticsFromAllFlowTablesInputBuilder input =
new GetAllFlowsStatisticsFromAllFlowTablesInputBuilder();
}
- private void sendAggregateFlowsStatsFromAllTablesRequest(NodeKey targetNodeKey) throws InterruptedException, ExecutionException{
+ public void sendFlowStatsFromTableRequest(NodeRef targetNode,Flow flow) throws InterruptedException, ExecutionException{
+ final GetFlowStatisticsFromFlowTableInputBuilder input =
+ new GetFlowStatisticsFromFlowTableInputBuilder();
+
+ input.setNode(targetNode);
+ input.fieldsFrom(flow);
+
+ Future<RpcResult<GetFlowStatisticsFromFlowTableOutput>> response =
+ flowStatsService.getFlowStatisticsFromFlowTable(input.build());
+
+ this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
+ , StatsRequestType.ALL_FLOW);
+
+ }
+
+ public void sendAggregateFlowsStatsFromAllTablesRequest(NodeKey targetNodeKey) throws InterruptedException, ExecutionException{
List<Short> tablesId = getTablesFromNode(targetNodeKey);
}
}
- private void sendAllNodeConnectorsStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendAllNodeConnectorsStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetAllNodeConnectorsStatisticsInputBuilder input = new GetAllNodeConnectorsStatisticsInputBuilder();
}
- private void sendAllGroupStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendAllGroupStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetAllGroupStatisticsInputBuilder input = new GetAllGroupStatisticsInputBuilder();
}
- private void sendGroupDescriptionRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendGroupDescriptionRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
final GetGroupDescriptionInputBuilder input = new GetGroupDescriptionInputBuilder();
input.setNode(targetNode);
}
- private void sendAllMeterStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendAllMeterStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
GetAllMeterStatisticsInputBuilder input = new GetAllMeterStatisticsInputBuilder();
}
- private void sendMeterConfigStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
+ public void sendMeterConfigStatisticsRequest(NodeRef targetNode) throws InterruptedException, ExecutionException{
GetAllMeterConfigStatisticsInputBuilder input = new GetAllMeterConfigStatisticsInputBuilder();
}
- private void sendAllQueueStatsFromAllNodeConnector(NodeRef targetNode) throws InterruptedException, ExecutionException {
+ public void sendAllQueueStatsFromAllNodeConnector(NodeRef targetNode) throws InterruptedException, ExecutionException {
GetAllQueuesStatisticsFromAllPortsInputBuilder input = new GetAllQueuesStatisticsFromAllPortsInputBuilder();
input.setNode(targetNode);
}
- public ConcurrentMap<NodeId, NodeStatistics> getStatisticsCache() {
+ public void sendQueueStatsFromGivenNodeConnector(NodeRef targetNode,NodeConnectorId nodeConnectorId, QueueId queueId) throws InterruptedException, ExecutionException {
+ GetQueueStatisticsFromGivenPortInputBuilder input = new GetQueueStatisticsFromGivenPortInputBuilder();
+
+ input.setNode(targetNode);
+ input.setNodeConnectorId(nodeConnectorId);
+ input.setQueueId(queueId);
+ Future<RpcResult<GetQueueStatisticsFromGivenPortOutput>> response =
+ queueStatsService.getQueueStatisticsFromGivenPort(input.build());
+
+ this.multipartMessageManager.addTxIdToRequestTypeEntry(response.get().getResult().getTransactionId()
+ , StatsRequestType.ALL_QUEUE_STATS);;
+
+ }
+
+ public ConcurrentMap<NodeId, NodeStatisticsAger> getStatisticsCache() {
return statisticsCache;
}
this.listenerRegistration.close();
this.statisticsRequesterThread.destroy();
+
+ this.statisticsAgerThread.destroy();
}
} catch (Throwable e) {
*/
package org.opendaylight.controller.md.statistics.manager;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.md.statistics.manager.NodeStatisticsAger.FlowEntry;
+import org.opendaylight.controller.md.statistics.manager.NodeStatisticsAger.QueueEntry;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.QueueKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.queue.rev130925.QueueId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupDescStatsUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.GroupFeaturesUpdated;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.nodes.node.meter.MeterStatisticsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.config.stats.reply.MeterConfigStats;
import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.meter.statistics.reply.MeterStats;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericQueueStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.statistics.types.rev130925.GenericStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.FlowCapableNodeConnectorStatisticsDataBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.ConcurrentMap;
-
/**
* Class implement statistics manager related listener interface and augment all the
* received statistics data to data stores.
private final StatisticsProvider statisticsManager;
- private final int unaccountedFlowsCounter = 1;
+ private int unaccountedFlowsCounter = 1;
public StatisticsUpdateCommiter(final StatisticsProvider manager){
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
+ NodeKey key = new NodeKey(notification.getId());
+
//Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+ ConcurrentMap<NodeId, NodeStatisticsAger> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
+ cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key));
}
- cache.get(notification.getId()).setMeterConfigStats(notification.getMeterConfigStats());
+ cache.get(notification.getId()).updateMeterConfigStats(notification.getMeterConfigStats());
//Publish data to configuration data store
- NodeKey key = new NodeKey(notification.getId());
+ List<MeterConfigStats> meterConfigStatsList = notification.getMeterConfigStats();
- List<MeterConfigStats> eterConfigStatsList = notification.getMeterConfigStats();
-
- for(MeterConfigStats meterConfigStats : eterConfigStatsList){
+ for(MeterConfigStats meterConfigStats : meterConfigStatsList){
DataModificationTransaction it = this.statisticsManager.startChange();
MeterBuilder meterBuilder = new MeterBuilder();
MeterKey meterKey = new MeterKey(meterConfigStats.getMeterId());
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
- //Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
- cache.get(notification.getId()).setMeterStatistics(notification.getMeterStats());
-
NodeKey key = new NodeKey(notification.getId());
List<MeterStats> meterStatsList = notification.getMeterStats();
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
+ NodeKey key = new NodeKey(notification.getId());
+
//Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+ ConcurrentMap<NodeId, NodeStatisticsAger> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
+ cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key));
}
- cache.get(notification.getId()).setGroupDescStats(notification.getGroupDescStats());
+ cache.get(notification.getId()).updateGroupDescStats(notification.getGroupDescStats());
//Publish data to configuration data store
- NodeKey key = new NodeKey(notification.getId());
List<GroupDescStats> groupDescStatsList = notification.getGroupDescStats();
for(GroupDescStats groupDescStats : groupDescStatsList){
if(this.statisticsManager.getMultipartMessageManager().removeTxId(notification.getTransactionId()) == null)
return;
- //Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
- cache.get(notification.getId()).setGroupStatistics(notification.getGroupStats());
-
//Publish data to configuration data store
NodeKey key = new NodeKey(notification.getId());
List<GroupStats> groupStatsList = notification.getGroupStats();
@Override
public void onMeterFeaturesUpdated(MeterFeaturesUpdated notification) {
- //Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
MeterFeaturesBuilder meterFeature = new MeterFeaturesBuilder();
meterFeature.setMeterBandSupported(notification.getMeterBandSupported());
meterFeature.setMeterCapabilitiesSupported(notification.getMeterCapabilitiesSupported());
meterFeature.setMaxColor(notification.getMaxColor());
meterFeature.setMaxMeter(notification.getMaxMeter());
- cache.get(notification.getId()).setMeterFeatures(meterFeature.build());
-
//Publish data to configuration data store
DataModificationTransaction it = this.statisticsManager.startChange();
NodeKey key = new NodeKey(notification.getId());
@Override
public void onGroupFeaturesUpdated(GroupFeaturesUpdated notification) {
- //Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
-
GroupFeaturesBuilder groupFeatures = new GroupFeaturesBuilder();
groupFeatures.setActions(notification.getActions());
groupFeatures.setGroupCapabilitiesSupported(notification.getGroupCapabilitiesSupported());
groupFeatures.setGroupTypesSupported(notification.getGroupTypesSupported());
groupFeatures.setMaxGroups(notification.getMaxGroups());
- cache.get(notification.getId()).setGroupFeatures(groupFeatures.build());
//Publish data to configuration data store
DataModificationTransaction it = this.statisticsManager.startChange();
GenericStatistics flowStats = stats.build();
//Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+ ConcurrentMap<NodeId, NodeStatisticsAger> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
- if(!cache.get(notification.getId()).getFlowAndStatsMap().containsKey(tableId)){
- cache.get(notification.getId()).getFlowAndStatsMap().put(tableId, new HashMap<Flow,GenericStatistics>());
+ cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key));
}
- cache.get(notification.getId()).getFlowAndStatsMap().get(tableId).put(flowRule,flowStats);
+ NodeStatisticsAger nsa = cache.get(notification.getId());
+ FlowEntry flowStatsEntry = nsa.new FlowEntry(tableId,flowRule);
+ cache.get(notification.getId()).updateFlowStats(flowStatsEntry);
//Augment the data to the flow node
}
}
+ table= (Table)it.readOperationalData(tableRef);
+ if(!foundOriginalFlow && table != null){
+
+ for(Flow existingFlow : table.getFlow()){
+ FlowStatisticsData augmentedflowStatisticsData = existingFlow.getAugmentation(FlowStatisticsData.class);
+ if(augmentedflowStatisticsData != null){
+ FlowBuilder existingOperationalFlow = new FlowBuilder();
+ existingOperationalFlow.fieldsFrom(augmentedflowStatisticsData.getFlowStatistics());
+ sucLogger.debug("Existing unaccounted flow in operational data store : {}",existingFlow.toString());
+ if(flowEquals(flowRule,existingOperationalFlow.build())){
+ InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
+ .augmentation(FlowCapableNode.class)
+ .child(Table.class, new TableKey(tableId))
+ .child(Flow.class,existingFlow.getKey()).toInstance();
+ flowBuilder.setKey(existingFlow.getKey());
+ flowBuilder.addAugmentation(FlowStatisticsData.class, flowStatisticsData.build());
+ sucLogger.debug("Found matching flow in the operational datastore, augmenting statistics");
+ foundOriginalFlow = true;
+ it.putOperationalData(flowRef, flowBuilder.build());
+ it.commit();
+ break;
+ }
+ }
+ }
+ }
if(!foundOriginalFlow){
sucLogger.debug("Associated original flow is not found in data store. Augmenting flow in operational data store");
- //TODO: Temporary fix: format [ 1+tableid+1+unaccounted flow counter]
- long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"1"+Integer.toString(this.unaccountedFlowsCounter)));
+ long flowKey = Long.parseLong(new String("1"+Short.toString(tableId)+"0"+Integer.toString(this.unaccountedFlowsCounter)));
+ this.unaccountedFlowsCounter++;
FlowKey newFlowKey = new FlowKey(new FlowId(Long.toString(flowKey)));
InstanceIdentifier<Flow> flowRef = InstanceIdentifier.builder(Nodes.class).child(Node.class, key)
.augmentation(FlowCapableNode.class)
aggregateFlowStatisticsBuilder.setPacketCount(notification.getPacketCount());
aggregateFlowStatisticsDataBuilder.setAggregateFlowStatistics(aggregateFlowStatisticsBuilder.build());
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
- cache.get(notification.getId()).getTableAndAggregateFlowStatsMap().put(tableId,aggregateFlowStatisticsBuilder.build());
-
sucLogger.debug("Augment aggregate statistics: {} for table {} on Node {}",aggregateFlowStatisticsBuilder.build().toString(),tableId,key);
TableBuilder tableBuilder = new TableBuilder();
NodeKey key = new NodeKey(notification.getId());
sucLogger.debug("Received port stats update : {}",notification.toString());
- //Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
-
-
List<NodeConnectorStatisticsAndPortNumberMap> portsStats = notification.getNodeConnectorStatisticsAndPortNumberMap();
for(NodeConnectorStatisticsAndPortNumberMap portStats : portsStats){
statisticsBuilder.setTransmitDrops(portStats.getTransmitDrops());
statisticsBuilder.setTransmitErrors(portStats.getTransmitErrors());
- //Update data in the cache
- cache.get(notification.getId()).getNodeConnectorStats().put(portStats.getNodeConnectorId(), statisticsBuilder.build());
-
//Augment data to the node-connector
FlowCapableNodeConnectorStatisticsDataBuilder statisticsDataBuilder =
new FlowCapableNodeConnectorStatisticsDataBuilder();
statisticsDataBuilder.setFlowTableStatistics(statisticsBuilder.build());
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
- if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
- }
- cache.get(notification.getId()).getFlowTableAndStatisticsMap().put(ftStats.getTableId().getValue(),statisticsBuilder.build());
-
sucLogger.debug("Augment flow table statistics: {} for table {} on Node {}",statisticsBuilder.build().toString(),ftStats.getTableId(),key);
TableBuilder tableBuilder = new TableBuilder();
sucLogger.debug("Received queue stats update : {}",notification.toString());
//Add statistics to local cache
- ConcurrentMap<NodeId, NodeStatistics> cache = this.statisticsManager.getStatisticsCache();
+ ConcurrentMap<NodeId, NodeStatisticsAger> cache = this.statisticsManager.getStatisticsCache();
if(!cache.containsKey(notification.getId())){
- cache.put(notification.getId(), new NodeStatistics());
+ cache.put(notification.getId(), new NodeStatisticsAger(statisticsManager,key));
}
+ NodeStatisticsAger nsa = cache.get(notification.getId());
+
List<QueueIdAndStatisticsMap> queuesStats = notification.getQueueIdAndStatisticsMap();
for(QueueIdAndStatisticsMap swQueueStats : queuesStats){
- if(!cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().containsKey(swQueueStats.getNodeConnectorId())){
- cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap().put(swQueueStats.getNodeConnectorId(), new HashMap<QueueId,GenericQueueStatistics>());
- }
+ QueueEntry queueEntry = nsa.new QueueEntry(swQueueStats.getNodeConnectorId(),swQueueStats.getQueueId());
+ nsa.updateQueueStats(queueEntry);
FlowCapableNodeConnectorQueueStatisticsDataBuilder queueStatisticsDataBuilder = new FlowCapableNodeConnectorQueueStatisticsDataBuilder();
queueStatisticsDataBuilder.setFlowCapableNodeConnectorQueueStatistics(queueStatisticsBuilder.build());
- cache.get(notification.getId()).getNodeConnectorAndQueuesStatsMap()
- .get(swQueueStats.getNodeConnectorId())
- .put(swQueueStats.getQueueId(), queueStatisticsBuilder.build());
-
-
DataModificationTransaction it = this.statisticsManager.startChange();
InstanceIdentifier<Queue> queueRef
* @param storedFlow
* @return
*/
+
public boolean matchEquals(Match statsFlow, Match storedFlow) {
if (statsFlow == storedFlow) {
return true;
}
if (storedFlow.getEthernetMatch() == null) {
if (statsFlow.getEthernetMatch() != null) {
- if(!statsFlow.getEthernetMatch().getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00") ||
- !statsFlow.getEthernetMatch().getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
- return false;
- }
+ return false;
}
- } else if(!EthernetMatchEquals(statsFlow.getEthernetMatch(),storedFlow.getEthernetMatch())) {
+ } else if(!storedFlow.getEthernetMatch().equals(statsFlow.getEthernetMatch())) {
return false;
}
if (storedFlow.getIcmpv4Match()== null) {
}
if (storedFlow.getInPort()== null) {
if (statsFlow.getInPort() != null) {
- String[] portArr = statsFlow.getInPort().getValue().split(":");
- if(portArr.length >= 3){
- if(Integer.parseInt(portArr[2]) != 0){
- return false;
- }
- }
+ return false;
}
} else if(!storedFlow.getInPort().equals(statsFlow.getInPort())) {
return false;
}
if (storedFlow.getLayer3Match()== null) {
if (statsFlow.getLayer3Match() != null) {
- Ipv4Match ipv4Match = (Ipv4Match)statsFlow.getLayer3Match();
- if(!ipv4Match.getIpv4Source().getValue().equals("0.0.0.0/0") ||
- !ipv4Match.getIpv4Destination().getValue().equals("0.0.0.0/0")){
return false;
- }
}
} else if(!storedFlow.getLayer3Match().equals(statsFlow.getLayer3Match())) {
return false;
}
if (storedFlow.getLayer4Match()== null) {
if (statsFlow.getLayer4Match() != null) {
- TcpMatch tcpMatch = (TcpMatch)statsFlow.getLayer4Match();
- if(!tcpMatch.getTcpDestinationPort().getValue().equals(0) ||
- !tcpMatch.getTcpSourcePort().getValue().equals(0)){
- return false;
- }
+ return false;
}
} else if(!storedFlow.getLayer4Match().equals(statsFlow.getLayer4Match())) {
return false;
}
if (storedFlow.getVlanMatch()== null) {
if (statsFlow.getVlanMatch() != null) {
- VlanMatch vlanMatch = statsFlow.getVlanMatch();
- if(!vlanMatch.getVlanId().getVlanId().getValue().equals(0) ||
- !vlanMatch.getVlanPcp().getValue().equals((short)0)){
- return false;
- }
+ return false;
}
} else if(!storedFlow.getVlanMatch().equals(statsFlow.getVlanMatch())) {
return false;
}
return true;
}
-
- public boolean EthernetMatchEquals(EthernetMatch statsEtherMatch, EthernetMatch storedEtherMatch) {
- if (statsEtherMatch == storedEtherMatch) {
- return true;
- }
- if (storedEtherMatch.getEthernetDestination()== null) {
- if (statsEtherMatch.getEthernetDestination() != null) {
- if(!statsEtherMatch.getEthernetDestination().getAddress().getValue().equals("00:00:00:00:00:00")){
- return false;
- }
- }
- } else if(!storedEtherMatch.getEthernetDestination().equals(statsEtherMatch.getEthernetDestination())) {
- return false;
- }
- if (storedEtherMatch.getEthernetSource() == null) {
- if (statsEtherMatch.getEthernetSource() != null) {
- if(!statsEtherMatch.getEthernetSource().getAddress().getValue().equals("00:00:00:00:00:00")){
- return false;
- }
- }
- } else if(!storedEtherMatch.getEthernetSource().equals(statsEtherMatch.getEthernetSource())) {
- return false;
- }
- if (storedEtherMatch.getEthernetType() == null) {
- if (statsEtherMatch.getEthernetType() != null) {
- if(!statsEtherMatch.getEthernetType().getType().getValue().equals(0)){
- return false;
- }
- }
- } else if(!storedEtherMatch.getEthernetType().equals(statsEtherMatch.getEthernetType())) {
- return false;
- }
- return true;
- }
}
--- /dev/null
+/*
+ * Copyright IBM Corporation, 2013. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.statistics.manager;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
+import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.queues.Queue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupDescStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.statistics.rev131111.NodeGroupStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterConfigStats;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.statistics.rev131111.NodeMeterStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.queue.statistics.rev131216.FlowCapableNodeConnectorQueueStatisticsData;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Following are two main responsibilities of the class
+ * 1) Listen for the create changes in config data store for tree nodes (Flow,Group,Meter,Queue)
+ * and send statistics request to the switch to fetch the statistics
+ *
+ * 2)Listen for the remove changes in config data store for tree nodes (Flow,Group,Meter,Queue)
+ * and remove the relative statistics data from operational data store.
+ *
+ * @author avishnoi@in.ibm.com
+ *
+ */
+public class StatisticsUpdateHandler implements DataChangeListener {
+
+ public final static Logger suhLogger = LoggerFactory.getLogger(StatisticsUpdateHandler.class);
+
+ private final StatisticsProvider statisticsManager;
+
+ public StatisticsUpdateHandler(final StatisticsProvider manager){
+
+ this.statisticsManager = manager;
+ }
+
+ public StatisticsProvider getStatisticsManager(){
+ return statisticsManager;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onDataChanged(DataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+
+ Map<InstanceIdentifier<?>, DataObject> additions = change.getCreatedConfigurationData();
+ for (InstanceIdentifier<? extends DataObject> dataObjectInstance : additions.keySet()) {
+ DataObject dataObject = additions.get(dataObjectInstance);
+ InstanceIdentifier<Node> nodeII = dataObjectInstance.firstIdentifierOf(Node.class);
+ NodeRef nodeRef = new NodeRef(nodeII);
+ if(dataObject instanceof Flow){
+ Flow flow = (Flow) dataObject;
+ try {
+ this.statisticsManager.sendFlowStatsFromTableRequest(nodeRef, flow);
+ } catch (InterruptedException | ExecutionException e) {
+ suhLogger.warn("Following exception occured while sending flow statistics request newly added flow: {}", e);
+ }
+ }
+ if(dataObject instanceof Meter){
+ try {
+ this.statisticsManager.sendMeterConfigStatisticsRequest(nodeRef);
+ } catch (InterruptedException | ExecutionException e) {
+ suhLogger.warn("Following exception occured while sending meter statistics request for newly added meter: {}", e);
+ }
+ }
+ if(dataObject instanceof Group){
+ try {
+ this.statisticsManager.sendGroupDescriptionRequest(nodeRef);
+ } catch (InterruptedException | ExecutionException e) {
+ suhLogger.warn("Following exception occured while sending group description request for newly added group: {}", e);
+ }
+ }
+ if(dataObject instanceof Queue){
+ Queue queue = (Queue) dataObject;
+ InstanceIdentifier<NodeConnector> nodeConnectorII = dataObjectInstance.firstIdentifierOf(NodeConnector.class);
+ NodeConnectorKey nodeConnectorKey = InstanceIdentifier.keyOf(nodeConnectorII);
+ try {
+ this.statisticsManager.sendQueueStatsFromGivenNodeConnector(nodeRef, nodeConnectorKey.getId(), queue.getQueueId());
+ } catch (InterruptedException | ExecutionException e) {
+ suhLogger.warn("Following exception occured while sending queue statistics request for newly added group: {}", e);
+ }
+ }
+ }
+
+ Set<InstanceIdentifier<? extends DataObject>> removals = change.getRemovedConfigurationData();
+ for (InstanceIdentifier<? extends DataObject> dataObjectInstance : removals) {
+ DataObject dataObject = change.getOriginalConfigurationData().get(dataObjectInstance);
+
+ if(dataObject instanceof Flow){
+ InstanceIdentifier<Flow> flowII = (InstanceIdentifier<Flow>)dataObjectInstance;
+ InstanceIdentifier<?> flowAugmentation =
+ InstanceIdentifier.builder(flowII).augmentation(FlowStatisticsData.class).toInstance();
+ removeAugmentedOperationalData(flowAugmentation);
+ }
+ if(dataObject instanceof Meter){
+ InstanceIdentifier<Meter> meterII = (InstanceIdentifier<Meter>)dataObjectInstance;
+
+ InstanceIdentifier<?> nodeMeterConfigStatsAugmentation =
+ InstanceIdentifier.builder(meterII).augmentation(NodeMeterConfigStats.class).toInstance();
+ removeAugmentedOperationalData(nodeMeterConfigStatsAugmentation);
+
+ InstanceIdentifier<?> nodeMeterStatisticsAugmentation =
+ InstanceIdentifier.builder(meterII).augmentation(NodeMeterStatistics.class).toInstance();
+ removeAugmentedOperationalData(nodeMeterStatisticsAugmentation);
+ }
+
+ if(dataObject instanceof Group){
+ InstanceIdentifier<Group> groupII = (InstanceIdentifier<Group>)dataObjectInstance;
+
+ InstanceIdentifier<?> nodeGroupDescStatsAugmentation =
+ InstanceIdentifier.builder(groupII).augmentation(NodeGroupDescStats.class).toInstance();
+ removeAugmentedOperationalData(nodeGroupDescStatsAugmentation);
+
+ InstanceIdentifier<?> nodeGroupStatisticsAugmentation =
+ InstanceIdentifier.builder(groupII).augmentation(NodeGroupStatistics.class).toInstance();
+ removeAugmentedOperationalData(nodeGroupStatisticsAugmentation);
+ }
+
+ if(dataObject instanceof Queue){
+ InstanceIdentifier<Queue> queueII = (InstanceIdentifier<Queue>)dataObjectInstance;
+
+ InstanceIdentifier<?> nodeConnectorQueueStatisticsDataAugmentation =
+ InstanceIdentifier.builder(queueII).augmentation(FlowCapableNodeConnectorQueueStatisticsData.class).toInstance();
+ removeAugmentedOperationalData(nodeConnectorQueueStatisticsDataAugmentation);
+ }
+ }
+ }
+
+ private void removeAugmentedOperationalData(InstanceIdentifier<? extends DataObject> dataObjectInstance ){
+ if(dataObjectInstance != null){
+ DataModificationTransaction it = this.statisticsManager.startChange();
+ it.removeOperationalData(dataObjectInstance);
+ it.commit();
+ }
+ }
+}
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.8</version>
+ <version>1.7</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
- <version>2.6</version>
+ <version>2.4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.8</version>
+ <version>1.7</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
"Unable to retrieve config snapshot after commit for persister, details: " + e.getMessage(),
ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error, e.getErrorInfo());
}
- logger.info("Datastore {} committed successfully: {}", Datastore.candidate, status);
+ logger.trace("Datastore {} committed successfully: {}", Datastore.candidate, status);
return document.createElement(XmlNetconfConstants.OK);
}
throw new NetconfDocumentedException(e.getMessage(), e, ErrorType.application, ErrorTag.operation_failed,
ErrorSeverity.error, errorInfo);
}
- logger.info("Changes discarded successfully from datastore {}", Datastore.candidate);
+ logger.trace("Changes discarded successfully from datastore {}", Datastore.candidate);
return document.createElement(XmlNetconfConstants.OK);
}
}
- logger.info("Datastore {} validated successfully", Datastore.candidate);
+ logger.trace("Datastore {} validated successfully", Datastore.candidate);
return document.createElement(XmlNetconfConstants.OK);
}
executeSet(configRegistryClient, editConfigExecution);
}
- logger.info("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
+ logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
return document.createElement(XmlNetconfConstants.OK);
}
ObjectName on = null;
try {
on = ta.createModule(module, instance);
- logger.info("New instance for {} {} created under name {}", module, instance, on);
+ logger.trace("New instance for {} {} created under name {}", module, instance, on);
} catch (InstanceAlreadyExistsException e1) {
throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
}
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
- logger.info("{} operation successful", XmlNetconfConstants.GET);
+ logger.trace("{} operation successful", XmlNetconfConstants.GET);
return element;
}
ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
- logger.info("{} operation successful", GET_CONFIG);
+ logger.trace("{} operation successful", GET_CONFIG);
return dataElement;
}
final Object result = executeOperation(configRegistryClient, execution.on, execution.operationName,
execution.attributes);
- logger.info("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
+ logger.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName,
execution.on, execution.attributes, result);
if (execution.isVoid()) {
import org.opendaylight.controller.netconf.mapping.api.NetconfOperationService;
import org.opendaylight.yangtools.yang.model.api.Module;
-import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
}
private static Set<Capability> setupCapabilities(YangStoreSnapshot yangStoreSnapshot) {
- Set<Capability> capabilities = Sets.newHashSet();
-
+ Set<Capability> capabilities = new HashSet<>();
// [RFC6241] 8.3. Candidate Configuration Capability
capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
// [RFC6241] 8.5. Rollback-on-Error Capability
capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
- final Collection<Map.Entry<Module, String>> modulesAndContents = yangStoreSnapshot.getModuleMap().values();
- for (Map.Entry<Module, String> moduleAndContent : modulesAndContents) {
- capabilities.add(new YangStoreCapability(moduleAndContent));
+ Set<Module> modules = yangStoreSnapshot.getModules();
+ for (Module module : modules) {
+ capabilities.add(new YangStoreCapability(module, yangStoreSnapshot.getModuleSource(module)));
}
return capabilities;
private final String moduleName;
private final String moduleNamespace;
- public YangStoreCapability(Map.Entry<Module, String> moduleAndContent) {
- super(getAsString(moduleAndContent.getKey()));
- this.content = moduleAndContent.getValue();
- Module module = moduleAndContent.getKey();
+ public YangStoreCapability(Module module, String moduleContent) {
+ super(getAsString(module));
+ this.content = moduleContent;
this.moduleName = module.getName();
this.moduleNamespace = module.getNamespace().toString();
this.revision = Util.writeDate(module.getRevision());
* Commit and notification send must be atomic
*/
public synchronized CommitStatus commitTransaction() throws NetconfDocumentedException {
- final Optional<ObjectName> taON = getTransaction();
- Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
- CommitStatus status = configRegistryClient.commitConfig(taON.get());
- allOpenedTransactions.remove(transaction);
- transaction = null;
- return status;
+ final Optional<ObjectName> maybeTaON = getTransaction();
+ Preconditions.checkState(maybeTaON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+ ObjectName taON = maybeTaON.get();
+ try {
+ CommitStatus status = configRegistryClient.commitConfig(taON);
+ // clean up
+ allOpenedTransactions.remove(transaction);
+ transaction = null;
+ return status;
+ } catch (ValidationException validationException) {
+ // no clean up: user can reconfigure and recover this transaction
+ logger.warn("Transaction {} failed on {}", taON, validationException.toString());
+ throw validationException;
+ } catch (Exception e) {
+ logger.error("Exception while commit of {}, aborting transaction", taON, e);
+ // clean up
+ abortTransaction();
+ throw e;
+ }
}
public synchronized void abortTransaction() {
+ logger.debug("Aborting current transaction");
Optional<ObjectName> taON = getTransaction();
Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
}
public synchronized void abortTestTransaction(ObjectName testTx) {
+ logger.debug("Aborting transaction {}", testTx);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(testTx);
allOpenedTransactions.remove(testTx);
transactionClient.abortConfig();
org.xml.sax,
javax.xml.namespace,
javax.xml.xpath,
- org.opendaylight.controller.config.api
+ org.opendaylight.controller.config.api,
+ org.opendaylight.controller.netconf.util
</Import-Package>
<Export-Package>
</Export-Package>
// Socket should not be closed at this point
// Activator unregisters this as JMX listener before close is called
- logger.info("Received notification {}", notification);
+ logger.trace("Received notification {}", notification);
if (notification instanceof CommitJMXNotification) {
try {
handleAfterCommitNotification((CommitJMXNotification) notification);
try {
persisterAggregator.persistConfig(new CapabilityStrippingConfigSnapshotHolder(notification.getConfigSnapshot(),
notification.getCapabilities(), ignoredMissingCapabilityRegex));
- logger.info("Configuration persisted successfully");
+ logger.trace("Configuration persisted successfully");
} catch (IOException e) {
throw new RuntimeException("Unable to persist configuration snapshot", e);
}
package org.opendaylight.controller.netconf.persist.impl;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import io.netty.channel.EventLoopGroup;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.InetSocketAddress;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.concurrent.Immutable;
-
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
import org.opendaylight.controller.netconf.util.messages.NetconfMessageAdditionalHeader;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+import javax.annotation.concurrent.Immutable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetSocketAddress;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
@Immutable
public class ConfigPusher {
private final InetSocketAddress address;
private final EventLoopGroup nettyThreadgroup;
-
- public static final long DEFAULT_TIMEOUT = 120000L;// 120 seconds until netconf must be stable
- private final long timeout;
+ // Default timeout for netconf becoming stable
+ public static final long DEFAULT_TIMEOUT = TimeUnit.MINUTES.toNanos(2);
+ private final int delayMillis = 5000;
+ private final long timeoutNanos;
public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadgroup) {
- this(address, DEFAULT_TIMEOUT, nettyThreadgroup);
+ this(address, nettyThreadgroup, DEFAULT_TIMEOUT);
+ }
+ @Deprecated
+ public ConfigPusher(InetSocketAddress address, long timeoutMillis, EventLoopGroup nettyThreadgroup) {
+ this(address, nettyThreadgroup, TimeUnit.MILLISECONDS.toNanos(timeoutMillis));
}
- public ConfigPusher(InetSocketAddress address, long timeout, EventLoopGroup nettyThreadgroup) {
+ public ConfigPusher(InetSocketAddress address, EventLoopGroup nettyThreadgroup, long timeoutNanos) {
this.address = address;
- this.timeout = timeout;
-
this.nettyThreadgroup = nettyThreadgroup;
+ this.timeoutNanos = timeoutNanos;
}
public synchronized NetconfClient init(List<ConfigSnapshotHolder> configs) throws InterruptedException {
}
private synchronized NetconfClient pushAllConfigs(List<ConfigSnapshotHolder> configs) throws InterruptedException {
+ // first just make sure we can connect to netconf, even if nothing is being pushed
NetconfClient netconfClient = makeNetconfConnection(Collections.<String>emptySet(), Optional.<NetconfClient>absent());
+ // start pushing snapshots:
for (ConfigSnapshotHolder configSnapshotHolder: configs){
netconfClient = pushSnapshotWithRetries(configSnapshotHolder, Optional.of(netconfClient));
}
int maxAttempts = 30;
for(int i = 0 ; i < maxAttempts; i++) {
NetconfClient netconfClient = makeNetconfConnection(configSnapshotHolder.getCapabilities(), oldClientForPossibleReuse);
- final String configSnapshot = configSnapshotHolder.getConfigSnapshot();
- logger.trace("Pushing following xml to netconf {}", configSnapshot);
+ logger.trace("Pushing following xml to netconf {}", configSnapshotHolder);
try {
pushLastConfig(configSnapshotHolder, netconfClient);
return netconfClient;
/**
* @param expectedCaps capabilities that server hello must contain. Will retry until all are found or throws RuntimeException.
* If empty set is provided, will only make sure netconf client successfuly connected to the server.
- * @param oldClientForPossibleReuse if present, try to get expected capabilities from it before closing it and retrying with
- * new client connection.
+ * @param maybeOldClient if present, close it.
* @return NetconfClient that has all required capabilities from server.
*/
private synchronized NetconfClient makeNetconfConnection(Set<String> expectedCaps,
- Optional<NetconfClient> oldClientForPossibleReuse)
+ Optional<NetconfClient> maybeOldClient)
throws InterruptedException {
- if (oldClientForPossibleReuse.isPresent()) {
- NetconfClient oldClient = oldClientForPossibleReuse.get();
- if (Util.isSubset(oldClient, expectedCaps)) {
- return oldClient;
- } else {
- Util.closeClientAndDispatcher(oldClient);
- }
+ if (maybeOldClient.isPresent()) {
+ NetconfClient oldClient = maybeOldClient.get();
+ Util.closeClientAndDispatcher(oldClient);
}
// TODO think about moving capability subset check to netconf client
// could be utilized by integration tests
- long pollingStart = System.currentTimeMillis();
- int delay = 5000;
-
+ final long pollingStart = System.nanoTime();
+ final long deadline = pollingStart + timeoutNanos;
int attempt = 0;
- long deadline = pollingStart + timeout;
-
String additionalHeader = NetconfMessageAdditionalHeader.toString("unknown", address.getAddress().getHostAddress(),
Integer.toString(address.getPort()), "tcp", Optional.of("persister"));
Set<String> latestCapabilities = new HashSet<>();
- while (System.currentTimeMillis() < deadline) {
+ while (System.nanoTime() < deadline) {
attempt++;
NetconfClientDispatcher netconfClientDispatcher = new NetconfClientDispatcher(nettyThreadgroup,
nettyThreadgroup, additionalHeader);
NetconfClient netconfClient;
try {
- netconfClient = new NetconfClient(this.toString(), address, delay, netconfClientDispatcher);
+ netconfClient = new NetconfClient(this.toString(), address, delayMillis, netconfClientDispatcher);
} catch (IllegalStateException e) {
logger.debug("Netconf {} was not initialized or is not stable, attempt {}", address, attempt, e);
netconfClientDispatcher.close();
- Thread.sleep(delay);
+ Thread.sleep(delayMillis);
continue;
}
latestCapabilities = netconfClient.getCapabilities();
if (Util.isSubset(netconfClient, expectedCaps)) {
logger.debug("Hello from netconf stable with {} capabilities", latestCapabilities);
- logger.info("Session id received from netconf server: {}", netconfClient.getClientSession());
+ logger.trace("Session id received from netconf server: {}", netconfClient.getClientSession());
return netconfClient;
}
logger.debug("Polling hello from netconf, attempt {}, capabilities {}", attempt, latestCapabilities);
Util.closeClientAndDispatcher(netconfClient);
- Thread.sleep(delay);
+ Thread.sleep(delayMillis);
}
Set<String> allNotFound = new HashSet<>(expectedCaps);
allNotFound.removeAll(latestCapabilities);
throws ConflictingVersionException, IOException, SAXException {
Element xmlToBePersisted = XmlUtil.readXmlToElement(configSnapshotHolder.getConfigSnapshot());
- logger.info("Pushing last configuration to netconf: {}", configSnapshotHolder);
+ logger.trace("Pushing last configuration to netconf: {}", configSnapshotHolder);
StringBuilder response = new StringBuilder("editConfig response = {");
-
NetconfMessage message = createEditConfigMessage(xmlToBePersisted, "/netconfOp/editConfig.xml");
// sending message to netconf
NetconfMessage responseMessage = getResponse(message, netconfClient);
- XmlElement element = XmlElement.fromDomDocument(responseMessage.getDocument());
- Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
- element = element.getOnlyChildElement();
-
- Util.checkIsOk(element, responseMessage);
+ NetconfUtil.checkIsMessageOk(responseMessage);
response.append(XmlUtil.toString(responseMessage.getDocument()));
response.append("}");
responseMessage = getResponse(getNetconfMessageFromResource("/netconfOp/commit.xml"), netconfClient);
- element = XmlElement.fromDomDocument(responseMessage.getDocument());
- Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
- element = element.getOnlyChildElement();
- Util.checkIsOk(element, responseMessage);
+
+ NetconfUtil.checkIsMessageOk(responseMessage);
response.append("commit response = {");
response.append(XmlUtil.toString(responseMessage.getDocument()));
response.append("}");
- logger.info("Last configuration loaded successfully");
+ logger.trace("Last configuration loaded successfully");
logger.trace("Detailed message {}", response);
}
package org.opendaylight.controller.netconf.persist.impl;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
import org.opendaylight.controller.netconf.client.NetconfClient;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
-import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
import java.util.Set;
public final class Util {
}
}
}
-
-
- public static void checkIsOk(XmlElement element, NetconfMessage responseMessage) throws ConflictingVersionException {
- if (element.getName().equals(XmlNetconfConstants.OK)) {
- return;
- }
-
- if (element.getName().equals(XmlNetconfConstants.RPC_ERROR)) {
- logger.warn("Can not load last configuration, operation failed");
- // is it ConflictingVersionException ?
- XPathExpression xPathExpression = XMLNetconfUtil.compileXPath("/netconf:rpc-reply/netconf:rpc-error/netconf:error-info/netconf:error");
- String error = (String) XmlUtil.evaluateXPath(xPathExpression, element.getDomElement(), XPathConstants.STRING);
- if (error!=null && error.contains(ConflictingVersionException.class.getCanonicalName())) {
- throw new ConflictingVersionException(error);
- }
- throw new IllegalStateException("Can not load last configuration, operation failed: "
- + XmlUtil.toString(responseMessage.getDocument()));
- }
-
- logger.warn("Can not load last configuration. Operation failed.");
- throw new IllegalStateException("Can not load last configuration. Operation failed: "
- + XmlUtil.toString(responseMessage.getDocument()));
- }
}
import java.lang.management.ManagementFactory;
import java.net.InetSocketAddress;
import java.util.regex.Pattern;
+import java.util.concurrent.TimeUnit;
public class ConfigPersisterActivator implements BundleActivator {
private final static MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
private static final String IGNORED_MISSING_CAPABILITY_REGEX_SUFFIX = "ignoredMissingCapabilityRegex";
+ private static final String PUSH_TIMEOUT = "pushTimeout";
+
public static final String NETCONF_CONFIG_PERSISTER = "netconf.config.persister";
public static final String STORAGE_ADAPTER_CLASS_PROP_SUFFIX = "storageAdapterClass";
} else {
regex = DEFAULT_IGNORED_REGEX;
}
+
+ String timeoutProperty = propertiesProvider.getProperty(PUSH_TIMEOUT);
+ long timeout = timeoutProperty == null ? ConfigPusher.DEFAULT_TIMEOUT : TimeUnit.SECONDS.toNanos(Integer.valueOf(timeoutProperty));
+
final Pattern ignoredMissingCapabilityRegex = Pattern.compile(regex);
nettyThreadgroup = new NioEventLoopGroup();
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/monitoring
+ ${project.build.directory}/generated-sources/monitoring
</outputBaseDir>
</generator>
</codeGenerators>
</goals>
<configuration>
<sources>
- <source>target/generated-sources/sal</source>
+ <source>${project.build.directory}/generated-sources/monitoring</source>
</sources>
</configuration>
</execution>
org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl
</codeGeneratorClass>
<outputBaseDir>
- target/generated-sources/monitoring
+ ${project.build.directory}/generated-sources/monitoring
</outputBaseDir>
</generator>
</codeGenerators>
</goals>
<configuration>
<sources>
- <source>target/generated-sources/sal</source>
+ <source>${project.build.directory}/generated-sources/monitoring</source>
</sources>
</configuration>
</execution>
--- /dev/null
+/*
+ * 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.client;
+
+import io.netty.channel.nio.NioEventLoopGroup;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
+import org.opendaylight.controller.netconf.util.handler.ssh.authentication.LoginPassword;
+
+import java.net.InetSocketAddress;
+
+@Ignore
+public class SSHNetconfClientLiveTest {
+
+ NioEventLoopGroup nettyThreadgroup;
+ NetconfSshClientDispatcher netconfClientDispatcher;
+
+ @Before
+ public void setUp() {
+ nettyThreadgroup = new NioEventLoopGroup();
+ netconfClientDispatcher = new NetconfSshClientDispatcher(new LoginPassword(
+ System.getProperty("username"), System.getProperty("password")),
+ nettyThreadgroup, nettyThreadgroup);
+ }
+
+ @Test
+ public void test() throws Exception {
+ InetSocketAddress address = new InetSocketAddress(System.getProperty("host"), 830);
+ int connectionAttempts = 10, attemptMsTimeout = 1000;
+
+ NetconfClient netconfClient = new NetconfClient("client", address, connectionAttempts,
+ attemptMsTimeout, netconfClientDispatcher);
+
+ netconfClient.getCapabilities();
+
+ NetconfMessage netconfMessage = NetconfUtil.createMessage(getClass().getResourceAsStream("/get_schema.xml"));
+ NetconfMessage response = netconfClient.sendMessage(netconfMessage);
+ NetconfUtil.checkIsMessageOk(response);
+ }
+}
--- /dev/null
+<rpc message-id="2"
+ xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <get-schema xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">
+ <identifier>ietf-netconf-monitoring</identifier>
+ <format
+ xmlns:ncm="urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring">ncm:yang
+ </format>
+ </get-schema>
+</rpc>
\ No newline at end of file
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeSet;
public class CapabilityProviderImpl implements CapabilityProvider {
private final NetconfOperationServiceSnapshot netconfOperationServiceSnapshot;
public CapabilityProviderImpl(NetconfOperationServiceSnapshot netconfOperationServiceSnapshot) {
this.netconfOperationServiceSnapshot = netconfOperationServiceSnapshot;
Map<String, Capability> urisToCapabilitiesInternalMap = getCapabilitiesInternal(netconfOperationServiceSnapshot);
- capabilityURIs = Collections.unmodifiableSet(urisToCapabilitiesInternalMap.keySet());
+ List<String> capabilityURIs = new ArrayList<>(urisToCapabilitiesInternalMap.keySet());
+ Collections.sort(capabilityURIs);
+ this.capabilityURIs = Collections.unmodifiableSet(new TreeSet<>(capabilityURIs));
}
private static Map<String, Capability> getCapabilitiesInternal(
import org.opendaylight.controller.netconf.api.NetconfServerSessionPreferences;
import org.opendaylight.controller.netconf.impl.mapping.CapabilityProvider;
import org.opendaylight.controller.netconf.impl.osgi.NetconfOperationServiceFactoryListener;
-import org.opendaylight.controller.netconf.impl.util.NetconfUtil;
+import org.opendaylight.controller.netconf.util.NetconfUtil;
import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
XmlUtil.addNamespaceAttr(getSchemaResult,
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_YANG_IETF_NETCONF_MONITORING);
- logger.info("{} operation successful", GET_SCHEMA);
+ logger.trace("{} operation successful", GET_SCHEMA);
return getSchemaResult;
}
.createElement(XmlNetconfConstants.RPC_ERROR);\r
}\r
\r
- logger.info("{} operation successful", START_EXI);\r
+ logger.trace("{} operation successful", START_EXI);\r
logger.debug("received start-exi message {} ", XmlUtil.toString(document));\r
return getSchemaResult;\r
\r
Element getSchemaResult = document.createElement(XmlNetconfConstants.OK);\r
XmlUtil.addNamespaceAttr(getSchemaResult,\r
XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);\r
- logger.info("{} operation successful", STOP_EXI);\r
+ logger.trace("{} operation successful", STOP_EXI);\r
logger.debug("received stop-exi message {} ", XmlUtil.toString(document));\r
return getSchemaResult;\r
}\r
+++ /dev/null
-/*
- * 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.impl.util;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class NetconfUtil {
-
- private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
-
- public static NetconfMessage createMessage(final File f) {
- Preconditions.checkNotNull(f, "File parameter was null");
- try {
- return createMessage(new FileInputStream(f));
- } catch (final FileNotFoundException e) {
- logger.warn("File {} not found.", f, e);
- }
- return null;
- }
-
- public static NetconfMessage createMessage(final InputStream is) {
- Preconditions.checkNotNull(is, "InputStream parameter was null");
- Document doc = null;
- try {
- doc = XmlUtil.readXmlToDocument(is);
- } catch (final IOException e) {
- logger.warn("Error ocurred while parsing stream.", e);
- } catch (final SAXException e) {
- logger.warn("Error ocurred while final parsing stream.", e);
- }
- return (doc == null) ? null : new NetconfMessage(doc);
- }
-}
final YangStoreSnapshot yStore = mock(YangStoreSnapshot.class);
doReturn(yStore).when(this.yangStoreService).getYangStoreSnapshot();
doReturn(Collections.emptyMap()).when(yStore).getModuleMXBeanEntryMap();
- doReturn(Collections.emptyMap()).when(yStore).getModuleMap();
final ConfigTransactionJMXClient mockedTCl = mock(ConfigTransactionJMXClient.class);
doReturn(mockedTCl).when(this.jmxClient).getConfigTransactionClient(any(ObjectName.class));
import com.google.common.base.Optional;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.net.InetSocketAddress;
import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
ServiceTrackerCustomizer<IUserManager, IUserManager> customizer = new ServiceTrackerCustomizer<IUserManager, IUserManager>(){
@Override
public IUserManager addingService(ServiceReference<IUserManager> reference) {
- logger.info("Service {} added, let there be SSH bridge.", reference);
+ logger.trace("Service {} added, let there be SSH bridge.", reference);
iUserManager = context.getService(reference);
try {
onUserManagerFound(iUserManager);
}
@Override
public void modifiedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Replacing modified service {} in netconf SSH.", reference);
+ logger.trace("Replacing modified service {} in netconf SSH.", reference);
server.addUserManagerService(service);
}
@Override
public void removedService(ServiceReference<IUserManager> reference, IUserManager service) {
- logger.info("Removing service {} from netconf SSH. " +
+ logger.trace("Removing service {} from netconf SSH. " +
"SSH won't authenticate users until IUserManeger service will be started.", reference);
removeUserManagerService();
}
if (path.equals("")){
throw new Exception("Missing netconf.ssh.pk.path key in configuration file.");
}
- FileInputStream fis = null;
- try {
- fis = new FileInputStream(path);
- } catch (FileNotFoundException e){
- throw new Exception("Missing file described by netconf.ssh.pk.path key in configuration file.");
- } catch (SecurityException e){
- throw new Exception("Read access denied to file described by netconf.ssh.pk.path key in configuration file.");
- }
- AuthProvider authProvider = null;
- try {
- authProvider = new AuthProvider(iUserManager,fis);
- } catch (Exception e){
- if (fis!=null){
- fis.close();
- }
- throw (e);
+
+ try (FileInputStream fis = new FileInputStream(path)){
+ AuthProvider authProvider = new AuthProvider(iUserManager,fis);
+ this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
}
- this.server = NetconfSSHServer.start(sshSocketAddressOptional.get().getPort(),tcpSocketAddress,authProvider);
+
Thread serverThread = new Thread(server,"netconf SSH server thread");
serverThread.setDaemon(true);
serverThread.start();
*/
package org.opendaylight.controller.netconf.ssh.authentication;
+import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
private static IUserManager um;
private static final String DEFAULT_USER = "netconf";
private static final String DEFAULT_PASSWORD = "netconf";
- private static InputStream privateKeyFileInputStream;
+ private String PEM;
private static final Logger logger = LoggerFactory.getLogger(AuthProvider.class);
throw new Exception("No usermanager service available.");
}
- this.privateKeyFileInputStream = privateKeyFileInputStream;
-
List<String> roles = new ArrayList<String>(1);
roles.add(UserLevel.SYSTEMADMIN.toString());
this.um.addLocalUser(new UserConfig(DEFAULT_USER, DEFAULT_PASSWORD, roles));
+
+ try {
+ PEM = IOUtils.toString(privateKeyFileInputStream);
+ } catch (IOException e) {
+ logger.error("Error reading RSA key from file.");
+ throw new IllegalStateException("Error reading RSA key from file.");
+ }
}
@Override
public boolean authenticated(String username, String password) throws Exception {
@Override
public char[] getPEMAsCharArray() throws Exception {
- char [] PEM = IOUtils.toCharArray(privateKeyFileInputStream);
- privateKeyFileInputStream.close();
- return PEM;
+ if (null == PEM){
+ logger.error("Missing RSA key string.");
+ throw new Exception("Missing RSA key.");
+ }
+ return PEM.toCharArray();
}
@Override
return AuthenticationResult.SUCCESS;
}
} catch (Exception e){
- logger.info("Authentication failed due to :" + e.getLocalizedMessage());
+ logger.warn("Authentication failed due to :" + e.getLocalizedMessage());
}
return AuthenticationResult.FAILURE;
}
com.siemens.ct.exi.exceptions,
com.siemens.ct.exi.api.dom,
org.xml.sax.helpers,
+ org.opendaylight.controller.config.api,
</Import-Package>
</instructions>
</configuration>
--- /dev/null
+/*
+ * 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;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.api.ConflictingVersionException;
+import org.opendaylight.controller.netconf.api.NetconfMessage;
+import org.opendaylight.controller.netconf.util.xml.XMLNetconfUtil;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class NetconfUtil {
+
+ private static final Logger logger = LoggerFactory.getLogger(NetconfUtil.class);
+
+ public static NetconfMessage createMessage(final File f) {
+ Preconditions.checkNotNull(f, "File parameter was null");
+ try {
+ return createMessage(new FileInputStream(f));
+ } catch (final FileNotFoundException e) {
+ logger.warn("File {} not found.", f, e);
+ }
+ return null;
+ }
+
+ public static NetconfMessage createMessage(final InputStream is) {
+ Preconditions.checkNotNull(is, "InputStream parameter was null");
+ Document doc = null;
+ try {
+ doc = XmlUtil.readXmlToDocument(is);
+ } catch (final IOException e) {
+ logger.warn("Error ocurred while parsing stream.", e);
+ } catch (final SAXException e) {
+ logger.warn("Error ocurred while final parsing stream.", e);
+ }
+ return (doc == null) ? null : new NetconfMessage(doc);
+ }
+
+ public static void checkIsMessageOk(NetconfMessage responseMessage) throws ConflictingVersionException {
+ XmlElement element = XmlElement.fromDomDocument(responseMessage.getDocument());
+ Preconditions.checkState(element.getName().equals(XmlNetconfConstants.RPC_REPLY_KEY));
+ element = element.getOnlyChildElement();
+
+ if (element.getName().equals(XmlNetconfConstants.OK)) {
+ return;
+ }
+
+ if (element.getName().equals(XmlNetconfConstants.RPC_ERROR)) {
+ logger.warn("Can not load last configuration, operation failed");
+ // is it ConflictingVersionException ?
+ XPathExpression xPathExpression = XMLNetconfUtil.compileXPath("/netconf:rpc-reply/netconf:rpc-error/netconf:error-info/netconf:error");
+ String error = (String) XmlUtil.evaluateXPath(xPathExpression, element.getDomElement(), XPathConstants.STRING);
+ if (error!=null && error.contains(ConflictingVersionException.class.getCanonicalName())) {
+ throw new ConflictingVersionException(error);
+ }
+ throw new IllegalStateException("Can not load last configuration, operation failed: "
+ + XmlUtil.toString(responseMessage.getDocument()));
+ }
+
+ logger.warn("Can not load last configuration. Operation failed.");
+ throw new IllegalStateException("Can not load last configuration. Operation failed: "
+ + XmlUtil.toString(responseMessage.getDocument()));
+ }
+}
public static void sendErrorMessage(final NetconfSession session,
final NetconfDocumentedException sendErrorException) {
- logger.info("Sending error {}", sendErrorException.getMessage(), sendErrorException);
+ logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
session.sendMessage(new NetconfMessage(errorDocument));
}
public static void sendErrorMessage(Channel channel, NetconfDocumentedException sendErrorException) {
- logger.info("Sending error {}", sendErrorException.getMessage(), sendErrorException);
+ logger.trace("Sending error {}", sendErrorException.getMessage(), sendErrorException);
final Document errorDocument = createDocument(sendErrorException);
channel.writeAndFlush(new NetconfMessage(errorDocument));
}
public static void sendErrorMessage(NetconfSession session, NetconfDocumentedException sendErrorException,
NetconfMessage incommingMessage) {
final Document errorDocument = createDocument(sendErrorException);
- logger.info("Sending error {}", XmlUtil.toString(errorDocument));
+ logger.trace("Sending error {}", XmlUtil.toString(errorDocument));
tryToCopyAttributes(incommingMessage.getDocument(), errorDocument, sendErrorException);
session.sendMessage(new NetconfMessage(errorDocument));
}
* 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.persist.impl;
+package org.opendaylight.controller.netconf.util;
import org.junit.Test;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.netconf.api.NetconfMessage;
-import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
import static org.junit.Assert.fail;
import static org.junit.matchers.JUnitMatchers.containsString;
-public class ConfigPersisterNotificationHandlerTest {
+public class NetconfUtilTest {
@Test
public void testConflictingVersionDetection() throws Exception {
- Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/conflictingVersionResponse.xml"));
+ Document document = XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconfMessages/conflictingversion/conflictingVersionResponse.xml"));
try{
- Util.checkIsOk(XmlElement.fromDomDocument(document).getOnlyChildElement(), new NetconfMessage(document));
+ NetconfUtil.checkIsMessageOk(new NetconfMessage(document));
fail();
}catch(ConflictingVersionException e){
assertThat(e.getMessage(), containsString("Optimistic lock failed. Expected parent version 21, was 18"));
}
}
-
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
private void startUp() {
allocateCache();
retrieveCache();
- if (floatingIPDB.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
}
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
private void startUp() {
allocateCache();
retrieveCache();
- if (networkDB.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
}
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
private void startUp() {
allocateCache();
retrieveCache();
- if (portDB.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
private void startUp() {
allocateCache();
retrieveCache();
- if (routerDB.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.Map.Entry;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
private void startUp() {
allocateCache();
retrieveCache();
- if (subnetDB.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadConfiguration();
}
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.3.6</version>
+ <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
*
* @param inputString
* IPv4 address in dotted decimal format
- * @returns high-endian representation of the IPv4 address as a long
+ * @returns high-endian representation of the IPv4 address as a long.
+ * This method will return 0 if the input is null.
*/
static long convert(String inputString) {
long ans = 0;
- String[] parts = inputString.split("\\.");
- for (String part: parts) {
- ans <<= 8;
- ans |= Integer.parseInt(part);
+ if (inputString != null) {
+ String[] parts = inputString.split("\\.");
+ for (String part: parts) {
+ ans <<= 8;
+ ans |= Integer.parseInt(part);
+ }
}
return ans;
}
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
- <version>4.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>${bundlescanner.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
</dependencies>
</project>
}
}
if (conflictsMsg.length() > 0) {
- LOGGER.info("JAXB type conflicts detected : {}", conflictsMsg.toString());
+ LOGGER.warn("JAXB type conflicts detected : {}", conflictsMsg.toString());
}
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>${usermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>${bundlescanner.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
- <version>${jersey.version}</version>
</dependency>
-
</dependencies>
</project>
} else {
auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource;
}
- logger.info(auditMsg);
+ logger.trace(auditMsg);
}
public static void auditlog(String moduleName, String user, String action, String resource) {
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class CommonsNorthboundTest extends TestCase {
+public class CommonsNorthboundTest {
@Test
public void testRestMessages() {
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class CommonsNorthboundExceptionTest extends TestCase {
+public class CommonsNorthboundExceptionTest {
@Test
public void testMethodNotAllowed() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
}
try {
- Node node = new Node(nodeType, nodeId);
+ Node node = Node.fromString(nodeType, nodeId);
Status status = connectionManager.disconnect(node);
if (status.isSuccess()) {
return Response.ok().build();
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>appauth</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>com.sun.jersey.jersey-servlet</artifactId>
- <version>${jersey-servlet.version}</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>${switchmanager.api.version}</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${spring.version}</version>
- <scope>provided</scope>
- </dependency>
-
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>org.apache.catalina.filters.CorsFilter</artifactId>
- <version>${corsfilter.version}</version>
</dependency>
</dependencies>
</project>
import java.util.HashSet;
import java.util.Set;
-import junit.framework.TestCase;
-
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.core.Property;
-public class ControllerManagerNorthboundTest extends TestCase {
+public class ControllerManagerNorthboundTest {
@Test
public void testControllerProperties() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>${forwardingrulesmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.httpclient</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.1.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
- <version>${forwarding.staticrouting}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services-implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>routing.dijkstra_implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>arphandler</artifactId>
- <version>${arphandler.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.implementation</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>security</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statistics.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>subnets.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>logging.bridge</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>bundlescanner.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
- <version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
- <version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
- <version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
- <version>${logback.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
- <version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
- <version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
- <version>1.8</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>javax.servlet</artifactId>
- <version>3.0.0.v201112011016</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>javax.servlet.jsp</artifactId>
- <version>2.2.0.v201112011158</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.ds</artifactId>
- <version>1.4.0.v20120522-1841</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.util</artifactId>
- <version>1.0.400.v20120522-2049</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi.services</artifactId>
- <version>3.3.100.v20120522-1822</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.osgi</artifactId>
- <version>3.8.1.v20120830-144521</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.command</artifactId>
- <version>0.8.0.v201108120515</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.runtime</artifactId>
- <version>0.8.0.v201108120515</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.apache.felix.gogo.shell</artifactId>
- <version>0.8.0.v201110170705</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.cm</artifactId>
- <version>1.0.400.v20120522-1841</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.console</artifactId>
- <version>1.0.0.v20120522-1841</version>
</dependency>
<dependency>
<groupId>equinoxSDK381</groupId>
<artifactId>org.eclipse.equinox.launcher</artifactId>
- <version>1.3.0.v20120522-1813</version>
</dependency>
<!-- Gemini Web -->
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.gemini.web.core</artifactId>
- <version>${geminiweb.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.gemini.web.extender</artifactId>
- <version>${geminiweb.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.gemini.web.tomcat</artifactId>
- <version>${geminiweb.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.kernel.equinox.extensions</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.common</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.io</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.math</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.osgi</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.osgi.manifest</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>geminiweb</groupId>
<artifactId>org.eclipse.virgo.util.parser.manifest</artifactId>
- <version>${virgo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager</artifactId>
- <version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- <version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
- <version>2.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
- <version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.fileinstall</artifactId>
- <version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
- <version>${commons.lang.version}</version>
</dependency>
<dependency>
<groupId>virgomirror</groupId>
<artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
- <version>3.8.0.I20120518-2145</version>
</dependency>
<dependency>
<groupId>eclipselink</groupId>
<artifactId>javax.persistence</artifactId>
- <version>2.0.4.v201112161009</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.activation</artifactId>
- <version>1.1.0.v201211130549</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.annotation</artifactId>
- <version>1.1.0.v201209060031</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.ejb</artifactId>
- <version>3.1.1.v201204261316</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.el</artifactId>
- <version>2.2.0.v201108011116</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.mail.glassfish</artifactId>
- <version>1.4.1.v201108011116</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.xml.rpc</artifactId>
- <version>1.1.0.v201005080400</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.catalina</artifactId>
- <version>7.0.32.v201211201336</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.catalina.ha</artifactId>
- <version>7.0.32.v201211201952</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.catalina.tribes</artifactId>
- <version>7.0.32.v201211201952</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.coyote</artifactId>
- <version>7.0.32.v201211201952</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.el</artifactId>
- <version>7.0.32.v201211081135</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.jasper</artifactId>
- <version>7.0.32.v201211201952</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.juli.extras</artifactId>
- <version>7.0.32.v201211081135</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.tomcat.api</artifactId>
- <version>7.0.32.v201211081135</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>org.apache.tomcat.util</artifactId>
- <version>7.0.32.v201211201952</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
- <version>1.2.0.v201105211821</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<artifactId>javax.servlet.jsp.jstl.impl</artifactId>
- <version>1.2.0.v201210211230</version>
</dependency>
<!-- Add Pax Exam -->
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-container-native</artifactId>
- <version>${exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-junit4</artifactId>
- <version>${exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-link-mvn</artifactId>
- <version>${exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-aether</artifactId>
- <version>${url.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
- <version>4.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.asm</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.aop</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context.support</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.beans</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.expression</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
- <version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aopalliance</groupId>
<artifactId>com.springsource.org.aopalliance</artifactId>
- <version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web.servlet</artifactId>
- <version>${spring.version}</version>
</dependency>
<!-- Spring security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
- <version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
- <version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
- <version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
- <version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.transaction</artifactId>
- <version>${spring-security.version}</version>
</dependency>
<!-- Visual VM hook -->
<dependency>
<groupId>org.ow2.chameleon.management</groupId>
<artifactId>chameleon-mbeans</artifactId>
- <version>1.0.0</version>
</dependency>
<!-- Jersey for JAXRS -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
- <version>${jersey.version}</version>
</dependency>
- <!-- <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId>
- <version>${jersey.version}</version> </dependency> -->
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
- <version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
- <version>${jersey.version}</version>
</dependency>
-
<dependency>
<groupId>eclipselink</groupId>
<artifactId>javax.resource</artifactId>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<!-- add dependency on all northbound bundles -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.northbound</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>controllermanager.northbound</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>flowprogrammer.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.bridgedomain.northbound</artifactId>
- <version>0.0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statistics.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>subnets.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topology.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager.northbound</artifactId>
- <version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
</parent>
<artifactId>jolokia-bridge</artifactId>
- <version>${jolokia.bridge.version}</version>
<description>Jolokia bridge web application</description>
+ <version>0.0.1-SNAPSHOT</version>
<packaging>bundle</packaging>
<build>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
- <version>2.4.0</version>
+ <version>${bundle.plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>${sal.connection.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.networkconfiguration</artifactId>
- <version>${sal.networkconfiguration.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>${connectionmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>networkconfig.neutron</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.moxy</artifactId>
- <version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
- <version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
- <version>2.5.0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
- <version>${forwarding.staticrouting}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
-public class StaticRoutingNorthboundTest extends TestCase {
+public class StaticRoutingNorthboundTest {
@Test
public void testStaticRoute() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>${statisticsmanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
-
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.reader.NodeTableStatistics;
import org.opendaylight.controller.sal.utils.NodeCreator;
-public class StatisticsNorthboundTest extends TestCase {
+public class StatisticsNorthboundTest {
@Test
public void testFlowStatistics() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
-
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${spring.version}</version>
- <scope>provided</scope>
- </dependency>
-
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
-
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
package org.opendaylight.controller.switchmanager.northbound;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-import java.util.ArrayList;
import org.junit.Assert;
import org.junit.Test;
-import junit.framework.TestCase;
-
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
import org.opendaylight.controller.sal.utils.NodeCreator;
-public class SwitchManagerNorthboundTest extends TestCase {
+public class SwitchManagerNorthboundTest {
@Test
public void testNodes() {
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>${containermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>${topologymanager.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>${sal.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>${usermanager.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.northbound</artifactId>
- <version>${commons.northbound.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
- <version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</plugins>
</build>
<dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </dependency>
- </dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal</artifactId>
+ </dependency>
+ </dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
} else {
if (!currentlyUp) {
// only generate log if the interface changes from down to up
- logger.info("Interface {} with address {} is UP!",
+ logger.trace("Interface {} with address {} is UP!",
netInt.getDisplayName(),
controllerIP.getHostAddress());
}
// build packet out
OFPacketOut po = new OFPacketOut()
.setBufferId(OFPacketOut.BUFFER_ID_NONE)
- .setInPort(OFPort.OFPP_NONE)
.setActions(Collections.singletonList((OFAction) action))
.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
+ if(outPkt.getIncomingNodeConnector() != null) {
+ po.setInPort((Short)outPkt.getIncomingNodeConnector().getID());
+ } else {
+ po.setInPort(OFPort.OFPP_NONE);
+ }
po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLength()
+ data.length);
List<LLDPTLV> optionalTLVList = lldp.getOptionalTLVList();
if (optionalTLVList == null) {
- logger.info("The discovery packet with null custom option from {}", dstNodeConnector);
+ logger.warn("The discovery packet with null custom option from {}", dstNodeConnector);
return false;
}
continue;
}
if (action.getType() == ActionType.SET_NEXT_HOP) {
- logger.info("Unsupported action: {}", action);
+ logger.warn("Unsupported action: {}", action);
continue;
}
}
}
private void printInfoMessage(String type, StatsRequest request) {
- log.info("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
+ log.trace("{} stats request not inserted for switch: {}. Queue size: {}. Collector state: {}.",
new Object[] {type, HexString.toHexString(request.switchId), pendingStatsRequests.size(),
statisticsCollector.getState().toString() });
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
- <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.TreeMap;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
if (this.fields == null) {
result = prime * result;
} else {
- int sum = 0;
- for (MatchType field : this.fields.keySet()) {
- MatchField f = this.fields.get(field);
- sum = sum + ((field==null ? 0 : field.calculateConsistentHashCode()) ^
- (f==null ? 0 : f.hashCode()));
+ // use a tree map as the order of hashMap is not guaranteed.
+ // 2 Match objects with fields in different order are still equal.
+ // Hence the hashCode should be the same too.
+ TreeMap<MatchType, MatchField> tm = new TreeMap<MatchType, MatchField>(this.fields);
+ for (MatchType field : tm.keySet()) {
+ MatchField f = tm.get(field);
+ int fieldHashCode = (field==null ? 0 : field.calculateConsistentHashCode()) ^
+ (f==null ? 0 : f.hashCode());
+ result = prime * result + fieldHashCode;
}
- result = prime * result + sum;
}
result = prime * result + matches;
return result;
Assert.assertTrue(match1.equals(match2));
}
+ @Test
+ public void testHashCodeWithReverseMatch() throws Exception {
+ InetAddress srcIP1 = InetAddress.getByName("1.1.1.1");
+ InetAddress ipMask1 = InetAddress.getByName("255.255.255.255");
+ InetAddress srcIP2 = InetAddress.getByName("2.2.2.2");
+ InetAddress ipMask2 = InetAddress.getByName("255.255.255.255");
+ MatchField field1 = new MatchField(MatchType.NW_SRC, srcIP1, ipMask1);
+ MatchField field2 = new MatchField(MatchType.NW_DST, srcIP2, ipMask2);
+ Match match1 = new Match();
+ match1.setField(field1);
+ match1.setField(field2);
+ Match match2 = match1.reverse();
+ Assert.assertFalse(match1.hashCode() == match2.hashCode());
+ }
+
@Test
public void testHashCode() throws Exception {
byte srcMac1[] = { (byte) 0x12, (byte) 0x34, (byte) 0x56, (byte) 0x78, (byte) 0x9a, (byte) 0xbc };
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.networkconfiguration</artifactId>
- <version>0.0.2-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
}
public VIP getVIPWithPoolName(VIP vip){
- cmLogger.info("Search a VIP with name:{}",vip);
+ cmLogger.trace("Search a VIP with name:{}",vip);
for(VIP vipTemp: this.vips.values()){
if(vipTemp.equals(vip)){
- cmLogger.info("Found VIP with pool detail : {}",vipTemp);
+ cmLogger.trace("Found VIP with pool detail : {}",vipTemp);
return vipTemp;
}
}
- cmLogger.info("VIP with pool detail not found ");
+ cmLogger.trace("VIP with pool detail not found ");
return null;
}
@Override
public VIP createVIP(String name,String ip,String protocol,short protocolPort,String poolName){
- cmLogger.info("Create VIP with the following details :[ name : "+name
+ cmLogger.trace("Create VIP with the following details :[ name : "+name
+" ip : "+ip
+" protocol : "+protocol
+" protocol_port : "+protocolPort
vip.setStatus(LBConst.STATUS_ACTIVE);
this.vips.put(name, vip);
- cmLogger.info("New VIP created : "+vip.toString());
+ cmLogger.trace("New VIP created : "+vip.toString());
return vip;
}
@Override
public VIP updateVIP(String name, String poolName){
- cmLogger.info("Updating VIP : "+name+" pool name to "+poolName);
+ cmLogger.trace("Updating VIP : "+name+" pool name to "+poolName);
if(vips.containsKey(name)){
VIP vip = vips.get(name);
@Override
public VIP deleteVIP(String name){
- cmLogger.info("Deleting VIP : "+name);
+ cmLogger.trace("Deleting VIP : "+name);
VIP vip = vips.get(name);
}
}
- cmLogger.info("VIP removed : "+vip.toString());
+ cmLogger.trace("VIP removed : "+vip.toString());
vips.remove(vip.getName());
PoolMember pm = new PoolMember(name,memberIP,poolName);
- cmLogger.info("Adding pool member : "+pm.toString());
+ cmLogger.trace("Adding pool member : "+pm.toString());
pools.get(poolName).addMember(pm);
@Override
public PoolMember removePoolMember(String name, String poolName){
- cmLogger.info("Removing pool member : {} from pool {}",name, poolName);
+ cmLogger.trace("Removing pool member : {} from pool {}",name, poolName);
Pool pool = pools.get(poolName);
pool.removeMember(name);
- cmLogger.info("Pool member {} removed from {} ",name,poolName);
+ cmLogger.trace("Pool member {} removed from {} ",name,poolName);
return pm;
}
Pool newPool = new Pool(name,lbMethod);
- cmLogger.info("New pool created : " + newPool.toString());
+ cmLogger.trace("New pool created : " + newPool.toString());
pools.put(name, newPool);
}
- cmLogger.info("Pool removed : "+pool.toString());
+ cmLogger.trace("Pool removed : "+pool.toString());
pools.remove(poolName);
* @return Details of the source machine in Client object.
*/
public Client getClientFromPacket(IPv4 inPkt){
- lbuLogger.info("Find client information from packet : {}",inPkt.toString());
+ lbuLogger.trace("Find client information from packet : {}",inPkt.toString());
String ip = NetUtils.getInetAddress(inPkt.getSourceAddress()).getHostAddress();
String protocol = IPProtocols.getProtocolName(inPkt.getProtocol());
- lbuLogger.info("client ip {} and protocl {}",ip,protocol);
+ lbuLogger.trace("client ip {} and protocl {}",ip,protocol);
Packet tpFrame= inPkt.getPayload();
- lbuLogger.info("Get protocol layer {}",tpFrame.toString());
+ lbuLogger.trace("Get protocol layer {}",tpFrame.toString());
short port = 0;
port = udpFrame.getSourcePort();
}
- lbuLogger.info("Found port {}",port);
+ lbuLogger.trace("Found port {}",port);
Client source = new Client(ip, protocol,port);
- lbuLogger.info("Client information : {}",source.toString());
+ lbuLogger.trace("Client information : {}",source.toString());
return source;
}
*/
public VIP getVIPFromPacket(IPv4 inPkt){
- lbuLogger.info("Find VIP information from packet : {}",inPkt.toString());
+ lbuLogger.trace("Find VIP information from packet : {}",inPkt.toString());
String ip = NetUtils.getInetAddress(inPkt.getDestinationAddress()).getHostAddress();
VIP dest = new VIP(null,ip, protocol,port,null);
- lbuLogger.info("VIP information : {}",dest.toString());
+ lbuLogger.trace("VIP information : {}",dest.toString());
return dest;
}
forwardPort = hnConnector.getnodeConnector();
lbsLogger
- .info("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",
+ .trace("Both source (client) and destination pool machine is connected to same switch nodes. Respective ports are - {},{}",
forwardPort, inPkt.getIncomingNodeConnector());
} else {
Path route = this.routing.getRoute(clientNode, destNode);
- lbsLogger.info("Path between source (client) and destination switch nodes : {}",
+ lbsLogger.trace("Path between source (client) and destination switch nodes : {}",
route.toString());
forwardPort = route.getEdges().get(0).getTailNodeConnector();
if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp,
hnConnector.getDataLayerAddressBytes(), forwardPort,
LBConst.FORWARD_DIRECTION_LB_FLOW)) {
- lbsLogger.info("Traffic from client : {} will be routed " + "to pool machine : {}",
+ lbsLogger.trace("Traffic from client : {} will be routed " + "to pool machine : {}",
client, poolMemberIp);
} else {
lbsLogger.error("Not able to route traffic from client : {}", client);
if (installLoadBalancerFlow(client, vip, clientNode, poolMemberIp, vipMacAddr,
inPkt.getIncomingNodeConnector(), LBConst.REVERSE_DIRECTION_LB_FLOW)) {
- lbsLogger.info("Flow rule installed to change the source ip/mac from "
+ lbsLogger.trace("Flow rule installed to change the source ip/mac from "
+ "pool machine ip {} to VIP {} for traffic coming pool machine", poolMemberIp,
vip);
} else {
FlowEntry fEntry = new FlowEntry(policyName, flowName, flow, sourceSwitch);
- lbsLogger.info("Install flow entry {} on node {}", fEntry.toString(), sourceSwitch.toString());
+ lbsLogger.trace("Install flow entry {} on node {}", fEntry.toString(), sourceSwitch.toString());
if (!this.ruleManager.checkFlowEntryConflict(fEntry)) {
if (this.ruleManager.installFlowEntry(fEntry).isSuccess()) {
if (props != null) {
this.containerName = (String) props.get("containerName");
- lbsLogger.info("Running container name:" + this.containerName);
+ lbsLogger.trace("Running container name:" + this.containerName);
} else {
// In the Global instance case the containerName is empty
this.containerName = "";
}
- lbsLogger.info(configManager.toString());
+ lbsLogger.trace(configManager.toString());
}
@Override
public String getPoolMemberForClient(Client source, VIP dest){
- rLogger.info("Received traffic from client : {} for VIP : {} ",source, dest);
+ rLogger.trace("Received traffic from client : {} for VIP : {} ",source, dest);
syncWithLoadBalancerData();
if(this.clientMemberMap.containsKey(source)){
pm= this.clientMemberMap.get(source);
- rLogger.info("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
+ rLogger.trace("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
}else{
Pool pool = null;
pool = this.cmgr.getPool(dest.getPoolName());
int memberNum = this.randomGenerator.nextInt(pool.getAllMembers().size()-1);
pm = pool.getAllMembers().get(memberNum);
this.clientMemberMap.put(source, pm );
- rLogger.info("Network traffic from client {} will be directed to pool member {}",pm);
+ rLogger.trace("Network traffic from client {} will be directed to pool member {}",pm);
}
return pm.getIp();
}
@Override
public String getPoolMemberForClient(Client source, VIP dest){
- rrLogger.info("Received traffic from client : {} for VIP : {} ",source, dest);
+ rrLogger.trace("Received traffic from client : {} for VIP : {} ",source, dest);
syncWithLoadBalancerData();
if(this.clientMemberMap.containsKey(source)){
pm= this.clientMemberMap.get(source);
- rrLogger.info("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
+ rrLogger.trace("Client {} had sent traffic before,new traffic will be routed to the same pool member {}",source,pm);
}else{
Pool pool = null;
pool = this.cmgr.getPool(dest.getPoolName());
pm = pool.getAllMembers().get(memberNum);
this.clientMemberMap.put(source, pm );
- rrLogger.info("New client's packet will be directed to pool member {}",pm);
+ rrLogger.trace("New client's packet will be directed to pool member {}",pm);
memberNum++;
if(memberNum > pool.getAllMembers().size()-1){
pm = pool.getAllMembers().get(0);
this.clientMemberMap.put(source, pm);
- rrLogger.info("Network traffic from client {} will be directed to pool member {}",pm);
+ rrLogger.trace("Network traffic from client {} will be directed to pool member {}",pm);
this.nextItemFromPool.put(dest, 1);
rrLogger.debug("Next pool member for new client of VIP is set to {}",pool.getAllMembers().get(1));
}
import org.opendaylight.controller.samples.loadbalancer.entities.VIP;\r
import org.opendaylight.controller.samples.loadbalancer.policies.RoundRobinLBPolicy;\r
\r
-import junit.framework.TestCase;\r
-\r
/**\r
*\r
* Class to unit test the load balancing policies.\r
*\r
*/\r
-public class LoadBalancerTest extends TestCase {\r
+public class LoadBalancerTest {\r
@Test\r
public void testRoundRobinPolicy() {\r
ConfigManager cm = null;\r
c1 = new Client("10.0.0.1","TCP",(short)5003);\r
Assert.assertTrue(rrp.getPoolMemberForClient(c1, vip).equals(host4.getIp()));\r
}\r
-}
\ No newline at end of file
+}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>samples.loadbalancer</artifactId>
- <version>${samples.loadbalancer}</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>commons.northbound</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.codehaus.enunciate</groupId>
<artifactId>enunciate-core-annotations</artifactId>
- <version>${enunciate.version}</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
private void allocateCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.trace("un-initialized clusterContainerService, can't create cache");
return;
}
@SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't retrieve cache");
+ log.trace("un-initialized clusterContainerService, can't retrieve cache");
return;
}
private void destroyCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't destroy cache");
+ log.trace("un-initialized clusterContainerService, can't destroy cache");
return;
}
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>orbit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-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>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal.connection.implementation</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
private static final long serialVersionUID = 1L;
// Key fields
private InetAddress networkAddress;
+ private transient InetAddress subnetPrefix;
private short subnetMaskLength;
// Property fields
private short vlan;
*/
public Subnet setNetworkAddress(InetAddress networkAddress) {
this.networkAddress = networkAddress;
+ this.subnetPrefix = null;
return this;
}
if (ip == null) {
return false;
}
- InetAddress thisPrefix = getPrefixForAddress(this.networkAddress);
+ if(subnetPrefix == null) {
+ subnetPrefix = getPrefixForAddress(this.networkAddress);
+ }
InetAddress otherPrefix = getPrefixForAddress(ip);
boolean isSubnetOf = true;
- if (((thisPrefix == null) || (otherPrefix == null)) || (!thisPrefix.equals(otherPrefix)) ) {
+ if (((subnetPrefix == null) || (otherPrefix == null)) || (!subnetPrefix.equals(otherPrefix)) ) {
isSubnetOf = false;
}
return isSubnetOf;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
+import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.packet.BitBufferHelper;
import org.opendaylight.controller.sal.utils.GUIField;
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
-public class SubnetConfig implements Cloneable, Serializable {
+public class SubnetConfig extends ConfigurationObject implements Cloneable, Serializable {
private static final long serialVersionUID = 1L;
private static final String prettyFields[] = { GUIField.NAME.toString(), GUIField.GATEWAYIP.toString(),
GUIField.NODEPORTS.toString() };
}
private Status validateName() {
- if (name == null || name.trim().isEmpty()) {
+ if (!isValidResourceName(name)) {
return new Status(StatusCode.BADREQUEST, "Invalid name");
}
return new Status(StatusCode.SUCCESS);
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-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>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
retrieveCaches();
/*
- * Read startup and build database if we have not already gotten the
- * configurations synced from another node
+ * Read startup and build database if we are the coordinator
*/
- if (subnetsConfigList.isEmpty()) {
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
loadSubnetConfiguration();
- }
- if (spanConfigList.isEmpty()) {
loadSpanConfiguration();
- }
- if (nodeConfigList.isEmpty()) {
loadSwitchConfiguration();
}
@SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
if (this.clusterContainerService == null) {
- log.info("un-initialized clusterContainerService, can't create cache");
+ log.warn("un-initialized clusterContainerService, can't create cache");
return;
}
return;
}
- log.info("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
+ log.trace("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode());
if (modeChange) {
notifyModeChange(node, cfgObject.isProactive());
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<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>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
userLinksFileName = ROOT + "userTopology_" + containerName + ".conf";
registerWithOSGIConsole();
- loadConfiguration();
+ if ((clusterContainerService != null) && (clusterContainerService.amICoordinator())) {
+ loadConfiguration();
+ }
// Restore the shuttingDown status on init of the component
shuttingDown = false;
notifyThread = new Thread(new TopologyNotify(notifyQ));
private TopoEdgeUpdate edgeUpdate(Edge e, UpdateType type, Set<Property> props) {
switch (type) {
case ADDED:
- // Avoid redundant update as notifications trigger expensive tasks
- if (edgesDB.containsKey(e)) {
- log.trace("Skipping redundant edge addition: {}", e);
- return null;
- }
-
- // Ensure that head node connector exists
- if (!headNodeConnectorExist(e)) {
- log.warn("Ignore edge that contains invalid node connector: {}", e);
- return null;
- }
-
- // Check if nodeConnectors of the edge were correctly categorized
- // by OF plugin
- crossCheckNodeConnectors(e);
- // Make sure the props are non-null
+ // Make sure the props are non-null or create a copy
if (props == null) {
props = new HashSet<Property>();
} else {
props = new HashSet<Property>(props);
}
- //in case of node switch-over to a different cluster controller,
- //let's retain edge props
Set<Property> currentProps = this.edgesDB.get(e);
- if (currentProps != null){
+ 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)) {
+ log.warn("Ignore edge that contains invalid node connector: {}", e);
+ return null;
+ }
+
+ // Check if nodeConnectors of the edge were correctly categorized
+ // by protocol plugin
+ crossCheckNodeConnectors(e);
+
// Now make sure there is the creation timestamp for the
// edge, if not there, stamp with the first update
boolean found_create = false;
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
<artifactId>pax-exam-container-native</artifactId>
- <version>${exam.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>protocol_plugins.stub</artifactId>
- <version>0.4.1-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>sal.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager.it.implementation</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.stub</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>switchmanager</artifactId>
</dependency>
-
- <dependency>
+ <dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration.implementation</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>hosttracker</artifactId>
- <version>${hosttracker.version}</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
</dependencies>
<properties>
</Import-Package>
<Export-Package>
org.opendaylight.controller.usermanager,
-<!--
- org.opendaylight.controller.usermanager.internal
- -->
</Export-Package>
<Bundle-Activator>
-<!--
- org.opendaylight.controller.usermanager.internal.Activator
- -->
</Bundle-Activator>
</instructions>
<manifestLocation>${project.basedir}/META-INF</manifestLocation>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
import org.opendaylight.controller.sal.authorization.AuthResultEnum;
import org.opendaylight.controller.sal.authorization.IResourceAuthorization;
import org.opendaylight.controller.sal.authorization.UserLevel;
-import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.IObjectReader;
import org.opendaylight.controller.sal.utils.ObjectReader;
import org.opendaylight.controller.sal.utils.ObjectWriter;
import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
import org.opendaylight.controller.usermanager.AuthResponse;
import org.opendaylight.controller.usermanager.AuthenticatedUser;
import org.opendaylight.controller.usermanager.AuthorizationConfig;
import org.opendaylight.controller.usermanager.UserConfig;
import org.opendaylight.controller.usermanager.security.SessionManager;
import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
-
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
private void loadConfigurations() {
// To encode and decode user and server configuration objects
loadSecurityKeys();
-
/*
- * Do not load local startup file if we already got the configurations
- * synced from another cluster node
+ * Do not load local startup file if we are not the coordinator
*/
- if (localUserConfigList.isEmpty()) {
+ if ((clusterGlobalService != null) && (clusterGlobalService.amICoordinator())) {
loadUserConfig();
- }
- if (remoteServerConfigList.isEmpty()) {
loadServerConfig();
- }
- if (authorizationConfList.isEmpty()) {
loadAuthConfig();
}
}
rcResponse = aaaClient.authService(userName, password,
aaaServer.getAddress(), aaaServer.getSecret());
if (rcResponse.getStatus() == AuthResultEnum.AUTH_ACCEPT) {
- logger.info(
+ logger.trace(
"Remote Authentication Succeeded for User: \"{}\", by Server: {}",
userName, aaaServer.getAddress());
remotelyAuthenticated = true;
break;
} else if (rcResponse.getStatus() == AuthResultEnum.AUTH_REJECT) {
- logger.info(
+ logger.trace(
"Remote Authentication Rejected User: \"{}\", from Server: {}, Reason:{}",
new Object[] { userName, aaaServer.getAddress(),
rcResponse.getStatus().toString() });
} else {
- logger.info(
+ logger.trace(
"Remote Authentication Failed for User: \"{}\", from Server: {}, Reason:{}",
new Object[] { userName, aaaServer.getAddress(),
rcResponse.getStatus().toString() });
// Trigger cluster update
localUserConfigList.put(user, targetConfigEntry);
- logger.info("Password changed for User \"{}\"", user);
+ logger.trace("Password changed for User \"{}\"", user);
return status;
}
// TODO: if user was authenticated through AAA server, send
// Acct-Status-Type=stop message to server with logout as reason
removeUserFromActiveList(userName);
- logger.info("User \"{}\" logged out", userName);
+ logger.trace("User \"{}\" logged out", userName);
}
/*
// TODO: if user was authenticated through AAA server, send
// Acct-Status-Type=stop message to server with timeout as reason
removeUserFromActiveList(userName);
- logger.info("User \"{}\" timed out", userName);
+ logger.trace("User \"{}\" timed out", userName);
}
@Override
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwarding.staticrouting</artifactId>
- <version>${forwarding.staticrouting}</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
}
},
modal : {
+ registry : { callback:undefined },
initialize: {
updateNode: function(evt) {
one.f.switchmanager.nodesLearnt.ajax.main(one.f.switchmanager.rootUrl + "/tiers", function(tiers) {
// inject body (nodePorts)
one.lib.modal.inject.body($modal, $body);
- $modal.modal();
+
+ $modal.modal().on("shown",function() {
+ var callback = one.f.switchmanager.nodesLearnt.modal.registry.callback;
+ if( callback !== undefined && $.isFunction(callback)) {
+ callback();
+ }
+ });
});
},
popout: function() {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>clustering.services</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>connectionmanager</artifactId>
- <version>0.1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-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>usermanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
} else {
auditMsg = "Mode: " + mode + " User " + user + " " + action + " " + moduleName + " " + resource;
}
- logger.info(auditMsg);
+ logger.trace(auditMsg);
}
public static void auditlog(String moduleName, String user, String action, String resource) {
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>configuration</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>topologymanager</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>forwardingrulesmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>containermanager</artifactId>
- <version>0.5.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal</artifactId>
- <version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>statisticsmanager</artifactId>
- <version>0.5.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>web</artifactId>
- <version>0.4.1-SNAPSHOT</version>
</dependency>
-
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
- <version>4.1.0</version>
+ <version>5.0.0</version>
</dependency>
<dependency>
<groupId>ch.ethz.ganymed</groupId>