</resource>
</resources>
<plugins>
+ <plugin>
+ <groupId>org.apache.karaf.tooling</groupId>
+ <artifactId>karaf-maven-plugin</artifactId>
+ <version>${karaf.version}</version>
+ <extensions>true</extensions>
+ <executions>
+ <execution>
+ <id>features-create-kar</id>
+ <goals>
+ <goal>features-create-kar</goal>
+ </goals>
+ <configuration>
+ <featuresFile>${project.build.directory}/classes/${features.file}</featuresFile>
+ </configuration>
+ </execution>
+ </executions>
+ <!-- There is no useful configuration for the kar mojo. The features-generate-descriptor mojo configuration may be useful -->
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<bundle start="true" start-level="35">mvn:orbit/org.apache.juli.extras/7.0.32.v201211081135</bundle>
<bundle start="true" start-level="35">mvn:orbit/org.apache.tomcat.api/7.0.32.v201211081135</bundle>
<bundle start="true" start-level="35">mvn:orbit/org.apache.tomcat.util/7.0.32.v201211201952</bundle>
+ <bundle start="true" start-level="35">wrap:mvn:virgomirror/org.eclipse.jdt.core.compiler.batch/3.8.0.I20120518-2145</bundle>
</feature>
<feature name="base-spring" description="Opendaylight Spring Support" version="${spring.version}">
<bundle>mvn:org.ow2.asm/asm-all/${asm.version}</bundle>
private final byte[] tMac;
private final byte[] sMac;
private final InetAddress sIP;
+ private final short vlan;
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
+ result = prime * result + ((port == null) ? 0 : port.hashCode());
result = prime * result + ((sIP == null) ? 0 : sIP.hashCode());
result = prime * result + Arrays.hashCode(sMac);
result = prime * result + Arrays.hashCode(tMac);
+ result = prime * result + vlan;
return result;
}
if (this == obj) {
return true;
}
- if (obj == null) {
+ if (!super.equals(obj)) {
return false;
}
if (!(obj instanceof ARPReply)) {
return false;
}
ARPReply other = (ARPReply) obj;
+ if (port == null) {
+ if (other.port != null) {
+ return false;
+ }
+ } else if (!port.equals(other.port)) {
+ return false;
+ }
if (sIP == null) {
if (other.sIP != null) {
return false;
if (!Arrays.equals(tMac, other.tMac)) {
return false;
}
+ if (vlan != other.vlan) {
+ return false;
+ }
return true;
}
- public ARPReply(NodeConnector port, InetAddress sIP, byte[] sMAC, InetAddress tIP, byte[] tMAC) {
+ public ARPReply(NodeConnector port, InetAddress sIP, byte[] sMAC, InetAddress tIP, byte[] tMAC, short vlan) {
super(tIP);
this.tMac = tMAC;
this.sIP = sIP;
this.sMac = sMAC;
this.port = port;
+ this.vlan = vlan;
}
- public ARPReply(InetAddress tIP, byte[] tMAC) {
+ public ARPReply(InetAddress tIP, byte[] tMAC, short vlan) {
super(tIP);
this.tMac = tMAC;
this.sIP = null;
this.sMac = null;
this.port = null;
+ this.vlan = vlan;
}
public byte[] getTargetMac() {
return port;
}
+ public short getVlan() {
+ return vlan;
+ }
+
/*
* (non-Javadoc)
*
builder.append("sIP=")
.append(sIP);
}
+ if (vlan != 0) {
+ builder.append(", vlan=")
+ .append(vlan);
+ }
builder.append("]");
return builder.toString();
}
import org.opendaylight.controller.sal.packet.ARP;
import org.opendaylight.controller.sal.packet.Ethernet;
import org.opendaylight.controller.sal.packet.IDataPacketService;
+import org.opendaylight.controller.sal.packet.IEEE8021Q;
import org.opendaylight.controller.sal.packet.IListenDataPacket;
import org.opendaylight.controller.sal.packet.IPv4;
import org.opendaylight.controller.sal.packet.Packet;
import org.opendaylight.controller.sal.packet.PacketResult;
import org.opendaylight.controller.sal.packet.RawPacket;
-import org.opendaylight.controller.sal.routing.IRouting;
import org.opendaylight.controller.sal.utils.EtherTypes;
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.NetUtils;
private ISwitchManager switchManager;
private ITopologyManager topologyManager;
private IDataPacketService dataPacketService;
- private IRouting routing;
private IClusterContainerServices clusterContainerService;
private IConnectionManager connectionManager;
private Set<IfHostListener> hostListeners = new CopyOnWriteArraySet<IfHostListener>();
}
}
- protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP, byte[] tMAC, InetAddress tIP) {
+ protected void sendARPReply(NodeConnector p, byte[] sMAC, InetAddress sIP, byte[] tMAC, InetAddress tIP, short vlan) {
byte[] senderIP = sIP.getAddress();
byte[] targetIP = tIP.getAddress();
ARP arp = createARP(ARP.REPLY, sMAC, senderIP, tMAC, targetIP);
sIP, HexEncode.bytesToHexString(tMAC), tIP, p);
}
- Ethernet ethernet = createEthernet(sMAC, tMAC, arp);
+ Ethernet ethernet = createEthernet(sMAC, tMAC, arp, vlan);
RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
destPkt.setOutgoingNodeConnector(p);
this.dataPacketService.transmitDataPacket(destPkt);
}
- private void logArpPacket(ARP pkt, NodeConnector p) {
+ private void logArpPacket(ARP pkt, NodeConnector p, short vlan) {
try {
- if (pkt.getOpCode() == ARP.REQUEST) {
- log.trace("Received Arp Request with srcMac {} - srcIp {} - dstMac {} - dstIp {} - inport {}", HexEncode.bytesToHexString(pkt.getSenderHardwareAddress()),
- InetAddress.getByAddress(pkt.getSenderProtocolAddress()), HexEncode.bytesToHexString(pkt.getTargetHardwareAddress()),
- InetAddress.getByAddress(pkt.getTargetProtocolAddress()), p);
- } else if(pkt.getOpCode() == ARP.REPLY) {
- log.trace("Received Arp Reply with srcMac {} - srcIp {} - dstMac {} - dstIp {} - inport {}", HexEncode.bytesToHexString(pkt.getSenderHardwareAddress()),
- InetAddress.getByAddress(pkt.getSenderProtocolAddress()), HexEncode.bytesToHexString(pkt.getTargetHardwareAddress()),
- InetAddress.getByAddress(pkt.getTargetProtocolAddress()), p);
- }
- } catch(UnknownHostException e) {
+ log.trace("Received Arp {} with srcMac {} - srcIp {} - dstMac {} - dstIp {} - inport {} {}",
+ ((pkt.getOpCode() == ARP.REQUEST) ? "Request" : "Reply"),
+ HexEncode.bytesToHexString(pkt.getSenderHardwareAddress()),
+ InetAddress.getByAddress(pkt.getSenderProtocolAddress()),
+ HexEncode.bytesToHexString(pkt.getTargetHardwareAddress()),
+ InetAddress.getByAddress(pkt.getTargetProtocolAddress()), p, (vlan != 0 ? "on vlan " + vlan : ""));
+
+ } catch (UnknownHostException e) {
log.warn("Illegal Ip Address in the ARP packet", e);
}
}
- protected void handleARPPacket(Ethernet eHeader, ARP pkt, NodeConnector p) {
+ protected void handleARPPacket(Ethernet eHeader, ARP pkt, NodeConnector p, short vlan) {
if(log.isTraceEnabled()) {
- logArpPacket(pkt, p);
+ logArpPacket(pkt, p, vlan);
}
byte[] sourceMAC = eHeader.getSourceMACAddress();
HostNodeConnector requestor = null;
if (NetUtils.isUnicastMACAddr(sourceMAC) && p.getNode() != null) {
try {
- requestor = new HostNodeConnector(sourceMAC, sourceIP, p, subnet.getVlan());
+ requestor = new HostNodeConnector(sourceMAC, sourceIP, p, vlan);
} catch (ConstructionException e) {
log.debug("Received ARP packet with invalid MAC: {}", HexEncode.bytesToHexString(sourceMAC));
return;
// the true value indicates we should generate replies to requestors
// across the cluster
log.trace("Received ARP reply packet from {}, reply to all requestors.", sourceIP);
- arpRequestReplyEvent.put(new ARPReply(sourceIP, sourceMAC), true);
+ arpRequestReplyEvent.put(new ARPReply(sourceIP, sourceMAC, vlan), true);
return;
}
log.trace("Received local ARP req. for default gateway. Replying with controller MAC: {}",
HexEncode.bytesToHexString(getControllerMAC()));
}
- sendARPReply(p, getControllerMAC(), targetIP, pkt.getSenderHardwareAddress(), sourceIP);
+ sendARPReply(p, getControllerMAC(), targetIP, pkt.getSenderHardwareAddress(), sourceIP, vlan);
} else {
log.trace("Received non-local ARP req. for default gateway. Raising reply event");
arpRequestReplyEvent.put(
- new ARPReply(p, targetIP, getControllerMAC(), sourceIP, pkt.getSenderHardwareAddress()), false);
+ new ARPReply(p, targetIP, getControllerMAC(), sourceIP, pkt.getSenderHardwareAddress(), vlan), false);
}
return;
}
log.trace("Received ARP req. for known host {}, sending reply...", targetIP);
if (connectionManager.getLocalityStatus(p.getNode()) == ConnectionLocality.LOCAL) {
sendARPReply(p, host.getDataLayerAddressBytes(), host.getNetworkAddress(),
- pkt.getSenderHardwareAddress(), sourceIP);
+ pkt.getSenderHardwareAddress(), sourceIP, vlan);
} else {
arpRequestReplyEvent.put(new ARPReply(p, host.getNetworkAddress(), host.getDataLayerAddressBytes(),
- sourceIP, pkt.getSenderHardwareAddress()), false);
+ sourceIP, pkt.getSenderHardwareAddress(), vlan), false);
}
} else {
/*
}
byte[] destMACAddress = NetUtils.getBroadcastMACAddr();
- Ethernet ethernet = createEthernet(getControllerMAC(), destMACAddress, arp);
+ Ethernet ethernet = createEthernet(getControllerMAC(), destMACAddress, arp, (short)0);
// TODO For now send port-by-port, see how to optimize to
// send to multiple ports at once
}
/**
- * Send a unicast ARP Request to the known host on a specific switch/port as
- * defined in the host. The sender IP is the networkAddress of the subnet
- * The sender MAC is the controller's MAC
+ * Send a unicast ARP Request to the known host on specific (switch/port,
+ * vlan) as defined in the host. The sender IP is the networkAddress of the
+ * subnet The sender MAC is the controller's MAC
*/
protected void sendUcastARPRequest(HostNodeConnector host, Subnet subnet) {
log.trace("sendUcastARPRequest host:{} subnet:{}", host, subnet);
outPort);
}
- Ethernet ethernet = createEthernet(getControllerMAC(), targetMAC, arp);
+ Ethernet ethernet = createEthernet(getControllerMAC(), targetMAC, arp, host.getVlan());
RawPacket destPkt = this.dataPacketService.encodeDataPacket(ethernet);
destPkt.setOutgoingNodeConnector(outPort);
* @param pkt
* @param p
*/
- protected void handlePuntedIPPacket(IPv4 pkt, NodeConnector p) {
+ protected void handlePuntedIPPacket(IPv4 pkt, NodeConnector p, short vlan) {
InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress());
if (dIP == null) {
log.trace("Received a frame of size: {}", inPkt.getPacketData().length);
Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt);
if (formattedPak instanceof Ethernet) {
- Object nextPak = formattedPak.getPayload();
+ Packet nextPak = formattedPak.getPayload();
+ short vlan = 0;
+ if (nextPak instanceof IEEE8021Q) {
+ vlan = ((IEEE8021Q) nextPak).getVid();
+ log.trace("Moved after the dot1Q header");
+ nextPak = ((IEEE8021Q) nextPak).getPayload();
+ }
if (nextPak instanceof IPv4) {
log.trace("Handle IP packet: {}", formattedPak);
- handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector());
+ handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector(), vlan);
} else if (nextPak instanceof ARP) {
log.trace("Handle ARP packet: {}", formattedPak);
- handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt.getIncomingNodeConnector());
+ handleARPPacket((Ethernet) formattedPak, (ARP) nextPak, inPkt.getIncomingNodeConnector(), vlan);
}
}
return PacketResult.IGNORED;
return arp;
}
- private Ethernet createEthernet(byte[] sourceMAC, byte[] targetMAC, ARP arp) {
+ private Ethernet createEthernet(byte[] sourceMAC, byte[] targetMAC, ARP arp, short vlan) {
Ethernet ethernet = new Ethernet();
ethernet.setSourceMACAddress(sourceMAC);
ethernet.setDestinationMACAddress(targetMAC);
- ethernet.setEtherType(EtherTypes.ARP.shortValue());
- ethernet.setPayload(arp);
+ if (vlan == 0) {
+ ethernet.setEtherType(EtherTypes.ARP.shortValue());
+ ethernet.setPayload(arp);
+ } else {
+ IEEE8021Q dot1q = new IEEE8021Q();
+ dot1q.setVid(vlan);
+ dot1q.setEtherType(EtherTypes.ARP.shortValue());
+ dot1q.setPayload(arp);
+ ethernet.setEtherType(EtherTypes.VLANTAGGED.shortValue());
+ ethernet.setPayload(dot1q);
+ }
return ethernet;
}
}
}
- private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC) {
+ private void generateAndSendReply(InetAddress sourceIP, byte[] sourceMAC, short vlan) {
if (log.isTraceEnabled()) {
log.trace("generateAndSendReply called with params sourceIP:{} sourceMAC:{}", sourceIP,
HexEncode.bytesToHexString(sourceMAC));
for (HostNodeConnector host : hosts) {
if (log.isTraceEnabled()) {
log.trace(
- "Sending ARP Reply with src {}/{}, target {}/{}",
+ "Sending ARP Reply with src {}/{}, target {}/{} {}",
new Object[] { HexEncode.bytesToHexString(sourceMAC), sourceIP,
- HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host.getNetworkAddress() });
+ HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host.getNetworkAddress(),
+ (vlan != 0 ? "on vlan " + vlan : "") });
}
if (connectionManager.getLocalityStatus(host.getnodeconnectorNode()) == ConnectionLocality.LOCAL) {
sendARPReply(host.getnodeConnector(), sourceMAC, sourceIP, host.getDataLayerAddressBytes(),
- host.getNetworkAddress());
+ host.getNetworkAddress(), vlan);
} else {
/*
* In the remote event a requestor moved to another controller
*/
arpRequestReplyEvent.put(
new ARPReply(host.getnodeConnector(), sourceIP, sourceMAC, host.getNetworkAddress(), host
- .getDataLayerAddressBytes()), false);
+ .getDataLayerAddressBytes(), vlan), false);
}
}
}
// requestors across the cluster
if (ev.isNewReply()) {
log.trace("Trigger a generateAndSendReply in response to {}", rep);
- generateAndSendReply(rep.getTargetIP(), rep.getTargetMac());
+ generateAndSendReply(rep.getTargetIP(), rep.getTargetMac(), rep.getVlan());
// Otherwise, a specific reply. If local, send out.
} else if (connectionManager.getLocalityStatus(rep.getPort().getNode()) == ConnectionLocality.LOCAL) {
log.trace("ARPCacheEventHandler - sendUcatARPReply locally in response to {}", rep);
sendARPReply(rep.getPort(), rep.getSourceMac(), rep.getSourceIP(), rep.getTargetMac(),
- rep.getTargetIP());
+ rep.getTargetIP(), rep.getVlan());
}
}
} catch (InterruptedException e) {
<artifactId>netconf-client</artifactId>
<version>${netconf.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- <version>${netconf.version}</version>
- <type>test-jar</type>
- </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-client</artifactId>
+ <version>${netconf.version}</version>
+ <type>test-jar</type>
+ </dependency>
<!--Netconf config-->
<dependency>
<artifactId>protocol_plugins.stub</artifactId>
<version>${protocol_plugins.stub.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>routing.dijkstra_implementation</artifactId>
<artifactId>sal-remote</artifactId>
<version>${mdsal.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-rest-connector</artifactId>
<artifactId>sample-toaster-provider</artifactId>
<version>${mdsal.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller.thirdparty</groupId>
<artifactId>com.sun.jersey.jersey-servlet</artifactId>
public interface ConfigSnapshotHolder {
/**
- * Get part of get-config document that contains just
+ * Get XML node that should be pushed to netconf's edit-config
*/
String getConfigSnapshot();
/**
* Get only required capabilities referenced by the snapshot.
+ * If no value is specified, return empty set instead of null
*/
SortedSet<String> getCapabilities();
*/
package org.opendaylight.controller.config.persist.storage.file.xml.model;
+import java.util.TreeSet;
import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
import javax.xml.bind.annotation.XmlAnyElement;
public static final String SNAPSHOT_ROOT_ELEMENT_NAME = "snapshot";
private String configSnapshot;
- private SortedSet<String> capabilities;
+ private SortedSet<String> capabilities = new TreeSet<>();
ConfigSnapshot(String configXml, SortedSet<String> capabilities) {
this.configSnapshot = configXml;
*/
package org.opendaylight.controller.config.yangjmxgenerator.plugin.gofactory;
+import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import com.google.common.base.Joiner;
"}\n", moduleField.getName(), osgi);
} else {
str = format(
- "%1$sDependency = dependencyResolver.resolveInstance(%2$s.class, %1$s, %1$sJmxAttribute);",
+ "%1$sDependency = dependencyResolver.resolveInstance(%2$s.class, %1$s, %1$sJmxAttribute);\n",
moduleField.getName(), osgi);
}
resolveDependenciesMap.put(moduleField, str);
// wrap each field resolvation statement with if !=null when dependency is not mandatory
for (Map.Entry<ModuleField, String> entry : resolveDependenciesMap.entrySet()) {
if (entry.getKey().getDependency().isMandatory() == false) {
- result += format("if (%s!=null) {\n%s;\n}", entry.getKey().getName(), entry.getValue());
+ checkState(entry.getValue().endsWith(";\n"));
+ result += format("if (%s!=null) {\n%s}\n", entry.getKey().getName(), entry.getValue());
} else {
result += entry.getValue();
}
parameters.put(ModuleIdentifier.class.getCanonicalName(), "identifier");
parameters.put(DependencyResolver.class.getCanonicalName(), "dependencyResolver");
- String setToNulls = "this.oldInstance=null;\n;" +
+ String setToNulls = "this.oldInstance=null;\n" +
"this.oldModule=null;\n";
return getConstructorStart(abstractFQN, parameters, setToNulls);
}
<type>xml</type>
<scope>runtime</scope>
</dependency>
- <!-- scope is compile so all features (there is only one) are installed
- into startup.properties and the feature repo itself is not installed -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>base-features</artifactId>
<version>${project.version}</version>
- <type>pom</type>
+ <type>kar</type>
<scope>runtime</scope>
</dependency>
<dependency>
# Extra packages to import from the boot class loader
org.osgi.framework.system.packages.extra=org.apache.karaf.branding,sun.reflect,sun.reflect.misc,sun.misc,sun.nio.ch
+# https://bugs.eclipse.org/bugs/show_bug.cgi?id=325578
+# Extend the framework to avoid the resources to be presented with
+# a URL of type bundleresource: but to be presented as file:
+osgi.hook.configurators.include=org.eclipse.virgo.kernel.equinox.extensions.hooks.ExtensionsHookConfigurator
# Embedded Tomcat configuration File
org.eclipse.gemini.web.tomcat.config.path=configuration/tomcat-server.xml
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true
+# Use Equinox as default OSGi Framework Implementation
+karaf.framework=equinox
# Netconf startup configuration
netconf.tcp.address=127.0.0.1
mvn\:org.ops4j.pax.url/pax-url-maven-commons/1.6.0 = 5
mvn\:org.ops4j.pax.url/pax-url-aether/1.6.0 = 5
mvn\:org.ops4j.pax.url/pax-url-wrap/1.6.0 = 5
-#mvn\:javax.annotation/javax.annotation-api/1.2 = 5
+mvn\:javax.annotation/javax.annotation-api/1.2 = 5
mvn\:org.ops4j.pax.logging/pax-logging-api/1.7.2 = 8
mvn\:org.ops4j.pax.logging/pax-logging-service/1.7.2 = 8
mvn\:org.apache.karaf.service/org.apache.karaf.service.guard/3.0.1 = 10
<artifactId>protocol-framework</artifactId>
</dependency>
- <!-- clustering -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <version>${mdsal.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-binding-api</artifactId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-remote</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-rest-connector</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ 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
+-->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ <!-- Netconf dispatcher to be used by all netconf-connectors -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
+ <name>global-netconf-dispatcher</name>
+ <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+ <name>global-boss-group</name>
+ </boss-thread-group>
+ <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
+ <name>global-worker-group</name>
+ </worker-thread-group>
+ <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
+ <name>global-timer</name>
+ </timer>
+ </module>
+
+ <!-- Thread factory to be used by all threadpools in netconf-connectors -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
+ <name>global-netconf-processing-executor-threadfactory</name>
+ <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
+ </module>
+ <!-- Flexible threadpool for all netconf connectors, Max thread count is set to 4 -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">prefix:threadpool-flexible</type>
+ <name>global-netconf-processing-executor</name>
+ <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1</minThreadCount>
+ <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4</max-thread-count>
+ <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000</keepAliveMillis>
+ <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
+ <name>global-netconf-processing-executor-threadfactory</name>
+ </threadFactory>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
+ <instance>
+ <name>global-netconf-dispatcher</name>
+ <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
+ <instance>
+ <name>global-netconf-processing-executor-threadfactory</name>
+ <provider>/modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
+ <instance>
+ <name>global-netconf-processing-executor</name>
+ <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
+ </instance>
+ </service>
+ </services>
+
+ </data>
+ </configuration>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher?module=odl-netconfig-client-cfg&revision=2014-04-08</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:threadpool:impl:flexible?module=threadpool-impl-flexible&revision=2013-12-01</capability>
+ </required-capabilities>
+</snapshot>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- 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
--->
-<snapshot>
- <configuration>
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <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>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- <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">
- </services>
- </data>
- </configuration>
-
- <required-capabilities>
- <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:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28</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:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28</capability>
- </required-capabilities>
-</snapshot>
-
<configuration>
<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
-
- <!-- Netconf dispatcher to be used by all netconf-connectors -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">prefix:netconf-client-dispatcher</type>
- <name>global-netconf-dispatcher</name>
- <boss-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-boss-group</name>
- </boss-thread-group>
- <worker-thread-group xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-threadgroup</type>
- <name>global-worker-group</name>
- </worker-thread-group>
- <timer xmlns="urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:netty">prefix:netty-timer</type>
- <name>global-timer</name>
- </timer>
- </module>
-
- <!-- Netconf dispatcher to be used by all netconf-connectors -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">prefix:threadfactory-naming</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- <name-prefix xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl">remote-connector-processing-executor</name-prefix>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">prefix:threadpool-flexible</type>
- <name>global-netconf-processing-executor</name>
- <minThreadCount xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">1</minThreadCount>
- <max-thread-count xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">4</max-thread-count>
- <keepAliveMillis xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">600000</keepAliveMillis>
- <threadFactory xmlns="urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl:flexible">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <name>global-netconf-processing-executor-threadfactory</name>
- </threadFactory>
- </module>
-
<!-- Loopback connection to netconf server in controller using netconf-connector -->
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf">prefix:sal-netconf-connector</type>
</processing-executor>
</module>
</modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:netconf">prefix:netconf-client-dispatcher</type>
- <instance>
- <name>global-netconf-dispatcher</name>
- <provider>/modules/module[type='netconf-client-dispatcher'][name='global-netconf-dispatcher']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadfactory</type>
- <instance>
- <name>global-netconf-processing-executor-threadfactory</name>
- <provider>/modules/module[type='threadfactory-naming'][name='global-netconf-processing-executor-threadfactory']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:threadpool">prefix:threadpool</type>
- <instance>
- <name>global-netconf-processing-executor</name>
- <provider>/modules/module[type='threadpool-flexible'][name='global-netconf-processing-executor']</provider>
- </instance>
- </service>
- </services>
-
</data>
</configuration>
<required-capabilities>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:connector:netconf?module=odl-sal-netconf-connector-cfg&revision=2013-10-28</capability>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:netconf:client:dispatcher?module=odl-netconfig-client-cfg&revision=2014-04-08</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:threadpool:impl:flexible?module=threadpool-impl-flexible&revision=2013-12-01</capability>
</required-capabilities>
</snapshot>
@Override
protected void init() {
+ // TODO: deprecated, should be removed soon
NodeIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class);
NodeConnectorIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class, NodeMapping.MD_SAL_TYPE);
}
private Dictionary<String,Object> properties() {
final Hashtable<String,Object> props = new Hashtable<String, Object>();
- props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), NodeMapping.MD_SAL_TYPE);
- props.put("protocolName", NodeMapping.MD_SAL_TYPE);
+ props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), NodeIDType.OPENFLOW);
+ props.put("protocolName", NodeIDType.OPENFLOW);
return props;
}
}
flowId = UUID.randomUUID();
cache.put(flow, flowId);
- return this.writeFlowAsync(MDFlowMapping.toMDFlow(flow, flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ return this.writeFlowAsync(MDFlowMapping.toMDFlow(flow, flowId.toString()), new NodeKey(
+ new NodeId(NodeMapping.OPENFLOW_ID_PREFIX + node.getID())));
}
private Future<RpcResult<TransactionStatus>> internalModifyFlowAsync(final Node node, final Flow oldFlow, final Flow newFlow, final long rid) {
}
cache.put(newFlow, flowId);
- return this.writeFlowAsync(MDFlowMapping.toMDFlow(newFlow, flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ return this.writeFlowAsync(MDFlowMapping.toMDFlow(newFlow, flowId.toString()), new NodeKey(
+ new NodeId(NodeMapping.OPENFLOW_ID_PREFIX + node.getID())));
}
private Future<RpcResult<TransactionStatus>> internalRemoveFlowAsync(final Node node, final Flow adflow, final long rid) {
final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow = MDFlowMapping.toMDFlow(adflow, flowId.toString());
final DataModificationTransaction modification = this.dataBrokerService.beginTransaction();
- modification.removeConfigurationData(flowPath(flow, new NodeKey(new NodeId(node.getNodeIDString()))));
+ modification.removeConfigurationData(flowPath(flow, new NodeKey(
+ new NodeId(NodeMapping.OPENFLOW_ID_PREFIX + node.getID()))));
return modification.commit();
}
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.NodeTable;
+import org.opendaylight.controller.sal.core.NodeTable.NodeTableIDType;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.inventory.IPluginInInventoryService;
}
try {
- final Node adNode = new Node(NodeMapping.MD_SAL_TYPE, NodeMapping.toADNodeId(node.getId()));
+ final Node adNode = NodeMapping.toADNode(node.getId());
props.put(adNode, perNodePropMap);
} catch (ConstructionException e) {
LOG.warn("Failed to construct node for {}, skipping it", node, e);
it.setLookupCount(tableStats.getPacketsLookedUp().getValue().longValue());
it.setMatchedCount(tableStats.getPacketsMatched().getValue().longValue());
it.setName(tableId.toString());
- it.setNodeTable(new NodeTable(NodeMapping.MD_SAL_TYPE, tableId, node));
+ it.setNodeTable(new NodeTable(NodeTableIDType.OPENFLOW, tableId.byteValue(), node));
return it;
}
}
public static Uri toUri(final NodeConnector connector) {
- return new NodeConnectorId(((String) connector.getID()));
+ return new NodeConnectorId(NodeMapping.OPENFLOW_ID_PREFIX + connector.getNode().getID() + ":" + (connector.getID()));
}
public static MacAddress toMacAddress(final byte[] bytes) {
import java.util.Date;
import java.util.HashSet;
import java.util.List;
-
import org.opendaylight.controller.sal.common.util.Arguments;
import org.opendaylight.controller.sal.core.AdvertisedBandwidth;
import org.opendaylight.controller.sal.core.Bandwidth;
import org.opendaylight.controller.sal.core.Capabilities;
import org.opendaylight.controller.sal.core.Config;
import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Description;
import org.opendaylight.controller.sal.core.MacAddress;
import org.opendaylight.controller.sal.core.Name;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
import org.opendaylight.controller.sal.core.PeerBandwidth;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortFeatures;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.flow.capable.port.State;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorUpdated;
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.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
public final class NodeMapping {
- public final static String MD_SAL_TYPE = "MD_SAL";
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(NodeMapping.class);
+
+ /** openflow id prefix */
+ public static final String OPENFLOW_ID_PREFIX = "openflow:";
+
+ public final static String MD_SAL_TYPE = "MD_SAL_DEPRECATED";
private final static Class<Node> NODE_CLASS = Node.class;
}
public static org.opendaylight.controller.sal.core.Node toADNode(final NodeId id) throws ConstructionException {
- String aDNodeId = NodeMapping.toADNodeId(id);
- return new org.opendaylight.controller.sal.core.Node(NodeMapping.MD_SAL_TYPE, aDNodeId);
+ Long aDNodeId = openflowFullNodeIdToLong(NodeMapping.toADNodeId(id));
+ return new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, aDNodeId);
+ }
+
+ /**
+ * @param adNodeId
+ * @return
+ */
+ private static Long openflowFullNodeIdToLong(String adNodeId) {
+ if (adNodeId == null) {
+ return null;
+ }
+ return Long.valueOf(adNodeId.replaceFirst("^.*:", ""));
}
public static NodeId toNodeId(final InstanceIdentifier<?> id) {
return key.getId();
}
+ /**
+ * @param nodeId containing "<NodeTypeString>:<plainIntegerId>"
+ * @return adNodeId form
+ */
public static String toADNodeId(final NodeId nodeId) {
+ if (nodeId == null) {
+ return null;
+ }
return nodeId.getValue();
}
return new org.opendaylight.controller.sal.core.NodeConnector(nodeConnectorType, aDNodeConnectorId, aDNode);
}
+ /**
+ * @param ncid nodeConnector identifier, e.g.: OF:21 or CTRL
+ * @param node
+ * @return nodeConnector attached to given node
+ * @throws ConstructionException
+ */
+ public static org.opendaylight.controller.sal.core.NodeConnector toADNodeConnector(
+ final NodeConnectorId ncid, final org.opendaylight.controller.sal.core.Node aDNode) throws ConstructionException {
+ NodeId nid = NodeMapping.toNodeId(aDNode);
+ String nodeConnectorType = NodeMapping.toNodeConnectorType(ncid, nid);
+ Object aDNodeConnectorId = NodeMapping.toADNodeConnectorId(ncid, nid);
+ return new org.opendaylight.controller.sal.core.NodeConnector(nodeConnectorType, aDNodeConnectorId, aDNode);
+ }
+
+ /**
+ * @param aDNode
+ * @return
+ */
+ private static NodeId toNodeId(org.opendaylight.controller.sal.core.Node aDNode) {
+ return new NodeId(aDNode.getType() + ":" +String.valueOf(aDNode.getID()));
+ }
+
public static String toNodeConnectorType(final NodeConnectorId ncId, final NodeId nodeId) {
if (ncId.equals(toLocalNodeConnectorId(nodeId))) {
return NodeConnectorIDType.SWSTACK;
} else if (ncId.equals(toControllerNodeConnectorId(nodeId))) {
return NodeConnectorIDType.CONTROLLER;
}
- return MD_SAL_TYPE;
+ return NodeConnectorIDType.OPENFLOW;
}
public static Object toADNodeConnectorId(final NodeConnectorId nodeConnectorId, final NodeId nodeId) {
nodeConnectorId.equals(toControllerNodeConnectorId(nodeId))) {
return org.opendaylight.controller.sal.core.NodeConnector.SPECIALNODECONNECTORID;
}
- return nodeConnectorId.getValue();
+
+ String nodeConnectorIdStripped = nodeConnectorId.getValue().replaceFirst("^.*:", "");
+ if (nodeConnectorIdStripped.matches("[0-9]+")) {
+ Short nodeConnectorIdVal = null;
+ try {
+ nodeConnectorIdVal = Short.valueOf(nodeConnectorIdStripped);
+ } catch (NumberFormatException e) {
+ LOG.warn("nodeConnectorId not supported (short): {}", nodeConnectorIdStripped, e);
+ }
+ return nodeConnectorIdVal;
+ }
+ return nodeConnectorIdStripped;
}
public static NodeId toAdNodeId(final NodeConnectorId nodeConnectorId) {
}
public static NodeConnectorId toControllerNodeConnectorId(final NodeId node) {
- return new NodeConnectorId(node.getValue() + ":" + 4294967293L);
+ return new NodeConnectorId(node.getValue() + ":" + OutputPortValues.CONTROLLER.toString());
}
public static NodeConnectorId toLocalNodeConnectorId(final NodeId node) {
- return new NodeConnectorId(node.getValue() + ":" + 4294967294L);
+ return new NodeConnectorId(node.getValue() + ":" + OutputPortValues.LOCAL.toString());
}
public static NodeConnectorId toNormalNodeConnectorId(final NodeId node) {
- return new NodeConnectorId(node.getValue() + ":" + 4294967290L);
+ return new NodeConnectorId(node.getValue() + ":" + OutputPortValues.NORMAL.toString());
}
public static NodeRef toNodeRef(final org.opendaylight.controller.sal.core.Node node) {
- Preconditions.checkArgument(MD_SAL_TYPE.equals(node.getType()));
- final String nodeId = Arguments.<String>checkInstanceOf(node.getID(), String.class);
- final NodeKey nodeKey = new NodeKey(new NodeId(nodeId));
+ Preconditions.checkArgument(NodeIDType.OPENFLOW.equals(node.getType()));
+ final Long nodeId = Arguments.<Long>checkInstanceOf(node.getID(), Long.class);
+ final NodeKey nodeKey = new NodeKey(new NodeId(OPENFLOW_ID_PREFIX+nodeId));
final InstanceIdentifier<Node> nodePath = InstanceIdentifier.builder(Nodes.class).child(NODE_CLASS, nodeKey).toInstance();
return new NodeRef(nodePath);
}
nodeConnectorId = toControllerNodeConnectorId(nodeId);
}
} else {
- nodeConnectorId = new NodeConnectorId(Arguments.<String>checkInstanceOf(nodeConnector.getID(), String.class));
+ nodeConnectorId = new NodeConnectorId(OPENFLOW_ID_PREFIX
+ + Arguments.<Short>checkInstanceOf(nodeConnector.getID(), Short.class));
}
final NodeConnectorKey connectorKey = new NodeConnectorKey(nodeConnectorId);
final InstanceIdentifier<NodeConnector> path = nodePath.child(NODECONNECTOR_CLASS, connectorKey);
public static HashSet<Property> toADNodeConnectorProperties(final NodeConnectorUpdated nc) {
final FlowCapableNodeConnectorUpdated fcncu = nc.<FlowCapableNodeConnectorUpdated>getAugmentation(FlowCapableNodeConnectorUpdated.class);
if (!Objects.equal(fcncu, null)) {
- return NodeMapping.toADNodeConnectorProperties(fcncu);
+ HashSet<Property> adNodeConnectorProperties = NodeMapping.toADNodeConnectorProperties(fcncu);
+ return adNodeConnectorProperties;
}
return new HashSet<Property>();
}
+ /**
+ * @param id
+ * @return node description in AD form, e.g.: OF|00:00:00:...:01
+ */
+ private static Description toADDescription(NodeRef nodeRef) {
+ Description desc;
+ try {
+ desc = new Description(toADNode(nodeRef).toString());
+ } catch (ConstructionException e) {
+ desc = new Description("none");
+ LOG.warn("node description extraction failed: {}", nodeRef);
+ }
+ return desc;
+ }
+
public static HashSet<Property> toADNodeConnectorProperties(final NodeConnector nc) {
final FlowCapableNodeConnector fcnc = nc.<FlowCapableNodeConnector>getAugmentation(FlowCapableNodeConnector.class);
if (!Objects.equal(fcnc, null)) {
public static HashSet<Property> toADNodeProperties(final NodeUpdated nu) {
final FlowCapableNodeUpdated fcnu = nu.getAugmentation(FlowCapableNodeUpdated.class);
if (fcnu != null) {
- return toADNodeProperties(fcnu, nu.getId());
+ HashSet<Property> adNodeProperties = toADNodeProperties(fcnu, nu.getId());
+ adNodeProperties.add(toADDescription(nu.getNodeRef()));
+ return adNodeProperties;
}
return new HashSet<org.opendaylight.controller.sal.core.Property>();
}
}
public static MacAddress toADMacAddress(final NodeId id) {
- final String nodeId = id.getValue().replaceAll("openflow:", "");
+ final String nodeId = id.getValue().replaceAll(OPENFLOW_ID_PREFIX, "");
BigInteger nodeIdRaw = new BigInteger(nodeId);
long lNodeId = nodeIdRaw.longValue();
byte[] bytesFromDpid = ToSalConversionsUtils.bytesFromDpid(lNodeId);
Uri nodeConnector = ((OutputActionCase) sourceAction).getOutputAction().getOutputNodeConnector();
if (nodeConnector != null) {
//for (Uri uri : nodeConnectors) {
- targetAction.add(new Output(fromNodeConnectorRef(nodeConnector, node)));
+ Uri fullNodeConnector = new Uri(node.getType()+":"+node.getID()+":"+nodeConnector.getValue());
+ targetAction.add(new Output(fromNodeConnectorRef(fullNodeConnector, node)));
//}
}
} else if (sourceAction instanceof PopMplsActionCase) {
return null;
}
- private static NodeConnector fromNodeConnectorRef(Uri uri, Node node) {
+ /**
+ * @param openflow nodeConnector uri
+ * @param node
+ * @return assembled nodeConnector
+ */
+ public static NodeConnector fromNodeConnectorRef(Uri uri, Node node) {
NodeConnector nodeConnector = null;
try {
- nodeConnector = new NodeConnector(NodeMapping.MD_SAL_TYPE,node.getNodeIDString()+":"+uri.getValue(),node);
+ NodeConnectorId nodeConnectorId = new NodeConnectorId(uri.getValue());
+ nodeConnector = NodeMapping.toADNodeConnector(nodeConnectorId, node);
} catch (ConstructionException e) {
- e.printStackTrace();
+ LOG.warn("nodeConnector creation failed at node: {} with nodeConnectorUri: {}",
+ node, uri.getValue());
}
return nodeConnector;
}
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.Edge;
import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.UpdateType;
import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
}
public static String toADNodeId(final NodeId nodeId) {
- return nodeId.getValue();
+ return nodeId.getValue().replaceFirst("^.*:", "");
}
public static NodeConnector toADNodeConnector(final TpId source, final NodeId nodeId) throws ConstructionException {
checkNotNull(source);
- return new NodeConnector(NodeMapping.MD_SAL_TYPE, toADNodeConnectorId(source), toADNode(nodeId));
+ return new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf(toADNodeConnectorId(source)), toADNode(nodeId));
}
public static String toADNodeConnectorId(final TpId nodeConnectorId) {
- return nodeConnectorId.getValue();
+ return nodeConnectorId.getValue().replaceFirst("^.*:", "");
}
public static Node toADNode(final NodeId nodeId) throws ConstructionException {
checkNotNull(nodeId);
- return new Node(NodeMapping.MD_SAL_TYPE, toADNodeId(nodeId));
+ return new Node(NodeIDType.OPENFLOW, Long.valueOf(toADNodeId(nodeId)));
}
}
--- /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.compatibility.test;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+
+/**
+ * test for {@link MDFlowMapping}
+ */
+public class MDFlowMappingTest {
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.MDFlowMapping#toUri(org.opendaylight.controller.sal.core.NodeConnector)}.
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToUri() throws ConstructionException {
+ Node node = new Node(NodeIDType.OPENFLOW, 41L);
+ NodeConnector connector = new NodeConnector(NodeConnectorIDType.OPENFLOW, (short) 42, node);
+ Uri observed = MDFlowMapping.toUri(connector );
+
+ Assert.assertEquals("openflow:41:42", observed.getValue());
+ }
+
+}
import org.junit.Assert;
import org.junit.Test;
import org.opendaylight.controller.sal.compatibility.NodeMapping;
+import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.MacAddress;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
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.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.yangtools.yang.binding.InstanceIdentifier;
/**
* test of {@link NodeMapping} utility class
observed = NodeMapping.toAdNodeId(null);
Assert.assertNull(observed);
- observed = NodeMapping.toAdNodeId(new NodeConnectorId("MD_SAL|openflow:5:2"));
- Assert.assertEquals("MD_SAL|openflow:5", observed.getValue());
+ observed = NodeMapping.toAdNodeId(new NodeConnectorId("openflow:5:2"));
+ Assert.assertEquals("openflow:5", observed.getValue());
}
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toADNode(NodeId)}
+ * .
+ */
+ @Test
+ public void testToAdNode1() {
+ org.opendaylight.controller.sal.core.Node observed;
+ try {
+ observed = NodeMapping.toADNode((NodeId) null);
+ } catch (NullPointerException | ConstructionException e) {
+ //expected
+ }
+
+ NodeId nodeId = new NodeId("openflow:1");
+ try {
+ observed = NodeMapping.toADNode(nodeId);
+ Assert.assertEquals("OF|00:00:00:00:00:00:00:01", observed.toString());
+ } catch (ConstructionException e) {
+ Assert.fail("should succeed to construct Node: "+e.getMessage());
+ }
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toNodeConnectorType(NodeConnectorId, NodeId)}
+ * .
+ */
+ @Test
+ public void testToNodeConnectorType() {
+ NodeConnectorId ncId;
+ NodeId nodeId = buildNodeId("1");
+
+ ncId = buildNodeConnectorId("1", "42");
+ Assert.assertEquals(NodeConnectorIDType.OPENFLOW, NodeMapping.toNodeConnectorType(ncId, nodeId ));
+
+ ncId = buildNodeConnectorId("1", OutputPortValues.CONTROLLER.toString());
+ Assert.assertEquals(NodeConnectorIDType.CONTROLLER, NodeMapping.toNodeConnectorType(ncId, nodeId ));
+
+ ncId = buildNodeConnectorId("1", OutputPortValues.NORMAL.toString());
+ Assert.assertEquals(NodeConnectorIDType.HWPATH, NodeMapping.toNodeConnectorType(ncId, nodeId ));
+
+ ncId = buildNodeConnectorId("1", OutputPortValues.LOCAL.toString());
+ Assert.assertEquals(NodeConnectorIDType.SWSTACK, NodeMapping.toNodeConnectorType(ncId, nodeId ));
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toADNodeConnectorId(NodeConnectorId, NodeId)}
+ * .
+ */
+ @Test
+ public void testToAdNodeConnectorId() {
+ NodeConnectorId nodeConnectorId = buildNodeConnectorId("1", "2");
+ NodeId nodeId = buildNodeId("1");
+ Assert.assertEquals(Short.valueOf((short) 2), NodeMapping.toADNodeConnectorId(nodeConnectorId , nodeId));
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toNodeRef(Node)}
+ * .
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToNodeRef() throws ConstructionException {
+ org.opendaylight.controller.sal.core.Node node = new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, 42L);
+ InstanceIdentifier<?> nodePath = NodeMapping.toNodeRef(node).getValue();
+
+ String observedId = nodePath.firstKeyOf(Node.class, NodeKey.class).getId().getValue();
+ Assert.assertEquals("openflow:42", observedId);
+ }
+
+ /**
+ * Test method for
+ * {@link org.opendaylight.controller.sal.compatibility.NodeMapping#toNodeConnectorRef(org.opendaylight.controller.sal.core.NodeConnector)}
+ * .
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToNodeConnectorRef() throws ConstructionException {
+ org.opendaylight.controller.sal.core.Node node = new org.opendaylight.controller.sal.core.Node(NodeIDType.OPENFLOW, 42L);
+ org.opendaylight.controller.sal.core.NodeConnector nodeConnector =
+ new org.opendaylight.controller.sal.core.NodeConnector(
+ NodeConnectorIDType.OPENFLOW, (short) 1, node);
+
+ InstanceIdentifier<?> nodeConnectorPath = NodeMapping.toNodeConnectorRef(nodeConnector ).getValue();
+ String observedNodeId = nodeConnectorPath.firstKeyOf(Node.class, NodeKey.class).getId().getValue();
+ Assert.assertEquals("openflow:42", observedNodeId);
+
+ String observedNodeConnectorId = nodeConnectorPath.firstKeyOf(NodeConnector.class, NodeConnectorKey.class).getId().getValue();
+ Assert.assertEquals("openflow:1", observedNodeConnectorId);
+ }
+
+ /**
+ * @param nodeId
+ * @param portId
+ * @return nodeConnectorId
+ */
+ public static NodeConnectorId buildNodeConnectorId(String nodeId, String portId) {
+ return new NodeConnectorId(NodeConnectorIDType.OPENFLOW+"|" + nodeId + ":" + portId);
+ }
+
+ /**
+ * @param id
+ * @return nodeId
+ */
+ public static NodeId buildNodeId(String id) {
+ return new NodeId(NodeConnectorIDType.OPENFLOW+"|" + id);
+ }
}
import java.util.Collections;
import java.util.List;
+import junit.framework.Assert;
+
import org.junit.Test;
import org.opendaylight.controller.sal.action.Flood;
import org.opendaylight.controller.sal.action.FloodAll;
import org.opendaylight.controller.sal.core.ConstructionException;
import org.opendaylight.controller.sal.core.Node;
import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.flowprogrammer.Flow;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
checkSalFlow(salFlow);
}
+ /**
+ * test of {@link ToSalConversionsUtils#fromNodeConnectorRef(Uri, Node)}
+ * @throws ConstructionException
+ */
+ @Test
+ public void testFromNodeConnectorRef() throws ConstructionException {
+ Node node = new Node(NodeIDType.OPENFLOW, 42L);
+ NodeConnector nodeConnector = ToSalConversionsUtils.fromNodeConnectorRef(new Uri("1"), node);
+ Assert.assertEquals("OF|1@OF|00:00:00:00:00:00:00:2a", nodeConnector.toString());
+ }
+
private void checkSalMatch(org.opendaylight.controller.sal.match.Match match, MtchType mt) {
switch (mt) {
case other:
--- /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.compatibility.topology.test;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+import org.opendaylight.controller.sal.compatibility.topology.TopologyMapping;
+import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+
+/**
+ * test for {@link TopologyMapping}
+ */
+public class TopologyMappingTest {
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.topology.TopologyMapping#toADNodeId(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)}.
+ */
+ @Test
+ public void testToADNodeId() {
+ NodeId nodeId = new NodeId("openflow:1");
+ String observedNodeId = TopologyMapping.toADNodeId(nodeId);
+
+ Assert.assertEquals("1", observedNodeId);
+ }
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.topology.TopologyMapping#toADNodeConnector(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId, org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)}.
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToADNodeConnector() throws ConstructionException {
+ NodeId nodeId = new NodeId("openflow:1");
+ TpId source = new TpId("foo:2");
+ NodeConnector observedNodeConnector = TopologyMapping.toADNodeConnector(source, nodeId);
+
+ Assert.assertEquals("OF|2@OF|00:00:00:00:00:00:00:01", observedNodeConnector.toString());
+ }
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.topology.TopologyMapping#toADNodeConnectorId(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId)}.
+ */
+ @Test
+ public void testToADNodeConnectorId() {
+ TpId source = new TpId("foo:2");
+ String observedNodeConnectorId = TopologyMapping.toADNodeConnectorId(source);
+
+ Assert.assertEquals("2", observedNodeConnectorId);
+ }
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.topology.TopologyMapping#toADNode(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId)}.
+ * @throws ConstructionException
+ */
+ @Test
+ public void testToADNode() throws ConstructionException {
+ NodeId nodeId = new NodeId("openflow:1");
+ Node observedNode = TopologyMapping.toADNode(nodeId);
+
+ Assert.assertEquals("OF|00:00:00:00:00:00:00:01", observedNode.toString());
+ }
+
+}
}
}
+ grouping "tunnel-ipv4-match-fields" {
+ leaf tunnel-ipv4-source {
+ description "IPv4 source tunnel endpoint address.";
+ type inet:ipv4-prefix;
+ }
+ leaf tunnel-ipv4-destination {
+ description "IPv4 destination tunnel endpoint address.";
+ type inet:ipv4-prefix;
+ }
+ }
+
grouping match {
leaf in-port {
type inv:node-connector-id;
case "arp-match" {
uses "arp-match-fields";
}
+ case "tunnel-ipv4-match" {
+ uses "tunnel-ipv4-match-fields";
+ }
}
choice layer-4-match {
grouping common-port {
leaf port-number {
- type uint32;
+ type union {
+ type uint32;
+ type string;
+ }
}
leaf hardware-address {
base match-field;
description "TCP Flag Match";
}
+ identity tunnel_ipv4_dst {
+ base match-field;
+ description "IPv4 destination tunnel endpoint address.";
+ }
+ identity tunnel_ipv4_src {
+ base match-field;
+ description "IPv4 source tunnel endpoint address.";
+ }
grouping set-field-match {
list set-field-match {
<!-- Compability Packages -->
<module>compatibility</module>
- <!-- Clustering -->
- <module>remoterpc-routingtable/implementation</module>
- <module>sal-remoterpc-connector/implementation</module>
<!-- Documentation -->
<module>sal-rest-docgen</module>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
-
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <packaging>bundle</packaging>
- <dependencies>
-
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- <version>${clustering.services.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-connector-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>org.opendaylight.controller.sal.connector.remoterpc.api,
- org.opendaylight.controller.sal.connector.remoterpc.impl</Export-Package>
- <Import-Package>javax.xml.bind.annotation,
- org.opendaylight.controller.sal.core,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.controller.sal.packet,
- org.opendaylight.controller.sal.topology,
- org.opendaylight.controller.clustering.services,
- org.opendaylight.controller.md.sal.common.api.data,
- org.opendaylight.yangtools.yang.binding,
- org.osgi.service.component,
- org.slf4j,
- org.apache.felix.dm,
- org.apache.commons.lang3.builder,
- org.apache.commons.lang3.tuple,
- org.eclipse.osgi.framework.console,
- org.osgi.framework,
- javax.transaction,
- com.google.common.base,
- com.google.common.collect</Import-Package>
- <Bundle-Activator>org.opendaylight.controller.sal.connector.remoterpc.impl.Activator</Bundle-Activator>
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
- </scm>
-</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.connector.remoterpc.api;
-
-import java.util.EventListener;
-
-public interface RouteChangeListener<I,R> extends EventListener {
-
-
- void onRouteUpdated(I key, R new_value);
-
- void onRouteDeleted(I key);
-}
+++ /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.api;
-
-import java.util.Set;
-
-public interface RoutingTable<I,R> {
-
- /**
- * Adds a network address for the route. If the route already exists,
- * it throws <code>DuplicateRouteException</code>.
- * This method would be used when registering a global service.
- *
- *
- * @param routeId route identifier
- * @param route network address
- * @throws DuplicateRouteException
- * @throws RoutingTableException
- */
- public void addGlobalRoute(I routeId, R route) throws RoutingTableException, SystemException;
-
- /**
- * Remove the route.
- * This method would be used when registering a global service.
- * @param routeId
- * @throws RoutingTableException
- * @throws SystemException
- */
- public void removeGlobalRoute(I routeId) throws RoutingTableException, SystemException;
-
- /**
- * Adds a network address for the route. If the route already exists,
- * it throws <code>DuplicateRouteException</code>.
- * This method would be used when registering a global service.
- *
- *
- * @param routeId route identifier
- * @param route network address
- * @throws DuplicateRouteException
- * @throws RoutingTableException
- */
- public R getGlobalRoute(I routeId) throws RoutingTableException, SystemException;
-
- /**
- * Adds a network address for the route. If address for route
- * exists, appends the address to the list
- *
- * @param routeId route identifier
- * @param route network address
- * @throws RoutingTableException for any logical exception
- * @throws SystemException
- */
- public void addRoute(I routeId, R route) throws RoutingTableException,SystemException;
-
-
- /**
- * Removes the network address for the route from routing table. If only
- * one network address existed, remove the route as well.
- * @param routeId
- * @param route
- */
- public void removeRoute(I routeId, R route) throws RoutingTableException,SystemException;
-
- /**
- * Adds address for a set of route identifiers. If address for route
- * exists, appends the address to the set.
- *
- * @param routeIds a set of routeIds
- * @param route network address
- * @throws RoutingTableException for any logical exception
- * @throws SystemException
- */
- public void addRoutes(Set<I> routeIds, R route) throws RoutingTableException,SystemException;
-
- /**
- * Removes address for a set of route identifiers.
- *
- * @param routeIds a set of routeIds
- * @param route network address
- * @throws RoutingTableException for any logical exception
- * @throws SystemException
- */
- public void removeRoutes(Set<I> routeIds, R route) throws RoutingTableException,SystemException;
-
- /**
- * Returns a set of network addresses associated with this route
- * @param routeId
- * @return
- */
- public Set<R> getRoutes(I routeId);
-
-
- /**
- * Returns the last inserted address from the list of network addresses
- * associated with the route.
- * @param routeId
- * @return
- */
- public R getLastAddedRoute(I routeId);
-
- public class DuplicateRouteException extends RoutingTableException {
- public DuplicateRouteException(String message) {
- super(message);
- }
-
- }
-
-}
+++ /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.api;
-
-/**
- * @author: syedbahm
- */
-public class RoutingTableException extends Exception {
-
- /**
- * Constructs a new exception with {@code null} as its detail message.
- * The cause is not initialized, and may subsequently be initialized by a
- * call to {@link #initCause}.
- */
- public RoutingTableException() {
- super();
- }
-
- /**
- * Constructs a new exception with the specified detail message. The
- * cause is not initialized, and may subsequently be initialized by
- * a call to {@link #initCause}.
- *
- * @param message the detail message. The detail message is saved for
- * later retrieval by the {@link #getMessage()} method.
- */
- public RoutingTableException(String message) {
- super(message);
- }
-
- /**
- * Constructs a new exception with the specified detail message and
- * cause. <p>Note that the detail message associated with
- * {@code cause} is <i>not</i> automatically incorporated in
- * this exception's detail message.
- *
- * @param message the detail message (which is saved for later retrieval
- * by the {@link #getMessage()} method).
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
- */
- public RoutingTableException(String message, Throwable cause) {
- super(message, cause);
- }
-}
+++ /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.api;
-
-/**
- * @author: syedbahm
- *
- */
-public class SystemException extends Exception {
- /**
- * Constructs a new exception with {@code null} as its detail message.
- * The cause is not initialized, and may subsequently be initialized by a
- * call to {@link #initCause}.
- */
- public SystemException() {
- super();
- }
-
- /**
- * Constructs a new exception with the specified detail message. The
- * cause is not initialized, and may subsequently be initialized by
- * a call to {@link #initCause}.
- *
- * @param message the detail message. The detail message is saved for
- * later retrieval by the {@link #getMessage()} method.
- */
- public SystemException(String message) {
- super(message);
- }
-
- /**
- * Constructs a new exception with the specified detail message and
- * cause. <p>Note that the detail message associated with
- * {@code cause} is <i>not</i> automatically incorporated in
- * this exception's detail message.
- *
- * @param message the detail message (which is saved for later retrieval
- * by the {@link #getMessage()} method).
- * @param cause the cause (which is saved for later retrieval by the
- * {@link #getCause()} method). (A <tt>null</tt> value is
- * permitted, and indicates that the cause is nonexistent or
- * unknown.)
- * @since 1.4
- */
- public SystemException(String message, Throwable cause) {
- super(message, cause);
- }
-}
+++ /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.impl;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
-import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Set;
-
-/**
- * @author: syedbahm
- */
-public class Activator extends ComponentActivatorAbstractBase {
-
- protected static final Logger logger = LoggerFactory
- .getLogger(Activator.class);
- private static final String CACHE_UPDATE_AWARE_REGISTRY_KEY = "cachenames" ;
-
-
- /**
- * Method which tells how many Global implementations are
- * supported by the bundle. This way we can tune the number of
- * components created. This components will be created ONLY at the
- * time of bundle startup and will be destroyed only at time of
- * bundle destruction, this is the major difference with the
- * implementation retrieved via getImplementations where all of
- * them are assumed to be in a container!
- *
- *
- * @return The list of implementations the bundle will support,
- * in Global version
- */
-
- @Override
- protected Object[] getGlobalImplementations(){
- logger.debug("Calling getGlobalImplementations to return:", RoutingTableImpl.class);
- return new Object[] {
- RoutingTableImpl.class
- };
- }
-
- /**
- * Configure the dependency for a given instance Global
- *
- * @param c Component assigned for this instance, this will be
- * what will be used for configuration
- * @param imp implementation to be configured
- *
- */
- @Override
- protected void configureGlobalInstance(Component c, Object imp){
- if (imp.equals(RoutingTableImpl.class)) {
- Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
- Set<String> propSet = new HashSet<String>();
- propSet.add(RoutingTableImpl.GLOBALRPC_CACHE);
- propSet.add(RoutingTableImpl.RPC_CACHE);
- props.put(CACHE_UPDATE_AWARE_REGISTRY_KEY, propSet);
-
- c.setInterface(new String[] { RoutingTable.class.getName(),ICacheUpdateAware.class.getName() }, props);
- logger.debug("configureGlobalInstance adding dependency:", IClusterGlobalServices.class);
-
-
- // RouteChangeListener services will be none or many so the
- // dependency is optional
- c.add(createServiceDependency()
- .setService(RouteChangeListener.class)
- .setCallbacks("setRouteChangeListener", "unsetRouteChangeListener")
- .setRequired(false));
-
- //dependency is required as it provides us the caching support
- c.add(createServiceDependency().setService(
- IClusterGlobalServices.class).setCallbacks(
- "setClusterGlobalServices",
- "unsetClusterGlobalServices").setRequired(true));
-
- }
- }
-
-
-}
+++ /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.impl;
-
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.transaction.HeuristicMixedException;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-
-import org.apache.felix.dm.Component;
-import org.opendaylight.controller.clustering.services.CacheConfigException;
-import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.CacheListenerAddException;
-import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
-import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-
-public class RoutingTableImpl<I, R> implements RoutingTable<I, R>, ICacheUpdateAware<I, R> {
-
- private final Logger log = LoggerFactory.getLogger(RoutingTableImpl.class);
-
- private IClusterGlobalServices clusterGlobalServices = null;
-
- private ConcurrentMap<I,R> globalRpcCache = null;
- private ConcurrentMap<I, LinkedHashSet<R>> rpcCache = null; //need routes to ordered by insert-order
-
- public static final String GLOBALRPC_CACHE = "remoterpc_routingtable.globalrpc_cache";
- public static final String RPC_CACHE = "remoterpc_routingtable.rpc_cache";
-
- public RoutingTableImpl() {
- }
-
- @Override
- public R getGlobalRoute(final I routeId) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeId, "getGlobalRoute: routeId cannot be null!");
- return globalRpcCache.get(routeId);
- }
-
- @Override
- public void addGlobalRoute(final I routeId, final R route) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeId, "addGlobalRoute: routeId cannot be null!");
- Preconditions.checkNotNull(route, "addGlobalRoute: route cannot be null!");
- try {
-
- log.debug("addGlobalRoute: adding a new route with id[{}] and value [{}]", routeId, route);
- clusterGlobalServices.tbegin();
- if (globalRpcCache.putIfAbsent(routeId, route) != null) {
- throw new DuplicateRouteException(" There is already existing route " + routeId);
- }
- clusterGlobalServices.tcommit();
-
- } 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) {
- throw new SystemException("System error occurred - while trying to create with value", e);
- }
-
- }
-
- @Override
- public void removeGlobalRoute(final I routeId) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeId, "removeGlobalRoute: routeId cannot be null!");
- try {
- log.debug("removeGlobalRoute: removing a new route with id [{}]", routeId);
-
- clusterGlobalServices.tbegin();
- globalRpcCache.remove(routeId);
- clusterGlobalServices.tcommit();
-
- } catch (NotSupportedException | HeuristicRollbackException | RollbackException | HeuristicMixedException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (javax.transaction.SystemException e) {
- throw new SystemException("System error occurred - while trying to remove with value", e);
- }
- }
-
-
- @Override
- public Set<R> getRoutes(final I routeId) {
- Preconditions.checkNotNull(routeId, "getRoutes: routeId cannot be null!");
- Set<R> routes = rpcCache.get(routeId);
-
- if (routes == null) {
- return Collections.emptySet();
- }
-
- return ImmutableSet.copyOf(routes);
- }
-
-
-
- @Override
- public R getLastAddedRoute(final I routeId) {
-
- Set<R> routes = getRoutes(routeId);
-
- if (routes.isEmpty()) {
- return null;
- }
-
- R route = null;
- Iterator<R> iter = routes.iterator();
- while (iter.hasNext()) {
- route = iter.next();
- }
-
- return route;
- }
-
- @Override
- public void addRoute(final I routeId, final R route) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeId, "addRoute: routeId cannot be null");
- Preconditions.checkNotNull(route, "addRoute: route cannot be null");
-
- try{
- clusterGlobalServices.tbegin();
- log.debug("addRoute: adding a route with k/v [{}/{}]", routeId, route);
- threadSafeAdd(routeId, route);
- clusterGlobalServices.tcommit();
-
- } catch (NotSupportedException | HeuristicRollbackException | RollbackException | HeuristicMixedException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (javax.transaction.SystemException e) {
- throw new SystemException("System error occurred - while trying to remove with value", e);
- }
- }
-
- @Override
- public void addRoutes(final Set<I> routeIds, final R route) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeIds, "addRoutes: routeIds must not be null");
- for (I routeId : routeIds){
- addRoute(routeId, route);
- }
- }
-
- @Override
- public void removeRoute(final I routeId, final R route) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeId, "removeRoute: routeId cannot be null!");
- Preconditions.checkNotNull(route, "removeRoute: route cannot be null!");
-
- LinkedHashSet<R> routes = rpcCache.get(routeId);
- if (routes == null) {
- return;
- }
-
- try {
- log.debug("removeRoute: removing a new route with k/v [{}/{}]", routeId, route);
-
- clusterGlobalServices.tbegin();
- threadSafeRemove(routeId, route);
- clusterGlobalServices.tcommit();
-
- } catch (NotSupportedException | HeuristicRollbackException | RollbackException | HeuristicMixedException e) {
- throw new RoutingTableException("Transaction error - while trying to remove route id="
- + routeId, e);
- } catch (javax.transaction.SystemException e) {
- throw new SystemException("System error occurred - while trying to remove with value", e);
- }
- }
-
- @Override
- public void removeRoutes(final Set<I> routeIds, final R route) throws RoutingTableException, SystemException {
- Preconditions.checkNotNull(routeIds, "removeRoutes: routeIds must not be null");
- for (I routeId : routeIds){
- removeRoute(routeId, route);
- }
- }
-
- /**
- * This method guarantees that no 2 thread over write each other's changes.
- * Just so that we dont end up in infinite loop, it tries for 100 times then throw
- */
- private void threadSafeAdd(final I routeId, final R route) {
-
- for (int i=0;i<100;i++){
-
- LinkedHashSet<R> updatedRoutes = new LinkedHashSet<>();
- updatedRoutes.add(route);
- LinkedHashSet<R> oldRoutes = rpcCache.putIfAbsent(routeId, updatedRoutes);
- if (oldRoutes == null) {
- return;
- }
-
- updatedRoutes = new LinkedHashSet<>(oldRoutes);
- updatedRoutes.add(route);
-
- if (rpcCache.replace(routeId, oldRoutes, updatedRoutes)) {
- return;
- }
- }
- //the method did not already return means it failed to add route in 10 attempts
- throw new IllegalStateException("Failed to add route [" + routeId + "]");
- }
-
- /**
- * This method guarantees that no 2 thread over write each other's changes.
- * Just so that we dont end up in infinite loop, it tries for 10 times then throw
- */
- private void threadSafeRemove(final I routeId, final R route) {
- LinkedHashSet<R> updatedRoutes = null;
- for (int i=0;i<10;i++){
- LinkedHashSet<R> oldRoutes = rpcCache.get(routeId);
-
- // if route to be deleted is the only entry in the set then remove routeId from the cache
- if ((oldRoutes.size() == 1) && oldRoutes.contains(route)){
- rpcCache.remove(routeId);
- return;
- }
-
- // if there are multiple routes for this routeId, remove the route to be deleted only from the set.
- updatedRoutes = new LinkedHashSet<>(oldRoutes);
- updatedRoutes.remove(route);
- if (rpcCache.replace(routeId, oldRoutes, updatedRoutes)) {
- return;
- }
-
- }
- //the method did not already return means it failed to remove route in 10 attempts
- throw new IllegalStateException("Failed to remove route [" + routeId + "]");
- }
-
-
- // /**
- // * @deprecated doesn't do anything will be removed once listeners used
- // * whiteboard pattern Registers listener for sending any change
- // * notification
- // * @param listener
- // */
- // @Override
- // public void registerRouteChangeListener(RouteChangeListener listener) {
- //
- // }
-
- // public void setRouteChangeListener(RouteChangeListener rcl) {
- // if(rcl != null){
- // routeChangeListeners.add(rcl);
- // }else{
- // log.warn("setRouteChangeListener called with null listener");
- // }
- // }
- //
- // public void unSetRouteChangeListener(RouteChangeListener rcl) {
- // if(rcl != null){
- // routeChangeListeners.remove(rcl);
- // }else{
- // log.warn("unSetRouteChangeListener called with null listener");
- // }
- // }
-
- /**
- * Returning the set of route change listeners for Unit testing Note: the
- * package scope is default
- *
- * @return List of registered RouteChangeListener<I,R> listeners
- */
- // Set<RouteChangeListener> getRegisteredRouteChangeListeners() {
- // return routeChangeListeners;
- // }
- public void setClusterGlobalServices(final IClusterGlobalServices clusterGlobalServices) {
- this.clusterGlobalServices = clusterGlobalServices;
- }
-
- public void unsetClusterGlobalServices(final IClusterGlobalServices clusterGlobalServices) {
- if ((clusterGlobalServices != null) && (this.clusterGlobalServices.equals(clusterGlobalServices))) {
- this.clusterGlobalServices = null;
- }
- }
-
- /**
- * Finds OR Creates clustered cache for Global RPCs
- *
- * @throws CacheExistException -- cluster global services exception when cache exist
- * @throws CacheConfigException -- cluster global services exception during cache config
- * @throws CacheListenerAddException -- cluster global services exception during adding of listener
- */
-
- @SuppressWarnings("unchecked")
- void findOrCreateGlobalRpcCache() throws CacheExistException, CacheConfigException,
- CacheListenerAddException {
- // TBD: HOW DO WE DECIDE ON PROPERTIES OF THE CACHE i.e. what duration it
- // should be caching?
-
- // let us check here if the cache already exists -- if so don't create
- if (!clusterGlobalServices.existCache(GLOBALRPC_CACHE)) {
-
- globalRpcCache = (ConcurrentMap<I,R>) clusterGlobalServices.createCache(GLOBALRPC_CACHE,
- EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
- log.debug("Cache created [{}] ", GLOBALRPC_CACHE);
-
- } else {
- globalRpcCache = (ConcurrentMap<I,R>) clusterGlobalServices.getCache(GLOBALRPC_CACHE);
- log.debug("Cache exists [{}] ", GLOBALRPC_CACHE);
- }
- }
-
- /**
- * Finds OR Creates clustered cache for Routed RPCs
- *
- * @throws CacheExistException -- cluster global services exception when cache exist
- * @throws CacheConfigException -- cluster global services exception during cache config
- * @throws CacheListenerAddException -- cluster global services exception during adding of listener
- */
-
- @SuppressWarnings("unchecked")
- void findOrCreateRpcCache() throws CacheExistException, CacheConfigException,
- CacheListenerAddException {
- // TBD: HOW DO WE DECIDE ON PROPERTIES OF THE CACHE i.e. what duration it
- // should be caching?
-
- if (clusterGlobalServices.existCache(RPC_CACHE)){
- rpcCache = (ConcurrentMap<I,LinkedHashSet<R>>) clusterGlobalServices.getCache(RPC_CACHE);
- log.debug("Cache exists [{}] ", RPC_CACHE);
- return;
- }
-
- //cache doesnt exist, create one
- rpcCache = (ConcurrentMap<I,LinkedHashSet<R>>) clusterGlobalServices.createCache(RPC_CACHE,
- EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
- log.debug("Cache created [{}] ", RPC_CACHE);
- }
-
-
- /**
- * Function called by the dependency manager when all the required
- * dependencies are satisfied
- */
- void init(final Component c) {
- try {
-
- findOrCreateGlobalRpcCache();
- findOrCreateRpcCache();
-
- } catch (CacheExistException|CacheConfigException|CacheListenerAddException e) {
- throw new IllegalStateException("could not construct routing table cache");
- }
- }
-
- /**
- * Useful for unit testing <note>It has package
- * scope</note>
- */
- ConcurrentMap<I, R> getGlobalRpcCache() {
- return this.globalRpcCache;
- }
-
- /**
- * Useful for unit testing <note>It has package
- * scope</note>
- */
- ConcurrentMap<I, LinkedHashSet<R>> getRpcCache() {
- return this.rpcCache;
- }
-
- /**
- * This is used from integration test NP rest API to check out the result of the
- * cache population
- * <Note> For testing purpose only-- use it wisely</Note>
- *
- * @return
- */
- public String dumpGlobalRpcCache() {
- Set<Map.Entry<I, R>> cacheEntrySet = this.globalRpcCache.entrySet();
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<I, R> entry : cacheEntrySet) {
- sb.append("Key:").append(entry.getKey()).append("---->Value:")
- .append((entry.getValue() != null) ? entry.getValue() : "null")
- .append("\n");
- }
- return sb.toString();
- }
-
- public String dumpRpcCache() {
- Set<Map.Entry<I, LinkedHashSet<R>>> cacheEntrySet = this.rpcCache.entrySet();
- StringBuilder sb = new StringBuilder();
- for (Map.Entry<I, LinkedHashSet<R>> entry : cacheEntrySet) {
- sb.append("Key:").append(entry.getKey()).append("---->Value:")
- .append((entry.getValue() != null) ? entry.getValue() : "null")
- .append("\n");
- }
- return sb.toString();
- }
- /**
- * Invoked when a new entry is available in the cache, the key is only
- * provided, the value will come as an entryUpdate invocation
- *
- * @param key Key for the entry just created
- * @param cacheName name of the cache for which update has been received
- * @param originLocal true if the event is generated from this node
- */
- @Override
- public void entryCreated(final I key, final String cacheName, final boolean originLocal) {
- // TBD: do we require this.
- if (log.isDebugEnabled()) {
- log.debug("RoutingTableUpdates: entryCreated routeId = " + key + " cacheName=" + cacheName);
- }
- }
-
- /**
- * Called anytime a given entry is updated
- *
- * @param key Key for the entry modified
- * @param new_value the new value the key will have
- * @param cacheName name of the cache for which update has been received
- * @param originLocal true if the event is generated from this node
- */
- @Override
- public void entryUpdated(final I key, final R new_value, final String cacheName, final boolean originLocal) {
- if (log.isDebugEnabled()) {
- log.debug("RoutingTableUpdates: entryUpdated routeId = " + key + ",value = " + new_value
- + " ,cacheName=" + cacheName + " originLocal=" + originLocal);
- }
- // if (!originLocal) {
- // for (RouteChangeListener rcl : routeChangeListeners) {
- // rcl.onRouteUpdated(key, new_value);
- // }
- // }
- }
-
- /**
- * Called anytime a given key is removed from the ConcurrentHashMap we are
- * listening to.
- *
- * @param key Key of the entry removed
- * @param cacheName name of the cache for which update has been received
- * @param originLocal true if the event is generated from this node
- */
- @Override
- public void entryDeleted(final I key, final String cacheName, final boolean originLocal) {
- if (log.isDebugEnabled()) {
- log.debug("RoutingTableUpdates: entryUpdated routeId = " + key + " local = " + originLocal
- + " cacheName=" + cacheName + " originLocal=" + originLocal);
- }
- // if (!originLocal) {
- // for (RouteChangeListener rcl : routeChangeListeners) {
- // rcl.onRouteDeleted(key);
- // }
- // }
- }
-}
+++ /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.impl;
-
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.when;
-
-import java.net.URI;
-import java.util.EnumSet;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import junit.framework.Assert;
-
-import org.apache.felix.dm.Component;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
-import org.opendaylight.controller.clustering.services.IClusterServices;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-public class RoutingTableImplTest {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "global");
-
- private IClusterGlobalServices clusterService;
- private RoutingTableImpl<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String> routingTable;
- ConcurrentMap mockGlobalRpcCache;
- ConcurrentMap mockRpcCache;
-
- @Before
- public void setUp() throws Exception{
- clusterService = mock(IClusterGlobalServices.class);
- routingTable = new RoutingTableImpl<RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>, String>();
- mockGlobalRpcCache = new ConcurrentHashMap<>();
- mockRpcCache = new ConcurrentHashMap<>();
- createRoutingTableCache();
- }
-
- @After
- public void tearDown(){
- reset(clusterService);
- mockGlobalRpcCache = null;
- mockRpcCache = null;
- }
-
- @Test
- public void addGlobalRoute_ValidArguments_ShouldAdd() throws Exception {
-
- Assert.assertNotNull(mockGlobalRpcCache);
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
-
- final String expectedRoute = "172.27.12.1:5000";
- routingTable.addGlobalRoute(routeIdentifier, expectedRoute);
-
- ConcurrentMap latestCache = routingTable.getGlobalRpcCache();
- Assert.assertEquals(mockGlobalRpcCache, latestCache);
- Assert.assertEquals(expectedRoute, latestCache.get(routeIdentifier));
- }
-
- @Test (expected = RoutingTable.DuplicateRouteException.class)
- public void addGlobalRoute_DuplicateRoute_ShouldThrow() throws Exception{
-
- Assert.assertNotNull(mockGlobalRpcCache);
-
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
- routingTable.addGlobalRoute(routeIdentifier, new String());
- routingTable.addGlobalRoute(routeIdentifier, new String());
- }
-
- @Test
- public void getGlobalRoute_ExistingRouteId_ShouldReturnRoute() throws Exception {
-
- Assert.assertNotNull(mockGlobalRpcCache);
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
- String expectedRoute = "172.27.12.1:5000";
-
- routingTable.addGlobalRoute(routeIdentifier, expectedRoute);
-
- String actualRoute = routingTable.getGlobalRoute(routeIdentifier);
- Assert.assertEquals(expectedRoute, actualRoute);
- }
-
- @Test
- public void getGlobalRoute_NonExistentRouteId_ShouldReturnNull() throws Exception {
-
- Assert.assertNotNull(mockGlobalRpcCache);
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
-
- String actualRoute = routingTable.getGlobalRoute(routeIdentifier);
- Assert.assertNull(actualRoute);
- }
-
- @Test
- public void removeGlobalRoute_ExistingRouteId_ShouldRemove() throws Exception {
-
- Assert.assertNotNull(mockGlobalRpcCache);
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
-
- ConcurrentMap cache = routingTable.getGlobalRpcCache();
- Assert.assertTrue(cache.size() == 0);
- routingTable.addGlobalRoute(routeIdentifier, "172.27.12.1:5000");
- Assert.assertTrue(cache.size() == 1);
-
- routingTable.removeGlobalRoute(routeIdentifier);
- Assert.assertTrue(cache.size() == 0);
-
- }
-
- @Test
- public void removeGlobalRoute_NonExistentRouteId_ShouldDoNothing() throws Exception {
-
- Assert.assertNotNull(mockGlobalRpcCache);
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = getRouteIdentifier();
-
- ConcurrentMap cache = routingTable.getGlobalRpcCache();
- Assert.assertTrue(cache.size() == 0);
-
- routingTable.removeGlobalRoute(routeIdentifier);
- Assert.assertTrue(cache.size() == 0);
-
- }
-
- @Test
- public void addRoute_ForNewRouteId_ShouldAddRoute() throws Exception {
- Assert.assertTrue(mockRpcCache.size() == 0);
-
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeId = getRouteIdentifier();
-
- routingTable.addRoute(routeId, new String());
- Assert.assertTrue(mockRpcCache.size() == 1);
-
- Set<String> routes = routingTable.getRoutes(routeId);
- Assert.assertEquals(1, routes.size());
- }
-
- @Test
- public void addRoute_ForExistingRouteId_ShouldAppendRoute() throws Exception {
-
- Assert.assertTrue(mockRpcCache.size() == 0);
-
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeId = getRouteIdentifier();
-
- String route_1 = "10.0.0.1:5955";
- String route_2 = "10.0.0.2:5955";
-
- routingTable.addRoute(routeId, route_1);
- routingTable.addRoute(routeId, route_2);
-
- Assert.assertTrue(mockRpcCache.size() == 1);
-
- Set<String> routes = routingTable.getRoutes(routeId);
- Assert.assertEquals(2, routes.size());
- Assert.assertTrue(routes.contains(route_1));
- Assert.assertTrue(routes.contains(route_2));
- }
-
- @Test
- public void addRoute_UsingMultipleThreads_ShouldNotOverwrite(){
- ExecutorService threadPool = Executors.newCachedThreadPool();
-
- int numOfRoutesToAdd = 100;
- String routePrefix_1 = "10.0.0.1:555";
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- threadPool.submit(addRoutes(numOfRoutesToAdd, routePrefix_1, routeId));
- String routePrefix_2 = "10.0.0.1:556";
- threadPool.submit(addRoutes(numOfRoutesToAdd, routePrefix_2, routeId));
-
- // wait for all tasks to complete; timeout in 10 sec
- threadPool.shutdown();
- try {
- threadPool.awaitTermination(10, TimeUnit.SECONDS); //
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
- Assert.assertEquals(2*numOfRoutesToAdd, routingTable.getRoutes(routeId).size());
- }
-
- @Test(expected = NullPointerException.class)
- public void addRoute_NullRouteId_shouldThrowNpe() throws Exception {
-
- routingTable.addRoute(null, new String());
- }
-
- @Test(expected = NullPointerException.class)
- public void addRoute_NullRoute_shouldThrowNpe() throws Exception{
-
- routingTable.addRoute(getRouteIdentifier(), null);
- }
-
- @Test (expected = UnsupportedOperationException.class)
- public void getRoutes_Call_ShouldReturnImmutableCopy() throws Exception{
- Assert.assertNotNull(routingTable);
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- routingTable.addRoute(routeId, new String());
-
- Set<String> routes = routingTable.getRoutes(routeId); //returns Immutable Set
-
- routes.add(new String()); //can not be modified; should throw
- }
-
- @Test
- public void getRoutes_With2RoutesFor1RouteId_ShouldReturnASetWithSize2() throws Exception{
- Assert.assertNotNull(routingTable);
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- routingTable.addRoute(routeId, "10.0.0.1:5555");
- routingTable.addRoute(routeId, "10.0.0.2:5555");
-
- Set<String> routes = routingTable.getRoutes(routeId); //returns Immutable Set
-
- Assert.assertEquals(2, routes.size());
- }
-
- @Test
- public void getLastAddedRoute_WhenMultipleRoutesExists_ShouldReturnLatestRoute()
- throws Exception {
-
- Assert.assertNotNull(routingTable);
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- String route_1 = "10.0.0.1:5555";
- String route_2 = "10.0.0.2:5555";
- routingTable.addRoute(routeId, route_1);
- routingTable.addRoute(routeId, route_2);
-
- Assert.assertEquals(route_2, routingTable.getLastAddedRoute(routeId));
- }
-
- @Test
- public void removeRoute_WhenMultipleRoutesExist_RemovesGivenRoute() throws Exception{
- Assert.assertNotNull(routingTable);
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- String route_1 = "10.0.0.1:5555";
- String route_2 = "10.0.0.2:5555";
-
- routingTable.addRoute(routeId, route_1);
- routingTable.addRoute(routeId, route_2);
-
- Assert.assertEquals(2, routingTable.getRoutes(routeId).size());
-
- routingTable.removeRoute(routeId, route_1);
- Assert.assertEquals(1, routingTable.getRoutes(routeId).size());
-
- }
-
- @Test
- public void removeRoute_WhenOnlyOneRouteExists_RemovesRouteId() throws Exception{
- Assert.assertNotNull(routingTable);
- RpcRouter.RouteIdentifier routeId = getRouteIdentifier();
- String route_1 = "10.0.0.1:5555";
-
- routingTable.addRoute(routeId, route_1);
- Assert.assertEquals(1, routingTable.getRoutes(routeId).size());
-
- routingTable.removeRoute(routeId, route_1);
- ConcurrentMap cache = routingTable.getRpcCache();
- Assert.assertFalse(cache.containsKey(routeId));
-
- }
-
- /*
- * Private helper methods
- */
- private void createRoutingTableCache() throws Exception {
-
- //here init
- Component c = mock(Component.class);
-
- when(clusterService.existCache(
- RoutingTableImpl.GLOBALRPC_CACHE)).thenReturn(false);
-
- when(clusterService.createCache(RoutingTableImpl.GLOBALRPC_CACHE,
- EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).
- thenReturn(mockGlobalRpcCache);
-
- when(clusterService.existCache(
- RoutingTableImpl.RPC_CACHE)).thenReturn(false);
-
- when(clusterService.createCache(RoutingTableImpl.RPC_CACHE,
- EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL))).
- thenReturn(mockRpcCache);
-
- doNothing().when(clusterService).tbegin();
- doNothing().when(clusterService).tcommit();
-
- routingTable.setClusterGlobalServices(this.clusterService);
- routingTable.init(c);
-
- Assert.assertEquals(mockGlobalRpcCache, routingTable.getGlobalRpcCache());
- Assert.assertEquals(mockRpcCache, routingTable.getRpcCache());
- }
-
- private RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> getRouteIdentifier(){
- RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier> routeIdentifier = mock(RpcRouter.RouteIdentifier.class);
- InstanceIdentifier identifier = mock(InstanceIdentifier.class);
- when(routeIdentifier.getType()).thenReturn(QNAME);
- when(routeIdentifier.getRoute()).thenReturn(identifier);
-
- return routeIdentifier;
- }
-
- private Runnable addRoutes(final int numRoutes, final String routePrefix, final RpcRouter.RouteIdentifier routeId){
- return new Runnable() {
- @Override
- public void run() {
- for (int i=0;i<numRoutes;i++){
- String route = routePrefix + i;
- try {
- routingTable.addRoute(routeId, route);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- };
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.integrationtest</artifactId>
- <version>0.5.1-SNAPSHOT</version>
- <relativePath>../../../commons/integrationtest</relativePath>
- </parent>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:Main</url>
- <tag>HEAD</tag>
- </scm>
-
- <artifactId>remoterpc-routingtable.integrationtest</artifactId>
- <version>0.4.1-SNAPSHOT</version>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager.it.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.stub</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <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-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.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- </dependency>
- <dependency>
- <groupId>eclipselink</groupId>
- <artifactId>javax.resource</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-connector-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- </dependency>
- <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.opendaylight.controller</groupId>
- <artifactId>config-manager</artifactId>
- </dependency>
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>antlr4-runtime-osgi-nohead</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>xtend-lib-osgi</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <version>${exam.version}</version>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <version>${exam.version}</version>
- </dependency>
- </dependencies>
- <properties>
- <!-- Sonar jacoco plugin to get integration test coverage info -->
- <sonar.jacoco.reportPath>../implementation/target/jacoco.exec</sonar.jacoco.reportPath>
- <sonar.jacoco.itReportPath>../implementation/target/jacoco-it.exec</sonar.jacoco.itReportPath>
- </properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.jacoco</groupId>
- <artifactId>jacoco-maven-plugin</artifactId>
- <configuration>
- <destFile>../implementation/target/jacoco-it.exec</destFile>
- <includes><include>org.opendaylight.controller.*</include></includes>
- </configuration>
- <executions>
- <execution>
- <id>pre-test</id>
- <goals>
- <goal>prepare-agent</goal>
- </goals>
- </execution>
- <execution>
- <id>post-test</id>
- <configuration>
- <skip>true</skip>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /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.connector.remoterpc.impl;
-
-import junit.framework.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.util.PathUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.inject.Inject;
-import java.io.Serializable;
-import java.net.URI;
-import java.util.Set;
-
-import static org.ops4j.pax.exam.CoreOptions.junitBundles;
-import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
-import static org.ops4j.pax.exam.CoreOptions.options;
-import static org.ops4j.pax.exam.CoreOptions.systemPackages;
-import static org.ops4j.pax.exam.CoreOptions.systemProperty;
-
-
-
-
-@RunWith(PaxExam.class)
-public class
- ZeroMQRoutingTableTestIT {
- private Logger log = LoggerFactory
- .getLogger(ZeroMQRoutingTableTestIT.class);
-
- public static final String ODL = "org.opendaylight.controller";
- public static final String YANG = "org.opendaylight.yangtools";
- public static final String CONTROLLER = "org.opendaylight.controller";
- public static final String YANGTOOLS = "org.opendaylight.yangtools";
- RoutingIdentifierImpl rii = new RoutingIdentifierImpl();
- // get the OSGI bundle context
- @Inject
- private BundleContext bc;
- @Inject
- private RoutingTable routingTable = null;
-
- // Configure the OSGi container
- @Configuration
- public Option[] config() {
- return options(
- //
- systemProperty("logback.configurationFile").value(
- "file:" + PathUtils.getBaseDir()
- + "/src/test/resources/logback.xml"),
- // To start OSGi console for inspection remotely
- systemProperty("osgi.console").value("2401"),
- // Set the systemPackages (used by clustering)
- 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.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(),
- // List all the bundles on which the test case depends
- mavenBundle(ODL,
- "clustering.services").versionAsInProject(),
-
- mavenBundle(ODL, "sal").versionAsInProject(),
- mavenBundle(ODL,
- "sal.implementation").versionAsInProject(),
- mavenBundle(ODL, "containermanager").versionAsInProject(),
- mavenBundle(ODL,
- "containermanager.it.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(),
- mavenBundle("org.apache.felix",
- "org.apache.felix.dependencymanager.shell").versionAsInProject(),
- mavenBundle("eclipselink", "javax.resource").versionAsInProject(),
-
- mavenBundle("com.google.guava","guava").versionAsInProject(),
- // List logger bundles
- 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, "clustering.services")
- .versionAsInProject(),
- mavenBundle(ODL, "clustering.stub")
- .versionAsInProject(),
-
-
- // List all the bundles on which the test case depends
- mavenBundle(ODL, "sal")
- .versionAsInProject(),
- mavenBundle(ODL, "sal-connector-api")
- .versionAsInProject(),
- mavenBundle(ODL, "remoterpc-routingtable.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(),
-
- mavenBundle(ODL,
- "sal-core-api")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.yangtools","yang-data-api")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.yangtools","yang-model-api")
- .versionAsInProject(),
- mavenBundle("org.opendaylight.yangtools","yang-binding")
- .versionAsInProject(),
-
- mavenBundle(CONTROLLER, "sal-binding-api").versionAsInProject(), //
- mavenBundle(CONTROLLER, "sal-binding-config").versionAsInProject(),
- mavenBundle(CONTROLLER, "sal-binding-broker-impl").versionAsInProject(), //
- mavenBundle("org.javassist", "javassist").versionAsInProject(), //
- mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), //
-
- mavenBundle(YANGTOOLS, "yang-data-api").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "yang-data-impl").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "yang-model-api").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "yang-model-util").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "yang-parser-api").versionAsInProject(),
- mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
-
-
- mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "binding-model-api").versionAsInProject(), //
- mavenBundle(YANGTOOLS, "binding-generator-util").versionAsInProject(),
- mavenBundle(YANGTOOLS, "yang-parser-impl").versionAsInProject(),
- mavenBundle(YANGTOOLS, "binding-type-provider").versionAsInProject(),
- mavenBundle(YANGTOOLS, "binding-generator-api").versionAsInProject(),
- mavenBundle(YANGTOOLS, "binding-generator-spi").versionAsInProject(),
- mavenBundle(YANGTOOLS, "binding-generator-impl").versionAsInProject(),
-
-
- mavenBundle(CONTROLLER, "sal-core-api").versionAsInProject().update(), //
- mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), //
- mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
-
- mavenBundle(YANGTOOLS + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
-
- mavenBundle(YANG+".thirdparty", "xtend-lib-osgi").versionAsInProject(),
- mavenBundle("com.google.guava", "guava").versionAsInProject(), //
- mavenBundle("org.javassist", "javassist").versionAsInProject(),
- 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-common").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-api").versionAsInProject(),//
- mavenBundle(ODL, "sal-common-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-util").versionAsInProject(), //
-
- mavenBundle(ODL, "config-api").versionAsInProject(), //
- mavenBundle(ODL, "config-manager").versionAsInProject(), //
- mavenBundle("commons-io", "commons-io").versionAsInProject(),
- mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),
-
- mavenBundle(ODL, "sal-binding-api").versionAsInProject(), //
- mavenBundle(ODL, "sal-binding-config").versionAsInProject(),
- mavenBundle("org.javassist", "javassist").versionAsInProject(), //
- mavenBundle(ODL, "sal-common-util").versionAsInProject(), //
-
- mavenBundle(YANG, "yang-data-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-data-impl").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-api").versionAsInProject(), //
- mavenBundle(YANG, "yang-model-util").versionAsInProject(), //
- mavenBundle(YANG, "yang-parser-api").versionAsInProject(),
- mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
-
-
- mavenBundle(YANG, "binding-generator-spi").versionAsInProject(), //
- mavenBundle(YANG, "binding-model-api").versionAsInProject(), //
- mavenBundle(YANG, "binding-generator-util").versionAsInProject(),
- mavenBundle(YANG, "yang-parser-impl").versionAsInProject(),
- mavenBundle(YANG, "binding-type-provider").versionAsInProject(),
- mavenBundle(YANG, "binding-generator-api").versionAsInProject(),
- mavenBundle(YANG, "binding-generator-spi").versionAsInProject(),
- mavenBundle(YANG, "binding-generator-impl").versionAsInProject(),
-
-
- mavenBundle(ODL, "sal-core-api").versionAsInProject().update(), //
- mavenBundle(ODL, "sal-broker-impl").versionAsInProject(), //
- mavenBundle(ODL, "sal-core-spi").versionAsInProject().update(), //
-
- mavenBundle(YANG + ".thirdparty", "antlr4-runtime-osgi-nohead").versionAsInProject(), //
-
- mavenBundle(YANG, "concepts").versionAsInProject(),
- mavenBundle(YANG, "yang-binding").versionAsInProject(), //
- mavenBundle(YANG, "yang-common").versionAsInProject(), //
- mavenBundle(YANG+".thirdparty", "xtend-lib-osgi").versionAsInProject(),
- mavenBundle("com.google.guava", "guava").versionAsInProject(), //
- mavenBundle("org.javassist", "javassist").versionAsInProject(),
-
- junitBundles());
- }
-
- private String stateToString(int state) {
- switch (state) {
- case Bundle.ACTIVE:
- return "ACTIVE";
- case Bundle.INSTALLED:
- return "INSTALLED";
- case Bundle.RESOLVED:
- return "RESOLVED";
- case Bundle.UNINSTALLED:
- return "UNINSTALLED";
- default:
- return "Not CONVERTED";
- }
- }
-
- @Test
- public void testAddGlobalRoute () throws Exception{
-
- routingTable.addGlobalRoute(rii,"172.27.12.1:5000");
-
- Set<String> routes = routingTable.getRoutes(rii);
-
- for(String route:routes){
- Assert.assertEquals(route,"172.27.12.1:5000");
- }
-
-
- }
-
-
- @Test
- public void testDeleteGlobalRoute () throws Exception{
-
- routingTable.removeGlobalRoute(rii);
-
- Set<String> routes = routingTable.getRoutes(rii);
-
- Assert.assertNull(routes);
-
-
- }
-
-
-
- class RoutingIdentifierImpl implements RpcRouter.RouteIdentifier,Serializable {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace,"global");
- private final QName instance = new QName(URI.create("127.0.0.1"),"local");
-
- @Override
- public QName getContext() {
- return QNAME;
- }
-
- @Override
- public QName getType() {
- return QNAME;
- }
-
- @Override
- 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 != null ? !QNAME.equals(that.QNAME) : that.QNAME != null) return false;
- if (instance != null ? !instance.equals(that.instance) : that.instance != null) return false;
- if (namespace != null ? !namespace.equals(that.namespace) : that.namespace != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int result = namespace != null ? namespace.hashCode() : 0;
- result = 31 * result + (QNAME != null ? QNAME.hashCode() : 0);
- result = 31 * result + (instance != null ? instance.hashCode() : 0);
- return result;
- }
- }
-
-
-
-
-
-}
+++ /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="error">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>remoterpc-routingtable-nb-it</artifactId>
- <packaging>bundle</packaging>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- org.opendaylight.controller.tests.zmqroutingtable.rest
- </Export-Package>
- <Import-Package>
- com.sun.jersey.spi.container.servlet,
- com.fasterxml.jackson.annotation,
- javax.ws.rs,
- javax.ws.rs.core,
- javax.xml.bind,
- javax.xml.bind.annotation,
- org.slf4j,
- org.apache.catalina.filters,
- org.codehaus.jackson.jaxrs,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.yangtools.yang.common,
- org.opendaylight.controller.sal.connector.api,
- org.opendaylight.controller.sal.connector.remoterpc.api,
- org.opendaylight.controller.sal.connector.remoterpc.impl,
- org.osgi.framework,
- com.google.common.base,
- org.opendaylight.yangtools.yang.data.api,
- !org.codehaus.enunciate.jaxrs
-
- </Import-Package>
- <Web-ContextPath>/controller/nb/v2/zmqnbrt</Web-ContextPath>
- <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
- </instructions>
- <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- </dependencies>
-
- </project>
+++ /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.tests.zmqroutingtable.rest;
-
-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;
-import java.net.URI;
-
-/**
- * @author: syedbahm
- * Date: 12/10/13
- */
-public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier, Serializable {
-
- private final URI namespace;
- private final QName QNAME;
- private final QName instance;
-
- public RouteIdentifierImpl() {
- namespace = URI.create("http://cisco.com/example");
- QNAME = new QName(namespace, "global");
- instance = new QName(URI.create("127.0.0.1"), "local");
- }
-
- public RouteIdentifierImpl(String url,String instanceIP){
- namespace = URI.create(url);
- QNAME = new QName(namespace,"global");
- instance = new QName(URI.create(instanceIP), "local");
- }
-
-
- @Override
- public QName getContext() {
- return QNAME;
- }
-
- @Override
- public QName getType() {
- return QNAME;
- }
-
- @Override
- 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;
-
- RouteIdentifierImpl that = (RouteIdentifierImpl) 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;
- }
-}
+++ /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.tests.zmqroutingtable.rest;
-
-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.impl.RoutingTableImpl;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleReference;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import java.io.Serializable;
-import java.net.URI;
-
-@Path("router")
-public class Router implements Serializable {
- private Logger _logger = LoggerFactory.getLogger(Router.class);
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
-
- @GET
- @Path("/hello")
- @Produces(MediaType.TEXT_PLAIN)
- public String hello() {
- return "Hello";
- }
-
-
-
-
- @GET
- @Path("/rtadd")
- @Produces(MediaType.TEXT_PLAIN)
- public String addToRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance,@QueryParam("port") String port) {
- _logger.info("Invoking adding an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
- try {
- routingTable.addGlobalRoute(rii, instance+":"+ port);
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("Result of adding route:").append("\n")
- .append(routingTable.dumpRoutingTableCache());
- return stringBuilder.toString();
- }
-
- @GET
- @Path("/rtdelete")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeDeleteRoutingTable(@QueryParam("nsp") String namespace,@QueryParam("inst") String instance) {
- _logger.info("Invoking delete an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RouteIdentifierImpl rii = new RouteIdentifierImpl(namespace,instance);
- try {
- routingTable.removeGlobalRoute(rii);
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("Result of deleting route:").append("\n")
- .append(routingTable.dumpRoutingTableCache());
-
- return stringBuilder.toString();
- }
-
- @GET
- @Path("/routingtable")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeGetRoutingTable() {
- _logger.info("Invoking getting of routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("Result of getting routetable:").append("\n")
- .append(routingTable.dumpRoutingTableCache());
-
- return stringBuilder.toString();
- }
-
-
-
- private BundleContext getBundleContext() {
- ClassLoader tlcl = Thread.currentThread().getContextClassLoader();
- Bundle bundle = null;
-
- if (tlcl instanceof BundleReference) {
- bundle = ((BundleReference) tlcl).getBundle();
- } else {
- _logger.info("Unable to determine the bundle context based on " +
- "thread context classloader.");
- bundle = FrameworkUtil.getBundle(this.getClass());
- }
- return (bundle == null ? null : bundle.getBundleContext());
- }
-
-
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- version="3.0">
- <servlet>
- <servlet-name>JAXRSZmqRT</servlet-name>
- <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
- <init-param>
- <param-name>javax.ws.rs.Application</param-name>
- <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>JAXRSZmqRT</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
-
-
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>NB api</web-resource-name>
- <url-pattern>/*</url-pattern>
- <http-method>POST</http-method>
- <http-method>GET</http-method>
- <http-method>PUT</http-method>
- <http-method>PATCH</http-method>
- <http-method>DELETE</http-method>
- <http-method>HEAD</http-method>
- </web-resource-collection>
- <auth-constraint>
- <role-name>System-Admin</role-name>
- <role-name>Network-Admin</role-name>
- <role-name>Network-Operator</role-name>
- <role-name>Container-User</role-name>
- </auth-constraint>
- </security-constraint>
-
- <security-role>
- <role-name>System-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Operator</role-name>
- </security-role>
- <security-role>
- <role-name>Container-User</role-name>
- </security-role>
-
- <login-config>
- <auth-method>BASIC</auth-method>
- <realm-name>opendaylight</realm-name>
- </login-config>
-</web-app>
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-public interface BindingDataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, BindingDataChangeListener>, BindingService {
+/**
+ * Provides access to a conceptual data tree store and also provides the ability to
+ * subscribe for changes to data under a given branch of the tree.
+ * <p>
+ * For more information on usage, please see the documentation in {@link AsyncDataBroker}.
+ */
+public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService {
@Override
- BindingDataReadTransaction newReadOnlyTransaction();
+ ReadOnlyTransaction newReadOnlyTransaction();
@Override
- BindingDataReadWriteTransaction newReadWriteTransaction();
+ ReadWriteTransaction newReadWriteTransaction();
@Override
- BindingDataWriteTransaction newWriteOnlyTransaction();
+ WriteTransaction newWriteOnlyTransaction();
@Override
- ListenerRegistration<BindingDataChangeListener> registerDataChangeListener(LogicalDatastoreType store,
- InstanceIdentifier<?> path, BindingDataChangeListener listener, DataChangeScope triggeringScope);
+ ListenerRegistration<DataChangeListener> registerDataChangeListener(LogicalDatastoreType store,
+ InstanceIdentifier<?> path, DataChangeListener listener, DataChangeScope triggeringScope);
}
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-public interface BindingDataChangeListener extends AsyncDataChangeListener<InstanceIdentifier<?>, DataObject> {
+public interface DataChangeListener extends AsyncDataChangeListener<InstanceIdentifier<?>, DataObject> {
@Override
void onDataChanged(AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change);
}
--- /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.md.sal.binding.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncReadOnlyTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * A transaction that provides a stateful read-only view of the data tree.
+ * <p>
+ * For more information on usage and examples, please see the documentation in
+ * {@link org.opendaylight.controller.md.sal.common.api.data.AsyncReadTransaction}.
+ */
+public interface ReadOnlyTransaction extends ReadTransaction, AsyncReadOnlyTransaction<InstanceIdentifier<?>, DataObject> {
+
+}
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
-public interface BindingDataReadTransaction extends AsyncReadTransaction<InstanceIdentifier<?>, DataObject> {
+public interface ReadTransaction extends AsyncReadTransaction<InstanceIdentifier<?>, DataObject> {
@Override
ListenableFuture<Optional<DataObject>> read(LogicalDatastoreType store, InstanceIdentifier<?> path);
}
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
- * Logical capture of a combination of both {@link BindingDataReadTransaction} and
- * {@link BindingDataWriteTransaction}.
+ * A transaction that enables combined read/write capabilities.
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncReadWriteTransaction}.
*/
-public interface BindingDataReadWriteTransaction extends BindingDataReadTransaction, BindingDataWriteTransaction, AsyncReadWriteTransaction<InstanceIdentifier<?>, DataObject> {
+public interface ReadWriteTransaction extends ReadTransaction, WriteTransaction, AsyncReadWriteTransaction<InstanceIdentifier<?>, DataObject> {
}
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-public interface BindingDataWriteTransaction extends AsyncWriteTransaction<InstanceIdentifier<?>, DataObject> {
+/**
+ * A transaction that provides mutation capabilities on a data tree.
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncWriteTransaction}.
+ */
+public interface WriteTransaction extends AsyncWriteTransaction<InstanceIdentifier<?>, DataObject> {
@Override
void put(LogicalDatastoreType store, InstanceIdentifier<?> path, DataObject data);
import java.util.Map.Entry;
import java.util.Set;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
codec.onGlobalContextUpdated(ctx);
}
- public ListenerRegistration<BindingDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
- final InstanceIdentifier<?> path, final BindingDataChangeListener listener,
+ public ListenerRegistration<DataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
+ final InstanceIdentifier<?> path, final DataChangeListener listener,
final DataChangeScope triggeringScope) {
DOMDataChangeListener domDataChangeListener = new TranslatingDataChangeInvoker(store, path, listener,
triggeringScope);
}
private class TranslatingDataChangeInvoker implements DOMDataChangeListener {
- private final BindingDataChangeListener bindingDataChangeListener;
+ private final DataChangeListener bindingDataChangeListener;
private final LogicalDatastoreType store;
private final InstanceIdentifier<?> path;
private final DataChangeScope triggeringScope;
public TranslatingDataChangeInvoker(final LogicalDatastoreType store, final InstanceIdentifier<?> path,
- final BindingDataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) {
+ final DataChangeListener bindingDataChangeListener, final DataChangeScope triggeringScope) {
this.store = store;
this.path = path;
this.bindingDataChangeListener = bindingDataChangeListener;
}
}
- private static class ListenerRegistrationImpl extends AbstractListenerRegistration<BindingDataChangeListener> {
+ private static class ListenerRegistrationImpl extends AbstractListenerRegistration<DataChangeListener> {
private final ListenerRegistration<DOMDataChangeListener> registration;
- public ListenerRegistrationImpl(final BindingDataChangeListener listener,
+ public ListenerRegistrationImpl(final DataChangeListener listener,
final ListenerRegistration<DOMDataChangeListener> registration) {
super(listener);
this.registration = registration;
return writeTransaction.commit();
}
- protected void doCancel(final DOMDataWriteTransaction writeTransaction) {
- writeTransaction.cancel();
+ protected boolean doCancel(final DOMDataWriteTransaction writeTransaction) {
+ return writeTransaction.cancel();
}
protected ListenableFuture<Optional<DataObject>> doRead(final DOMDataReadTransaction readTransaction,
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataChangeListener;
import org.opendaylight.controller.md.sal.common.api.RegistrationListener;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
final InstanceIdentifier<? extends DataObject> path, final DataChangeListener listener) {
- BindingDataChangeListener asyncOperListener = new BackwardsCompatibleOperationalDataChangeInvoker(listener);
- BindingDataChangeListener asyncCfgListener = new BackwardsCompatibleConfigurationDataChangeInvoker(listener);
+ org.opendaylight.controller.md.sal.binding.api.DataChangeListener asyncOperListener = new BackwardsCompatibleOperationalDataChangeInvoker(listener);
+ org.opendaylight.controller.md.sal.binding.api.DataChangeListener asyncCfgListener = new BackwardsCompatibleConfigurationDataChangeInvoker(listener);
- ListenerRegistration<BindingDataChangeListener> cfgReg = registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, asyncCfgListener, DataChangeScope.SUBTREE);
- ListenerRegistration<BindingDataChangeListener> operReg = registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, path, asyncOperListener, DataChangeScope.SUBTREE);
+ ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> cfgReg = registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, path, asyncCfgListener, DataChangeScope.SUBTREE);
+ ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> operReg = registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, path, asyncOperListener, DataChangeScope.SUBTREE);
return new LegacyListenerRegistration(listener,cfgReg,operReg);
}
private static final class LegacyListenerRegistration implements ListenerRegistration<DataChangeListener> {
private final DataChangeListener instance;
- private final ListenerRegistration<BindingDataChangeListener> cfgReg;
- private final ListenerRegistration<BindingDataChangeListener> operReg;
+ private final ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> cfgReg;
+ private final ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> operReg;
public LegacyListenerRegistration(final DataChangeListener listener,
- final ListenerRegistration<BindingDataChangeListener> cfgReg,
- final ListenerRegistration<BindingDataChangeListener> operReg) {
+ final ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> cfgReg,
+ final ListenerRegistration<org.opendaylight.controller.md.sal.binding.api.DataChangeListener> operReg) {
this.instance = listener;
this.cfgReg = cfgReg;
this.operReg = operReg;
}
- private static class BackwardsCompatibleOperationalDataChangeInvoker implements BindingDataChangeListener, Delegator<DataChangeListener> {
+ private static class BackwardsCompatibleOperationalDataChangeInvoker implements org.opendaylight.controller.md.sal.binding.api.DataChangeListener, Delegator<DataChangeListener> {
private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<?,?> delegate;
}
- private static class BackwardsCompatibleConfigurationDataChangeInvoker implements BindingDataChangeListener, Delegator<DataChangeListener> {
+ private static class BackwardsCompatibleConfigurationDataChangeInvoker implements org.opendaylight.controller.md.sal.binding.api.DataChangeListener, Delegator<DataChangeListener> {
private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener<?,?> delegate;
public BackwardsCompatibleConfigurationDataChangeInvoker(final DataChangeListener listener) {
*/
package org.opendaylight.controller.md.sal.binding.impl;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataBroker;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataReadTransaction;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataWriteTransaction;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
* NormalizedNode once the MappingService is updated
*
*/
-public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements BindingDataBroker {
+public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker implements DataBroker {
public ForwardedBindingDataBroker(final DOMDataBroker domDataBroker, final BindingIndependentMappingService mappingService, final SchemaService schemaService) {
super(domDataBroker, mappingService,schemaService);
}
@Override
- public BindingDataReadTransaction newReadOnlyTransaction() {
+
+ public ReadOnlyTransaction newReadOnlyTransaction() {
return new BindingDataReadTransactionImpl(getDelegate().newReadOnlyTransaction(),getCodec());
}
@Override
- public BindingDataReadWriteTransaction newReadWriteTransaction() {
+ public ReadWriteTransaction newReadWriteTransaction() {
return new BindingDataReadWriteTransactionImpl(getDelegate().newReadWriteTransaction(),getCodec());
}
@Override
- public BindingDataWriteTransaction newWriteOnlyTransaction() {
+ public WriteTransaction newWriteOnlyTransaction() {
return new BindingDataWriteTransactionImpl<DOMDataWriteTransaction>(getDelegate().newWriteOnlyTransaction(),getCodec());
}
return getDelegate().getIdentifier();
}
- @Override
- public void close() {
- getDelegate().close();
- }
-
}
- private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadTransaction> implements
- BindingDataReadTransaction {
- protected BindingDataReadTransactionImpl(final DOMDataReadTransaction delegate,
+ private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadOnlyTransaction> implements
+ ReadOnlyTransaction {
+
+ protected BindingDataReadTransactionImpl(final DOMDataReadOnlyTransaction delegate,
final BindingToNormalizedNodeCodec codec) {
super(delegate, codec);
}
final InstanceIdentifier<?> path) {
return doRead(getDelegate(), store, path);
}
+
+ @Override
+ public void close() {
+ getDelegate().close();
+ }
}
private class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
- AbstractBindingTransaction<T> implements BindingDataWriteTransaction {
+ AbstractBindingTransaction<T> implements WriteTransaction {
protected BindingDataWriteTransactionImpl(final T delegate, final BindingToNormalizedNodeCodec codec) {
super(delegate, codec);
}
@Override
- public void cancel() {
- doCancel(getDelegate());
+ public boolean cancel() {
+ return doCancel(getDelegate());
}
@Override
}
private class BindingDataReadWriteTransactionImpl extends
- BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements BindingDataReadWriteTransaction {
+ BindingDataWriteTransactionImpl<DOMDataReadWriteTransaction> implements ReadWriteTransaction {
protected BindingDataReadWriteTransactionImpl(final DOMDataReadWriteTransaction delegate,
final BindingToNormalizedNodeCodec codec) {
import static com.google.common.base.Preconditions.checkState;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.util.AbstractBindingSalProviderInstance;
import org.opendaylight.controller.md.sal.binding.util.BindingContextUtils;
import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
private DataProviderService legacyDataBroker;
- private BindingDataBroker dataBroker;
+ private DataBroker dataBroker;
private MountPointManagerImpl mountManager;
consBuilder.put(DataBrokerService.class, getRoot());
consBuilder.put(RpcConsumerRegistry.class, getRoot());
if(dataBroker != null) {
- consBuilder.put(BindingDataBroker.class, dataBroker);
+ consBuilder.put(DataBroker.class, dataBroker);
}
consBuilder.put(MountService.class, mountManager).build();
supportedConsumerServices = consBuilder.build();
}
}
- public void setDataBroker(final BindingDataBroker asyncDataBroker) {
+ public void setDataBroker(final DataBroker asyncDataBroker) {
dataBroker = asyncDataBroker;
}
}
identity binding-async-data-broker {
base "config:service-type";
- config:java-class "org.opendaylight.controller.md.sal.binding.api.BindingDataBroker";
+ config:java-class "org.opendaylight.controller.md.sal.binding.api.DataBroker";
}
identity binding-data-consumer-broker {
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.Lists;
private NormalizedNode<?, ?> resolveDataAsserted(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
- try (DOMDataReadTransaction readTx = testContext.getDomAsyncDataBroker().newReadOnlyTransaction()){
+ try (DOMDataReadOnlyTransaction readTx = testContext.getDomAsyncDataBroker().newReadOnlyTransaction()){
ListenableFuture<Optional<NormalizedNode<?, ?>>> data = readTx.read(LogicalDatastoreType.OPERATIONAL, domPath);
Optional<NormalizedNode<?, ?>> potential = data.get();
assertTrue(potential.isPresent());
</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>
/**
*
- * Provides access to a conceptual data tree store.
+ * Base interface that provides access to a conceptual data tree store and also provides the ability to
+ * subscribe for changes to data under a given branch of the tree.
*
* <p>
- * Also provides the ability to subscribe for changes to data under a given
- * branch of the tree.
- *
- * <p>
- * All operations on data tree are performed via one of the transactions:
+ * All operations on the data tree are performed via one of the transactions:
* <ul>
* <li>Read-Only - allocated using {@link #newReadOnlyTransaction()}
* <li>Write-Only - allocated using {@link #newWriteOnlyTransaction()}
* {@inheritDoc}
*/
@Override
- public AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ public AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
* {@inheritDoc}
*
* @return new read-only transaction
*/
- AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
* Allocates new read-write transaction which provides a mutable view of the data
--- /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.md.sal.common.api.data;
+
+import org.opendaylight.yangtools.concepts.Path;
+
+/**
+ * Read-only transaction, which provides stable view of data
+ * and is {@link AutoCloseable} resource.
+ *
+ * @see AsyncReadTransaction
+ *
+* @param <P>
+ * Type of path (subtree identifier), which represents location in
+ * tree
+ * @param <D>
+ * Type of data (payload), which represents data payload
+ */
+public interface AsyncReadOnlyTransaction<P extends Path<P>, D> extends AsyncReadTransaction<P, D>, AutoCloseable {
+
+ /**
+ * Closes this transaction and releases all resources associated with it.
+ *
+ */
+ @Override
+ public void close();
+}
/**
*
- * Provides a stateful read-only view of the data tree.
+ * Provides a stateful read view of the data tree.
*
* <p>
* View of the data tree is a stable point-in-time snapshot of the current data tree state when
* <b>Implementation Note:</b> This interface is not intended to be implemented
* by users of MD-SAL, but only to be consumed by them.
*
- * <h2>Transaction isolation example</h2> Lest assume initial state of data tree
- * for <code>PATH</code> is <code>A</code>.
+ * <h2>Transaction isolation example</h2>
+ * Lets assume initial state of data tree for <code>PATH</code> is <code>A</code>.
*
* <pre>
* txRead = broker.newReadOnlyTransaction(); // read Transaction is snapshot of data
* or other functions from {@link com.google.common.util.concurrent.Futures} to
* register more specific listeners.
*
+ * @see AsyncReadTransaction
+ * @see AsyncWriteTransaction
*
* @param <P>
* Type of path (subtree identifier), which represents location in
* @param <D> Type of data (payload), which represents data payload
*/
public interface AsyncTransaction<P extends Path<P>,D> extends //
- Identifiable<Object>,
- AutoCloseable {
+ Identifiable<Object> {
@Override
public Object getIdentifier();
- /**
- * Closes transaction and releases all resources associated with it.
- */
- @Override
- public void close();
+
}
* {@link TransactionStatus#NEW} or {@link TransactionStatus#SUBMITED}
*
* Invoking cancel() on {@link TransactionStatus#FAILED} or
- * {@link TransactionStatus#CANCELED} will have no effect.
+ * {@link TransactionStatus#CANCELED} will have no effect, and transaction
+ * is considered cancelled.
*
- * @throws IllegalStateException
- * If transaction status is {@link TransactionStatus#COMMITED}
+ * Invoking cancel() on finished transaction (future returned by {@link #commit()}
+ * already completed with {@link TransactionStatus#COMMITED}) will always
+ * fail (return false).
+ *
+ * @return <tt>false</tt> if the task could not be cancelled,
+ * typically because it has already completed normally;
+ * <tt>true</tt> otherwise
*
*/
- public void cancel();
+ public boolean cancel();
/**
* Store a piece of data at specified path. This acts as an add / replace
*/
public void delete(LogicalDatastoreType store, P path);
- /**
- *
- * Closes transaction and resources allocated to the transaction.
- *
- * This call does not change Transaction status. Client SHOULD explicitly
- * {@link #commit()} or {@link #cancel()} transaction.
- *
- * @throws IllegalStateException
- * if the transaction has not been updated by invoking
- * {@link #commit()} or {@link #cancel()}.
- */
- @Override
- public void close();
-
/**
* Submits transaction to be applied to update logical data tree.
* <p>
* @throws TransactionChainClosedException if the chain has been closed.
*/
@Override
- public AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ public AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.AbstractMap;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
Collections.sort(unorderdChildData, new Comparator<LegacyNodeData>() {
@Override
public int compare(LegacyNodeData arg1, LegacyNodeData arg2) {
- String str1 = arg1.nodeKey.getLocalName();
- if (!(arg1.nodeData instanceof List))
- str1 += arg1.nodeData; // add simple node value
-
- String str2 = arg2.nodeKey.getLocalName();
- if (!(arg2.nodeData instanceof List))
- str2 += arg2.nodeData; // add simple node value
-
- return str1.compareTo(str2);
+ if (!(arg1.nodeData instanceof List) && !(arg2.nodeData instanceof List)) {
+ // if neither is a list, just compare them
+ String str1 = arg1.nodeKey.getLocalName() + arg1.nodeData;
+ String str2 = arg2.nodeKey.getLocalName() + arg2.nodeData;
+ return str1.compareTo(str2);
+ } else if (arg1.nodeData instanceof List && arg2.nodeData instanceof List) {
+ // if both are lists, first check their local name
+ String str1 = arg1.nodeKey.getLocalName();
+ String str2 = arg2.nodeKey.getLocalName();
+ if (!str1.equals(str2)) {
+ return str1.compareTo(str2);
+ } else {
+ // if local names are the same, then look at the list contents
+ List<LegacyNodeData> l1 = (List<LegacyNodeData>) arg1.nodeData;
+ List<LegacyNodeData> l2 = (List<LegacyNodeData>) arg2.nodeData;
+
+ if (l1.size() != l2.size()) {
+ // if the sizes are different, use that
+ return l2.size() - l1.size();
+ } else {
+ // lastly sort and recursively check the list contents
+ Collections.sort(l1, this);
+ Collections.sort(l2, this);
+
+ for (int i = 0 ; i < l1.size() ; i++) {
+ int diff = this.compare(l1.get(i), l2.get(i));
+ if (diff != 0) {
+ return diff;
+ }
+ }
+ return 0;
+ }
+ }
+ } else if( arg1.nodeData instanceof List ) {
+ return -1;
+ } else{
+ return 1;
+ }
}
});
Collections.sort(unorderedChildNodes, new Comparator<Node<?>>() {
@Override
public int compare(Node<?> n1, Node<?> n2) {
- String str1 = n1.getKey().getLocalName();
- if (n1 instanceof SimpleNode)
- str1 += ((SimpleNode<?>) n1).getValue();
-
- String str2 = n2.getKey().getLocalName();
- if (n2 instanceof SimpleNode)
- str2 += ((SimpleNode<?>) n2).getValue();
-
- return str1.compareTo(str2);
+ if (n1 instanceof SimpleNode && n2 instanceof SimpleNode) {
+ // if they're SimpleNodes just compare their strings
+ String str1 = n1.getKey().getLocalName() + ((SimpleNode<?>)n1).getValue();
+ String str2 = n2.getKey().getLocalName() + ((SimpleNode<?>)n2).getValue();
+ return str1.compareTo(str2);
+ } else if (n1 instanceof CompositeNode && n2 instanceof CompositeNode) {
+ // if they're CompositeNodes, things are more interesting
+ String str1 = n1.getKey().getLocalName();
+ String str2 = n2.getKey().getLocalName();
+ if (!str1.equals(str2)) {
+ // if their local names differ, return that difference
+ return str1.compareTo(str2);
+ } else {
+ // otherwise, we need to look at their contents
+ ArrayList<Node<?>> l1 = new ArrayList<Node<?>>( ((CompositeNode)n1).getValue() );
+ ArrayList<Node<?>> l2 = new ArrayList<Node<?>>( ((CompositeNode)n2).getValue() );
+
+ if (l1.size() != l2.size()) {
+ // if they have different numbers of things in them return that
+ return l2.size() - l1.size();
+ } else {
+ // otherwise, compare the individual elements, first sort them
+ Collections.sort(l1, this);
+ Collections.sort(l2, this);
+
+ // then compare them individually
+ for(int i = 0 ; i < l2.size() ; i++) {
+ int diff = this.compare(l1.get(i), l2.get(i));
+ if(diff != 0){
+ return diff;
+ }
+ }
+ return 0;
+ }
+ }
+ } else if (n1 instanceof CompositeNode && n2 instanceof SimpleNode) {
+ return -1;
+ } else if (n2 instanceof CompositeNode && n1 instanceof SimpleNode) {
+ return 1;
+ } else {
+ assertTrue("Expected either SimpleNodes CompositeNodes", false);
+ return 0;
+ }
}
});
* {@inheritDoc}
*/
@Override
- DOMDataReadTransaction newReadOnlyTransaction();
+ DOMDataReadOnlyTransaction newReadOnlyTransaction();
/**
* {@inheritDoc}
--- /dev/null
+package org.opendaylight.controller.md.sal.dom.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncReadOnlyTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface DOMDataReadOnlyTransaction extends DOMDataReadTransaction, AsyncReadOnlyTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+
+}
public interface DOMTransactionChain extends TransactionChain<InstanceIdentifier, NormalizedNode<?, ?>> {
@Override
- DOMDataReadTransaction newReadOnlyTransaction();
+ DOMDataReadOnlyTransaction newReadOnlyTransaction();
@Override
DOMDataReadWriteTransaction newReadWriteTransaction();
return identifier;
}
- @Override
- public void close() {
+ protected void closeSubtransactions() {
/*
* We share one exception for all failures, which are added
* as supressedExceptions to it.
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
*
* Subtransaction for reading is selected by supplied
* {@link LogicalDatastoreType} as parameter for
- * {@link DOMDataReadTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
+ * {@link DOMDataReadOnlyTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
* .
*
* Id of returned transaction is retrieved via
*
* @return New composite read-only transaction.
*/
- public DOMDataReadTransaction newReadOnlyTransaction() {
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
checkNotClosed();
ImmutableMap.Builder<LogicalDatastoreType, DOMStoreReadTransaction> builder = ImmutableMap.builder();
for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
package org.opendaylight.controller.md.sal.dom.broker.impl;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
*/
class DOMForwardedReadOnlyTransaction extends
AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, DOMStoreReadTransaction> implements
- DOMDataReadTransaction {
+ DOMDataReadOnlyTransaction {
protected DOMForwardedReadOnlyTransaction(final Object identifier,
final ImmutableMap<LogicalDatastoreType, DOMStoreReadTransaction> backingTxs) {
return getSubtransaction(store).read(path);
}
+ @Override
+ public void close() {
+ closeSubtransactions();
+ }
+
}
class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, T> implements DOMDataWriteTransaction {
+ /**
+ * Implementation of real commit.
+ *
+ * Transaction can not be commited if commitImpl is null,
+ * so this seting this property to null is also used to
+ * prevent write to
+ * already commited / canceled transaction {@link #checkNotCanceled()
+ *
+ *
+ */
@GuardedBy("this")
- private DOMDataCommitImplementation commitImpl;
-
- @GuardedBy("this")
- private boolean canceled;
+ private volatile DOMDataCommitImplementation commitImpl;
+
+ /**
+ *
+ * Future task of transaction commit.
+ *
+ * This value is initially null, and is once updated if transaction
+ * is commited {@link #commit()}.
+ * If this future exists, transaction MUST not be commited again
+ * and all modifications should fail. See {@link #checkNotCommited()}.
+ *
+ */
@GuardedBy("this")
- private ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
+ private volatile ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
protected DOMForwardedWriteTransaction(final Object identifier,
final ImmutableMap<LogicalDatastoreType, T> backingTxs, final DOMDataCommitImplementation commitImpl) {
}
@Override
- public synchronized void cancel() {
- checkState(!canceled, "Transaction was canceled.");
- if (commitFuture != null) {
- // FIXME: Implement cancelation of commit future
- // when Broker impl will support cancelation.
- throw new UnsupportedOperationException("Not implemented yet.");
+ public synchronized boolean cancel() {
+ // Transaction is already canceled, we are safe to return true
+ final boolean cancelationResult;
+ if (commitImpl == null && commitFuture != null) {
+ // Transaction is submitted, we try to cancel future.
+ cancelationResult = commitFuture.cancel(false);
+ } else if(commitImpl == null) {
+ return true;
+ } else {
+ cancelationResult = true;
+ commitImpl = null;
}
- canceled = true;
- commitImpl = null;
+ return cancelationResult;
}
}
ImmutableList<DOMStoreThreePhaseCommitCohort> cohorts = cohortsBuilder.build();
commitFuture = commitImpl.commit(this, cohorts);
+
+ /*
+ *We remove reference to Commit Implementation in order
+ *to prevent memory leak
+ */
+ commitImpl = null;
return commitFuture;
}
private void checkNotReady() {
- checkNotCanceled();
checkNotCommited();
+ checkNotCanceled();
}
private void checkNotCanceled() {
- Preconditions.checkState(!canceled, "Transaction was canceled.");
+ Preconditions.checkState(commitImpl != null, "Transaction was canceled.");
}
private void checkNotCommited() {
- checkState(commitFuture == null, "Transaction was already commited.");
+ checkState(commitFuture == null, "Transaction was already submited.");
}
}
\ No newline at end of file
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
this.normalizer = normalizer;
}
- public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadTransaction readTx,
+ public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadOnlyTransaction readTx,
final DataNormalizer normalizer) {
- return new BackwardsCompatibleTransaction<DOMDataReadTransaction>(readTx, normalizer) {
+ return new BackwardsCompatibleTransaction<DOMDataReadOnlyTransaction>(readTx, normalizer) {
@Override
public TransactionStatus getStatus() {
import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
}
@Override
- public DOMDataReadTransaction newReadOnlyTransaction() {
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
return getDelegate().newReadOnlyTransaction();
}
import java.io.File;
import java.io.InputStream;
-import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfiguration;
import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder;
import org.opendaylight.protocol.framework.ReconnectStrategy;
import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
import org.opendaylight.protocol.framework.TimedReconnectStrategy;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider;
import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProviders;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-import com.google.common.net.InetAddresses;
-import io.netty.util.HashedWheelTimer;
-
/**
*
*/
@Override
protected void customValidation() {
checkNotNull(getAddress(), addressJmxAttribute);
+ checkCondition(isHostAddressPresent(getAddress()), "Host address not present in " + getAddress(), addressJmxAttribute);
checkNotNull(getPort(), portJmxAttribute);
checkNotNull(getDomRegistry(), portJmxAttribute);
checkNotNull(getDomRegistry(), domRegistryJmxAttribute);
checkNotNull(getBetweenAttemptsTimeoutMillis(), betweenAttemptsTimeoutMillisJmxAttribute);
checkCondition(getBetweenAttemptsTimeoutMillis() > 0, "must be > 0", betweenAttemptsTimeoutMillisJmxAttribute);
- // FIXME BUG-944 remove backwards compatibility
- if(getClientDispatcher() == null) {
- checkCondition(getBossThreadGroup() != null, "Client dispatcher was not set, thread groups have to be set instead", bossThreadGroupJmxAttribute);
- checkCondition(getWorkerThreadGroup() != null, "Client dispatcher was not set, thread groups have to be set instead", workerThreadGroupJmxAttribute);
- }
+ checkNotNull(getClientDispatcher(), clientDispatcherJmxAttribute);
+ checkNotNull(getBindingRegistry(), bindingRegistryJmxAttribute);
+ checkNotNull(getProcessingExecutor(), processingExecutorJmxAttribute);
// Check username + password in case of ssh
if(getTcpOnly() == false) {
checkNotNull(getPassword(), passwordJmxAttribute);
}
- // FIXME BUG 944 remove this warning
- if(getBindingRegistry() == null) {
- logger.warn("Configuration property: \"binding-registry\" not set for sal-netconf-connector (" + getIdentifier() + "). " +
- "Netconf-connector now requires a dependency on \"binding-broker-osgi-registry\". " +
- "The dependency is optional for now to preserve backwards compatibility, but will be mandatory in the future. " +
- "Please set the property as in \"01-netconf-connector\" initial config file. " +
- "The service will be retrieved from OSGi service registry now.");
- }
+ }
- // FIXME BUG 944 remove this warning
- if(getProcessingExecutor() == null) {
- logger.warn("Configuration property: \"processing-executor\" not set for sal-netconf-connector (" + getIdentifier() + "). " +
- "Netconf-connector now requires a dependency on \"threadpool\". " +
- "The dependency is optional for now to preserve backwards compatibility, but will be mandatory in the future. " +
- "Please set the property as in \"01-netconf-connector\" initial config file. " +
- "New instance will be created for the executor.");
- }
+ private boolean isHostAddressPresent(Host address) {
+ return address.getDomainName() != null ||
+ address.getIpAddress() != null && (address.getIpAddress().getIpv4Address() != null || address.getIpAddress().getIpv6Address() != null);
}
@Override
public java.lang.AutoCloseable createInstance() {
final RemoteDeviceId id = new RemoteDeviceId(getIdentifier());
- final ExecutorService globalProcessingExecutor = getGlobalProcessingExecutor();
+ final ExecutorService globalProcessingExecutor = getProcessingExecutorDependency().getExecutor();
final Broker domBroker = getDomRegistryDependency();
- final BindingAwareBroker bindingBroker = getBindingRegistryBackwards();
+ final BindingAwareBroker bindingBroker = getBindingRegistryDependency();
final RemoteDeviceHandler salFacade = new NetconfDeviceSalFacade(id, domBroker, bindingBroker, bundleContext, globalProcessingExecutor);
final NetconfDevice device =
final NetconfDeviceCommunicator listener = new NetconfDeviceCommunicator(id, device);
final NetconfReconnectingClientConfiguration clientConfig = getClientConfig(listener);
- // FIXME BUG-944 remove backwards compatibility
- final NetconfClientDispatcher dispatcher = getClientDispatcher() == null ? createDispatcher() : getClientDispatcherDependency();
+ final NetconfClientDispatcher dispatcher = getClientDispatcherDependency();
listener.initializeRemoteConnection(dispatcher, clientConfig);
return new AutoCloseable() {
};
}
- private BindingAwareBroker getBindingRegistryBackwards() {
- if(getBindingRegistry() != null) {
- return getBindingRegistryDependency();
- } else {
- // FIXME BUG 944 remove backwards compatibility
- final ServiceReference<BindingAwareBroker> serviceReference = bundleContext.getServiceReference(BindingAwareBroker.class);
- Preconditions
- .checkNotNull(
- serviceReference,
- "Unable to retrieve %s from OSGi service registry, use binding-registry config property to inject %s with config subsystem",
- BindingAwareBroker.class, BindingAwareBroker.class);
- return bundleContext.getService(serviceReference);
- }
- }
-
- private ExecutorService getGlobalProcessingExecutor() {
- if(getProcessingExecutor() != null) {
- return getProcessingExecutorDependency().getExecutor();
- } else {
- // FIXME BUG 944 remove backwards compatibility
- return Executors.newCachedThreadPool();
- }
- }
-
private synchronized AbstractCachingSchemaSourceProvider<String, InputStream> getGlobalNetconfSchemaProvider() {
if(GLOBAL_NETCONF_SOURCE_PROVIDER == null) {
final String storageFile = "cache/schema";
return GLOBAL_NETCONF_SOURCE_PROVIDER;
}
- // FIXME BUG-944 remove backwards compatibility
- /**
- * @deprecated Use getClientDispatcherDependency method instead to retrieve injected dispatcher.
- * This one creates new instance of NetconfClientDispatcher and will be removed in near future.
- */
- @Deprecated
- private NetconfClientDispatcher createDispatcher() {
- return new NetconfClientDispatcherImpl(getBossThreadGroupDependency(), getWorkerThreadGroupDependency(), new HashedWheelTimer());
- }
-
public void setBundleContext(final BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
}
private InetSocketAddress getSocketAddress() {
- /*
- * Uncomment after Switch to IP Address
- if(getAddress().getIpv4Address() != null) {
- addressValue = getAddress().getIpv4Address().getValue();
+ if(getAddress().getDomainName() != null) {
+ return new InetSocketAddress(getAddress().getDomainName().getValue(), getPort().getValue());
} else {
- addressValue = getAddress().getIpv6Address().getValue();
+ IpAddress ipAddress = getAddress().getIpAddress();
+ String ip = ipAddress.getIpv4Address() != null ? ipAddress.getIpv4Address().getValue() : ipAddress.getIpv6Address().getValue();
+ return new InetSocketAddress(ip, getPort().getValue());
}
- */
- final InetAddress inetAddress = InetAddresses.forString(getAddress());
- return new InetSocketAddress(inetAddress, getPort().intValue());
}
}
Thread.currentThread().interrupt();
throw new RuntimeException(id + ": Interrupted while waiting for response", e);
} catch (final ExecutionException e) {
- logger.warn("%s: Error executing pre commit operation on remote device", id, e);
+ logger.warn("{}: Error executing pre commit operation on remote device", id, e);
return new FailingTransaction(twoPhaseCommit, e);
}
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CANDIDATE_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_COMMIT_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_CONFIG_QNAME;
+import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_DEFAULT_OPERATION_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_EDIT_CONFIG_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_ERROR_OPTION_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_OPERATION_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.NETCONF_TARGET_QNAME;
import static org.opendaylight.controller.sal.connect.netconf.util.NetconfMessageTransformUtil.ROLLBACK_ON_ERROR_OPTION;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
-
import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
import org.opendaylight.controller.md.sal.common.api.data.DataModification;
import org.opendaylight.controller.sal.common.util.RpcErrors;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
+import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
import org.opendaylight.yangtools.yang.data.impl.util.CompositeNodeBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-
/**
* Remote transaction that delegates data change to remote device using netconf messages.
*/
}
private void sendMerge(final InstanceIdentifier key, final CompositeNode value) throws InterruptedException, ExecutionException {
- sendEditRpc(createEditConfigStructure(key, Optional.<String>absent(), Optional.of(value)));
+ sendEditRpc(createEditConfigStructure(key, Optional.<String>absent(), Optional.of(value)), Optional.<String>absent());
}
private void sendDelete(final InstanceIdentifier toDelete) throws InterruptedException, ExecutionException {
- sendEditRpc(createEditConfigStructure(toDelete, Optional.of("delete"), Optional.<CompositeNode>absent()));
+ // FIXME use org.opendaylight.yangtools.yang.data.api.ModifyAction instead of strings
+ // TODO add string lowercase value to ModifyAction enum entries
+ sendEditRpc(createEditConfigStructure(toDelete, Optional.of("delete"), Optional.<CompositeNode>absent()), Optional.of("none"));
}
- private void sendEditRpc(final CompositeNode editStructure) throws InterruptedException, ExecutionException {
- final ImmutableCompositeNode editConfigRequest = createEditConfigRequest(editStructure);
+ private void sendEditRpc(final CompositeNode editStructure, final Optional<String> defaultOperation) throws InterruptedException, ExecutionException {
+ final ImmutableCompositeNode editConfigRequest = createEditConfigRequest(editStructure, defaultOperation);
final RpcResult<CompositeNode> rpcResult = rpc.invokeRpc(NETCONF_EDIT_CONFIG_QNAME, editConfigRequest).get();
- // TODO 874 add default operation when sending delete
// Check result
if(rpcResult.isSuccessful() == false) {
}
}
- private ImmutableCompositeNode createEditConfigRequest(final CompositeNode editStructure) {
+ private ImmutableCompositeNode createEditConfigRequest(final CompositeNode editStructure, Optional<String> defaultOperation) {
final CompositeNodeBuilder<ImmutableCompositeNode> ret = ImmutableCompositeNode.builder();
+ // Target
final Node<?> targetWrapperNode = ImmutableCompositeNode.create(NETCONF_TARGET_QNAME, ImmutableList.<Node<?>>of(targetNode));
ret.add(targetWrapperNode);
+ // Default operation
+ if(defaultOperation.isPresent()) {
+ SimpleNode<String> defOp = NodeFactory.createImmutableSimpleNode(NETCONF_DEFAULT_OPERATION_QNAME, null, defaultOperation.get());
+ ret.add(defOp);
+ }
+
+ // Error option
if(rollbackSupported) {
ret.addLeaf(NETCONF_ERROR_OPTION_QNAME, ROLLBACK_ON_ERROR_OPTION);
}
+
ret.setQName(NETCONF_EDIT_CONFIG_QNAME);
+ // Edit content
ret.add(editStructure);
return ret.toInstance();
}
final DataNodeContainer schemaForEdit = NetconfMessageTransformUtil.createSchemaForEdit(schemaContext.get());
w3cPayload = XmlDocumentUtils.toDocument(rpcPayload, schemaForEdit, codecProvider);
} else {
+ // FIXME get and get-config needs schema as well to transform filter using schema context
+ // e.g. Identityref nodes in filter fail to serialize properly to xml without schema
w3cPayload = XmlDocumentUtils.toDocument(rpcPayload, schemaContext.get(), codecProvider);
}
} else {
private NetconfMessageTransformUtil() {
}
- public static final QName IETF_NETCONF_MONITORING = QName.create(
- "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
+ public static final QName IETF_NETCONF_MONITORING = QName.create("urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", "2010-10-04", "ietf-netconf-monitoring");
public static URI NETCONF_URI = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0");
public static QName NETCONF_QNAME = QName.create(NETCONF_URI, null, "netconf");
public static QName NETCONF_DATA_QNAME = QName.create(NETCONF_QNAME, "data");
public static QName NETCONF_RPC_REPLY_QNAME = QName.create(NETCONF_QNAME, "rpc-reply");
public static QName NETCONF_ERROR_OPTION_QNAME = QName.create(NETCONF_QNAME, "error-option");
public static QName NETCONF_RUNNING_QNAME = QName.create(NETCONF_QNAME, "running");
- static List<Node<?>> RUNNING = Collections.<Node<?>> singletonList(new SimpleNodeTOImpl<>(NETCONF_RUNNING_QNAME,
- null, null));
+ static List<Node<?>> RUNNING = Collections.<Node<?>> singletonList(new SimpleNodeTOImpl<>(NETCONF_RUNNING_QNAME, null, null));
public static QName NETCONF_SOURCE_QNAME = QName.create(NETCONF_QNAME, "source");
public static CompositeNode CONFIG_SOURCE_RUNNING = new CompositeNodeTOImpl(NETCONF_SOURCE_QNAME, null, RUNNING);
public static QName NETCONF_CANDIDATE_QNAME = QName.create(NETCONF_QNAME, "candidate");
public static QName NETCONF_CONFIG_QNAME = QName.create(NETCONF_QNAME, "config");
public static QName NETCONF_COMMIT_QNAME = QName.create(NETCONF_QNAME, "commit");
public static QName NETCONF_OPERATION_QNAME = QName.create(NETCONF_QNAME, "operation");
+ public static QName NETCONF_DEFAULT_OPERATION_QNAME = QName.create(NETCONF_OPERATION_QNAME, "default-operation");
public static QName NETCONF_EDIT_CONFIG_QNAME = QName.create(NETCONF_QNAME, "edit-config");
public static QName NETCONF_GET_CONFIG_QNAME = QName.create(NETCONF_QNAME, "get-config");
public static QName NETCONF_TYPE_QNAME = QName.create(NETCONF_QNAME, "type");
import opendaylight-md-sal-dom {prefix dom;}
import opendaylight-md-sal-binding {prefix md-sal-binding; revision-date 2013-10-28;}
import odl-netconf-cfg { prefix cfg-net; revision-date 2014-04-08; }
+ import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
description
"Service definition for Binding Aware MD-SAL.";
when "/config:modules/config:module/config:type = 'sal-netconf-connector'";
leaf address {
- type string;
+ type inet:host;
}
leaf port {
- type uint32;
+ type inet:port-number;
}
leaf tcp-only {
container binding-registry {
uses config:service-ref {
refine type {
- // FIXME BUG-944 make mandatory (remove backwards compatibility)
- mandatory false;
+ mandatory true;
config:required-identity md-sal-binding:binding-broker-osgi-registry;
}
}
}
- // FIXME BUG-944 remove backwards compatibility
- // Deprecated, replaced by client dispatcher.
- // This dependency will be removed in near future and all configurations of netconf-connector need to be changed to use dispatcher dependency.
- container boss-thread-group {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
- // FIXME BUG-944 remove backwards compatibility
- // Deprecated, replaced by client dispatcher.
- // This dependency will be removed in near future and all configurations of netconf-connector need to be changed to use dispatcher dependency.
- container worker-thread-group {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity netty:netty-threadgroup;
- }
- }
- }
-
container event-executor {
uses config:service-ref {
refine type {
+ mandatory true;
config:required-identity netty:netty-event-executor;
}
}
container processing-executor {
uses config:service-ref {
refine type {
- // FIXME BUG-944 make mandatory (remove backwards compatibility)
- mandatory false;
+ mandatory true;
config:required-identity th:threadpool;
}
}
description "Makes up for flaws in netty threading design";
}
- // Replaces thread group dependencies
container client-dispatcher {
uses config:service-ref {
refine type {
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
-
- <artifactId>sal-remoterpc-connector</artifactId>
- <packaging>bundle</packaging>
-
- <properties>
- <stax.version>1.0.1</stax.version>
- <zeromq.version>0.3.1</zeromq.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-common-util</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-connector-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <!-- MD Sal interdependencies -->
- <dependency>
- <groupId>${project.groupId}</groupId>
- <artifactId>sal-core-api</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
-
- <!-- Tests -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <!-- AD Sal -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
-
- <!-- Yang tools -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
-
- <!-- Third Party -->
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- <version>${zeromq.version}</version>
- </dependency>
-
- <dependency>
- <groupId>stax</groupId>
- <artifactId>stax-api</artifactId>
- <version>${stax.version}</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>*,
- !org.codehaus.enunciate.jaxrs</Import-Package>
- <Export-Package>org.opendaylight.controller.config.yang.md.sal.remote.rpc,
- 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>
- </configuration>
- </plugin>
-
- <plugin>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-maven-plugin</artifactId>
- <executions>
- <execution>
- <goals>
- <goal>generate-sources</goal>
- </goals>
- <configuration>
- <codeGenerators>
- <generator>
- <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
- <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
- <additionalConfiguration>
- <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
- </additionalConfiguration>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>${salGeneratorPath}</outputBaseDir>
- </generator>
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>target/site/models</outputBaseDir>
- </generator>
-
- <generator>
- <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
- <outputBaseDir>target/site/models</outputBaseDir>
- </generator>
- </codeGenerators>
- <inspectDependencies>true</inspectDependencies>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
+++ /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.config.yang.md.sal.remote.rpc;
-
-import org.opendaylight.controller.sal.connector.remoterpc.ClientImpl;
-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.core.api.Broker;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-import org.osgi.framework.BundleContext;
-
-/**
- *
- */
-public final class ZeroMQServerModule
-extends org.opendaylight.controller.config.yang.md.sal.remote.rpc.AbstractZeroMQServerModule {
-
- private static final Integer ZEROMQ_ROUTER_PORT = 5554;
- private BundleContext bundleContext;
-
- public ZeroMQServerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
- final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public ZeroMQServerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier,
- final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver,
- final ZeroMQServerModule oldModule, final java.lang.AutoCloseable oldInstance) {
-
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- protected void customValidation() {
- // Add custom validation for module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
-
- Broker broker = getDomBrokerDependency();
-
- final int port = getPort() != null ? getPort() : ZEROMQ_ROUTER_PORT;
-
- ServerImpl serverImpl = new ServerImpl(port);
-
- ClientImpl clientImpl = new ClientImpl();
-
- RoutingTableProvider provider = new RoutingTableProvider(bundleContext);//,serverImpl);
-
- RemoteRpcProvider facade = new RemoteRpcProvider(serverImpl, clientImpl);
- facade.setRoutingTableProvider(provider);
- facade.setContext(bundleContext);
- facade.setRpcProvisionRegistry((RpcProvisionRegistry) broker);
-
- broker.registerProvider(facade, bundleContext);
- return facade;
- }
-
- public void setBundleContext(final BundleContext bundleContext) {
- this.bundleContext = bundleContext;
- }
-}
+++ /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.config.yang.md.sal.remote.rpc;
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-
-/**
-*
-*/
-public class ZeroMQServerModuleFactory extends org.opendaylight.controller.config.yang.md.sal.remote.rpc.AbstractZeroMQServerModuleFactory
-{
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
- ZeroMQServerModule module = (ZeroMQServerModule) super.createModule(instanceName, dependencyResolver, bundleContext);
- module.setBundleContext(bundleContext);
- return module;
- }
-
- @Override
- public Module createModule(String instanceName, DependencyResolver dependencyResolver,
- DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
- ZeroMQServerModule module = (ZeroMQServerModule) super.createModule(instanceName, dependencyResolver, old,bundleContext);
- module.setBundleContext(bundleContext);
- return module;
- }
-}
+++ /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 static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-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.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.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * An implementation of {@link org.opendaylight.controller.sal.core.api.RpcImplementation} that makes
- * remote RPC calls
- */
-public class ClientImpl implements RemoteRpcClient {
-
- private final Logger _logger = LoggerFactory.getLogger(ClientImpl.class);
-
- private final ZMQ.Context context = ZMQ.context(1);
- private final 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;
- }
-
- @Override
- public void setRoutingTableProvider(RoutingTableProvider routingTableProvider) {
- this.routingTableProvider = routingTableProvider;
- }
-
- @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
- */
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- String address = lookupRemoteAddressForGlobalRpc(routeId);
- return sendMessage(input, routeId, address);
- }
-
- /**
- * Finds remote server that can execute this routed 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
- * rpc to be called
- * @param identifier
- * instance identifier on which rpc is to be executed
- * @param input
- * payload
- * @return
- */
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
-
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
- routeId.setRoute(identifier);
-
- String address = lookupRemoteAddressForRpc(routeId);
-
- return sendMessage(input, routeId, address);
- }
-
- private ListenableFuture<RpcResult<CompositeNode>> sendMessage(CompositeNode input, RouteIdentifierImpl routeId, String address) {
- 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 ) {
-
- _logger.info("Received response [{}]", response);
-
- Object rawPayload = response.getPayload();
- switch (response.getType()) {
- case ERROR:
- if ( rawPayload instanceof List )
- errors = (List) rawPayload;
- break;
-
- case RESPONSE:
- payload = XmlUtils.xmlToCompositeNode((String) rawPayload);
- break;
-
- default:
- errors.add(
- RpcErrors.getRpcError(null, null,null,null,"Unable to get response from remote controller", null, null)
- );
- break;
-
- }
- }
- return Futures.immediateFuture(Rpcs.getRpcResult(true, payload, errors));
-
- } catch (Exception e){
- collectErrors(e, errors);
- return Futures.immediateFuture(Rpcs.<CompositeNode>getRpcResult(false, null, errors));
- }
- }
-
- /**
- * Find address for the given route identifier in routing table
- * @param routeId route identifier
- * @return remote network address
- */
- private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier<?, ?, ?> routeId){
- checkNotNull(routeId, "route must not be null");
-
- Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable = routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
-
- String address = null;
- try {
- address = routingTable.get().getGlobalRoute(routeId);
- } catch (RoutingTableException|SystemException e) {
- _logger.error("Exception caught while looking up remote address " + e);
- }
- checkState(address != null, "Address not found for route [%s]", routeId);
-
- return address;
- }
-
- /**
- * Find address for the given route identifier in routing table
- * @param routeId route identifier
- * @return remote network address
- */
- private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier<?, ?, ?> routeId){
- checkNotNull(routeId, "route must not be null");
-
- Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable = routingTableProvider.getRoutingTable();
- checkNotNull(routingTable.isPresent(), "Routing table is null");
-
- String address = routingTable.get().getLastAddedRoute(routeId);
- checkState(address != null, "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<Void>(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 {
- String inProcessSocketAddress = INPROC_PROTOCOL_PREFIX + address;
- socket.connect( inProcessSocketAddress );
- _logger.debug("Sending request [{}]", request);
- socket.send(Message.serialize(request));
- _logger.info("Request sent. Waiting for reply...");
- byte[] reply = socket.recv(0);
- _logger.info("Response received");
- response = (Message) Message.deserialize(reply);
- _logger.debug("Response [{}]", response);
- } 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; //<serverip: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...");
- }
- }
- }
-}
+++ /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 java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Enumeration;
-
-import org.zeromq.ZMQ;
-
-/**
- * Provides a ZeroMQ Context object
- */
-public class Context {
- private final ZMQ.Context zmqContext = ZMQ.context(1);
- private String uri;
- private final String DEFAULT_RPC_PORT = "5554";
-
- private static Context _instance = new Context();
-
- private Context() {}
-
- public static Context getInstance(){
- return _instance;
- }
-
- public ZMQ.Context getZmqContext(){
- return this.zmqContext;
- }
-
- public String getLocalUri(){
- uri = (uri != null) ? uri
- : new StringBuilder().append(getIpAddress()).append(":")
- .append(getRpcPort()).toString();
-
- return uri;
- }
-
- public String getRpcPort(){
- String rpcPort = (System.getProperty("rpc.port") != null)
- ? System.getProperty("rpc.port")
- : DEFAULT_RPC_PORT;
-
- return rpcPort;
- }
-
- private String getIpAddress(){
- String ipAddress = (System.getProperty("local.ip") != null)
- ? System.getProperty("local.ip")
- : findIpAddress();
-
- return ipAddress;
- }
-
- /**
- * 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()) {
-
- NetworkInterface n = (NetworkInterface) e.nextElement();
-
- Enumeration<?> ee = n.getInetAddresses();
- while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
- if ((i instanceof Inet4Address) && (i.isSiteLocalAddress()))
- hostAddress = i.getHostAddress();
- }
- }
- return hostAddress;
-
- }
-}
+++ /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;
-
-public interface RemoteRpcClient extends AutoCloseable{
-
- void setRoutingTableProvider(RoutingTableProvider provider);
-
- void stop();
-
- void start();
-}
+++ /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 static com.google.common.base.Preconditions.checkState;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChange;
-import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-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.RouteIdentifierImpl;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.controller.sal.core.api.Provider;
-import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation;
-import org.opendaylight.controller.sal.core.api.RpcImplementation;
-import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
-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.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class RemoteRpcProvider implements
- RpcImplementation,
- RoutedRpcDefaultImplementation,
- AutoCloseable,
- Provider {
-
- private final Logger _logger = LoggerFactory.getLogger(RemoteRpcProvider.class);
-
- private final ServerImpl server;
- private final ClientImpl client;
- private RoutingTableProvider routingTableProvider;
- private final RpcListener listener = new RpcListener();
- private final RoutedRpcListener routeChangeListener = new RoutedRpcListener();
- private ProviderSession brokerSession;
- private RpcProvisionRegistry rpcProvisionRegistry;
- private BundleContext context;
- private ServiceTracker<?, ?> clusterTracker;
-
- public RemoteRpcProvider(ServerImpl server, ClientImpl client) {
- this.server = server;
- this.client = client;
- }
-
- public void setRoutingTableProvider(RoutingTableProvider provider) {
- this.routingTableProvider = provider;
- client.setRoutingTableProvider(provider);
- }
-
- public void setContext(BundleContext context){
- this.context = context;
- }
-
- public void setRpcProvisionRegistry(RpcProvisionRegistry rpcProvisionRegistry){
- this.rpcProvisionRegistry = rpcProvisionRegistry;
- }
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
- brokerSession = session;
- server.setBrokerSession(session);
- start();
- }
-
- @Override
- public Set<QName> getSupportedRpcs() {
- //TODO: Ask Tony if we need to get this from routing table
- return Collections.emptySet();
- }
-
- @Override
- public Collection<ProviderFunctionality> getProviderFunctionality() {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, CompositeNode input) {
- return client.invokeRpc(rpc, input);
- }
-
- @Override
- public ListenableFuture<RpcResult<CompositeNode>> invokeRpc(QName rpc, InstanceIdentifier identifier, CompositeNode input) {
- return client.invokeRpc(rpc, identifier, input);
- }
-
- public void start() {
- server.start();
- client.start();
- brokerSession.addRpcRegistrationListener(listener);
- rpcProvisionRegistry.setRoutedRpcDefaultDelegate(this);
- rpcProvisionRegistry.registerRouteChangeListener(routeChangeListener);
-
- announceSupportedRpcs();
- announceSupportedRoutedRpcs();
- }
-
- @Override
- public void close() throws Exception {
- unregisterSupportedRpcs();
- unregisterSupportedRoutedRpcs();
- server.close();
- client.close();
- }
-
- public void stop() {
- server.stop();
- client.stop();
- }
-
- /**
- * Add all the locally registered RPCs in the clustered routing table
- */
- private void announceSupportedRpcs(){
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- for (QName rpc : currentlySupported) {
- listener.onRpcImplementationAdded(rpc);
- }
- }
-
- /**
- * Add all the locally registered Routed RPCs in the clustered routing table
- */
- private void announceSupportedRoutedRpcs(){
-
- //TODO: announce all routed RPCs as well
-
- }
-
- /**
- * Un-Register all the supported RPCs from clustered routing table
- */
- private void unregisterSupportedRpcs(){
- Set<QName> currentlySupported = brokerSession.getSupportedRpcs();
- //TODO: remove all routed RPCs as well
- for (QName rpc : currentlySupported) {
- listener.onRpcImplementationRemoved(rpc);
- }
- }
-
- /**
- * Un-Register all the locally supported Routed RPCs from clustered routing table
- */
- private void unregisterSupportedRoutedRpcs(){
-
- //TODO: remove all routed RPCs as well
-
- }
-
- private RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> getRoutingTable(){
- Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> routingTable =
- routingTableProvider.getRoutingTable();
-
- checkState(routingTable.isPresent(), "Routing table is null");
-
- return routingTable.get();
- }
-
- /**
- * Listener for rpc registrations in broker
- */
- private class RpcListener implements RpcRegistrationListener {
-
- @Override
- public void onRpcImplementationAdded(QName rpc) {
-
- _logger.debug("Adding registration for [{}]", rpc);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
-
- try {
- routingTable.addGlobalRoute(routeId, server.getServerAddress());
- _logger.debug("Route added [{}-{}]", routeId, server.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 onRpcImplementationRemoved(QName rpc) {
-
- _logger.debug("Removing registration for [{}]", rpc);
- RouteIdentifierImpl routeId = new RouteIdentifierImpl();
- routeId.setType(rpc);
-
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
-
- try {
- routingTable.removeGlobalRoute(routeId);
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route delete failed {}", e);
- }
- }
- }
-
- /**
- * Listener for Routed Rpc registrations in broker
- */
- private class RoutedRpcListener
- implements RouteChangeListener<RpcRoutingContext, InstanceIdentifier> {
-
- /**
- *
- * @param routeChange
- */
- @Override
- public void onRouteChange(RouteChange<RpcRoutingContext, InstanceIdentifier> routeChange) {
- Map<RpcRoutingContext, Set<InstanceIdentifier>> announcements = routeChange.getAnnouncements();
- announce(getRouteIdentifiers(announcements));
-
- Map<RpcRoutingContext, Set<InstanceIdentifier>> removals = routeChange.getRemovals();
- remove(getRouteIdentifiers(removals));
- }
-
- /**
- *
- * @param announcements
- */
- private void announce(Set<RpcRouter.RouteIdentifier<?, ?, ?>> announcements) {
- _logger.debug("Announcing [{}]", announcements);
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
- try {
- routingTable.addRoutes(announcements, server.getServerAddress());
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route announcement failed {}", e);
- }
- }
-
- /**
- *
- * @param removals
- */
- private void remove(Set<RpcRouter.RouteIdentifier<?, ?, ?>> removals){
- _logger.debug("Removing [{}]", removals);
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> routingTable = getRoutingTable();
- try {
- routingTable.removeRoutes(removals, server.getServerAddress());
- } catch (RoutingTableException | SystemException e) {
- _logger.error("Route removal failed {}", e);
- }
- }
-
- /**
- *
- * @param changes
- * @return
- */
- private Set<RpcRouter.RouteIdentifier<?, ?, ?>> getRouteIdentifiers(Map<RpcRoutingContext, Set<InstanceIdentifier>> changes) {
- RouteIdentifierImpl routeId = null;
- Set<RpcRouter.RouteIdentifier<?, ?, ?>> routeIdSet = new HashSet<>();
-
- for (RpcRoutingContext context : changes.keySet()){
- routeId = new RouteIdentifierImpl();
- routeId.setType(context.getRpc());
- //routeId.setContext(context.getContext());
-
- for (InstanceIdentifier instanceId : changes.get(context)){
- routeId.setRoute(instanceId);
- routeIdSet.add(routeId);
- }
- }
- return routeIdSet;
- }
-
- }
-}
+++ /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;
-
-public interface RemoteRpcServer extends AutoCloseable {
-
-}
+++ /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.api.RpcRouter;
-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){//,RouteChangeListener rcl) {
- @SuppressWarnings("rawtypes")
- ServiceTracker<RoutingTable, RoutingTable> rawTracker = new ServiceTracker<>(ctx, RoutingTable.class, null);
- tracker = rawTracker;
- tracker.open();
-
- //routeChangeListener = rcl;
- }
-
- public Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> getRoutingTable() {
- @SuppressWarnings("unchecked")
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> tracked = tracker.getService();
-
- if(tracked instanceof RoutingTableImpl){
- if(routingTableImpl != tracked){
- routingTableImpl= (RoutingTableImpl<?, ?>)tracked;
- //routingTableImpl.setRouteChangeListener(routeChangeListener);
- }
- }
-
- return Optional.fromNullable(tracked);
- }
-
- @Override
- public void close() throws Exception {
- tracker.close();
- }
-}
+++ /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 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.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-/**
- * ZeroMq based implementation of RpcRouter.
- */
-public class ServerImpl implements RemoteRpcServer {
-
- private final Logger _logger = LoggerFactory.getLogger(ServerImpl.class);
-
- private ExecutorService serverPool;
- protected ServerRequestHandler handler;
-
- private Set<QName> remoteServices;
- private ProviderSession brokerSession;
- private ZMQ.Context context;
-
- 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 String serverAddress;
- private final int port;
-
- public static enum State {
- STARTING, STARTED, STOPPED;
- }
-
- public ServerImpl(int port) {
- this.port = port;
- }
-
- public State getStatus() {
- return this.status;
- }
-
- public Optional<ServerRequestHandler> getHandler() {
- return Optional.fromNullable(this.handler);
- }
-
- public void setBrokerSession(ProviderSession session) {
- this.brokerSession = session;
- }
-
- public Optional<ProviderSession> getBrokerSession() {
- return Optional.fromNullable(this.brokerSession);
- }
-
- public Optional<ZMQ.Context> getZmqContext() {
- return Optional.fromNullable(this.context);
- }
-
- public String getServerAddress() {
- return serverAddress;
- }
-
- public String getHandlerAddress() {
- return HANDLER_INPROC_ADDRESS;
- }
-
- /**
- *
- */
- public void start() {
- Preconditions.checkState(State.STOPPED == this.getStatus(),
- "Remote RPC Server is already running");
-
- status = State.STARTING;
- _logger.debug("Remote RPC Server is starting...");
-
- String hostIpAddress = findIpAddress();
-
- //Log and silently die as per discussion in the bug (bug-362)
- //https://bugs.opendaylight.org/show_bug.cgi?id=362
- //
- // A tracking enhancement defect (bug-366) is created to properly fix this issue
- //https://bugs.opendaylight.org/show_bug.cgi?id=366
- //checkState(hostIpAddress != null, "Remote RPC Server could not acquire host ip address");
-
- if (hostIpAddress == null) {
- _logger.error("Remote RPC Server could not acquire host ip address. Stopping...");
- stop();
- return;
- }
-
- this.serverAddress = new StringBuilder(hostIpAddress).
- append(":").
- append(port).
- toString();
-
- context = ZMQ.context(1);
- remoteServices = new HashSet<QName>();//
- serverPool = Executors.newSingleThreadExecutor();//main server thread
- serverPool.execute(receive()); // Start listening rpc requests
-
- status = State.STARTED;
- _logger.info("Remote RPC Server started [{}]", getServerAddress());
- }
-
- public void stop(){
- close();
- }
-
- /**
- *
- */
- @Override
- public void close() {
-
- if (State.STOPPED == this.getStatus()) return; //do nothing
-
- if (serverPool != null)
- serverPool.shutdown();
-
- closeZmqContext();
-
- status = State.STOPPED;
- _logger.info("Remote RPC Server stopped");
- }
-
- /**
- * Closes ZMQ Context. It tries to gracefully terminate the context. If
- * termination takes more than 5 seconds, its forcefully shutdown.
- */
- private void closeZmqContext() {
- ExecutorService exec = Executors.newSingleThreadExecutor();
- FutureTask<?> zmqTermination = new FutureTask<Void>(new Runnable() {
-
- @Override
- public void run() {
- try {
- if (context != null)
- context.term();
- _logger.debug("ZMQ Context terminated gracefully!");
- } catch (Exception 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");
- }
- }
- };
- }
-
- /**
- * 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() {
- Enumeration<?> e = null;
- try {
- e = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e1) {
- _logger.error("Failed to get list of interfaces", e1);
- return null;
- }
- while (e.hasMoreElements()) {
-
- NetworkInterface n = (NetworkInterface) e.nextElement();
-
- Enumeration<?> ee = n.getInetAddresses();
- while (ee.hasMoreElements()) {
- InetAddress i = (InetAddress) ee.nextElement();
- _logger.debug("Trying address {}", i);
- if ((i instanceof Inet4Address) && (!i.isLoopbackAddress())) {
- String hostAddress = i.getHostAddress();
- _logger.debug("Settled on host address {}", hostAddress);
- return hostAddress;
- }
- }
- }
-
- _logger.error("Failed to find a suitable host address");
- 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.connector.remoterpc;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-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;
-
-/**
- *
- */
-public class ServerRequestHandler implements AutoCloseable{
-
- private final Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class);
- private final String DEFAULT_NAME = "remote-rpc-worker";
- private final String dealerAddress;
- private final String serverAddress;
- private final int workerCount;
- private final ZMQ.Context context;
- private final 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 final 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()) {
-
- MessageHandler handler = new MessageHandler(socket);
- handler.receiveMessage();
-
- if (handler.hasMessageForBroker()) {
-
- Message request = handler.getMessage();
- 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;
-
- handler.sendResponse(result);
-
- } catch (Exception e) {
- _logger.debug("Broker threw [{}]", e);
- handler.sendError(e.getMessage());
- }
- }
-
- }
- } catch (Exception e) {
- printException(e);
- } finally {
- closeSocket(socket);
- }
- }
-
- 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);
- }
- }
-
- class MessageHandler{
- private final ZMQ.Socket socket;
- private Message message; //parsed message received on zmq server port
- private boolean messageForBroker = false; //if the message is valid and not a "ping" message
-
- public MessageHandler(ZMQ.Socket socket){
- this.socket = socket;
- }
-
- void receiveMessage(){
- byte[] bytes = socket.recv(); //this blocks
- _logger.debug("Received bytes:[{}]", bytes.length);
-
- Object objectRecvd = null;
- try{
- objectRecvd = Message.deserialize(bytes);
- }catch (Exception e){
- sendError(e.getMessage());
- return;
- }
-
- if (!(objectRecvd instanceof Message)) {
- sendError("Invalid message received");
- return;
- }
-
- message = (Message) objectRecvd;
-
- _logger.info("Received request [{}]", message);
-
- if (Message.MessageType.PING == message.getType()){
- sendPong();
- return;
- }
-
- messageForBroker = true;
- }
-
- boolean hasMessageForBroker(){
- return messageForBroker;
- }
-
- Message getMessage(){
- return message;
- }
-
- void sendResponse(RpcResult<CompositeNode> result){
- CompositeNode payload = (result != null) ? result.getResult() : null;
-
- String recipient = null;
- RpcRouter.RouteIdentifier<?, ?, ?> routeId = null;
-
- if (message != null) {
- recipient = message.getSender();
- routeId = message.getRoute();
- }
-
- Message response = new Message.MessageBuilder()
- .type(Message.MessageType.RESPONSE)
- .sender(serverAddress)
- .recipient(recipient)
- .route(routeId)
- .payload(XmlUtils.compositeNodeToXml(payload))
- .build();
-
- send(response);
- }
-
- private void sendError(String msg){
- Message errorResponse = new Message.MessageBuilder()
- .type(Message.MessageType.ERROR)
- .sender(serverAddress)
- .payload(msg)
- .build();
-
- send(errorResponse);
- }
-
- private void sendPong(){
- Message pong = new Message.MessageBuilder()
- .type(Message.MessageType.PONG)
- .sender(serverAddress)
- .build();
-
- send(pong);
- }
-
- private void send(Message msg){
- byte[] serializedMessage = null;
- try {
- serializedMessage = Message.serialize(msg);
- } catch (Exception e) {
- _logger.debug("Unexpected error during serialization of response [{}]", msg);
- return;
- }
-
- if (serializedMessage != null)
- if (socket.send(serializedMessage))
- _logger.info("Response sent [{}]", msg);
- else _logger.debug("Failed to send serialized message");
- }
- }
-}
+++ /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.connector.remoterpc;
-
-import org.zeromq.ZMQ;
-
-import java.util.UUID;
-
-/**
- *
- */
-public class SocketPair implements AutoCloseable{
- private ZMQ.Socket sender;
- private ZMQ.Socket receiver;
-
- private static final String INPROC_PREFIX = "inproc://";
-
- public SocketPair(){
- String address = new StringBuilder(INPROC_PREFIX)
- .append(UUID.randomUUID())
- .toString();
-
- receiver = Context.getInstance().getZmqContext().socket(ZMQ.PAIR);
- receiver.bind(address);
-
- sender = Context.getInstance().getZmqContext().socket(ZMQ.PAIR);
- sender.connect(address);
- }
-
- public ZMQ.Socket getSender(){
- return this.sender;
- }
-
- public ZMQ.Socket getReceiver(){
- return this.receiver;
- }
-
- @Override
- public void close() throws Exception {
- sender.close();
- receiver.close();
- }
-}
+++ /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 java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-
-public class Message implements Serializable {
- private static final long serialVersionUID = 1L;
-
- public static enum MessageType {
- PING((byte) 0),
- PONG((byte) 1),
- REQUEST((byte) 2),
- RESPONSE((byte) 3),
- ERROR((byte)4);
-
- private final byte type;
-
- MessageType(byte type) {
- this.type = type;
- }
-
- public byte getType(){
- return this.type;
- }
- }
-
- private MessageType type;
- private String sender;
- private String recipient;
- private RpcRouter.RouteIdentifier<?, ?, ?> route;
- private Object payload;
-
- public MessageType getType() {
- return type;
- }
-
- public void setType(MessageType type) {
- this.type = type;
- }
-
- public String getSender() {
- return sender;
- }
-
- public void setSender(String sender) {
- this.sender = sender;
- }
-
- public RpcRouter.RouteIdentifier<?, ?, ?> getRoute() {
- return route;
- }
-
- public void setRoute(RpcRouter.RouteIdentifier<?, ?, ?> route) {
- this.route = route;
- }
-
- public Object getPayload() {
- return payload;
- }
-
- public void setPayload(Object payload) {
- this.payload = payload;
- }
-
- public String getRecipient() {
- return recipient;
- }
-
- public void setRecipient(String recipient) {
- this.recipient = recipient;
- }
-
- @Override
- public String toString() {
- return "Message{" +
- "type=" + type +
- ", sender='" + sender + '\'' +
- ", recipient='" + recipient + '\'' +
- ", route=" + route +
- ", payload=" + payload +
- '}';
- }
-
- /**
- * Converts any {@link Serializable} object to byte[]
- *
- * @param obj
- * @return
- * @throws IOException
- */
- public static byte[] serialize(Object obj) throws IOException {
- ByteArrayOutputStream b = new ByteArrayOutputStream();
- ObjectOutputStream o = new ObjectOutputStream(b);
- o.writeObject(obj);
- return b.toByteArray();
- }
-
- /**
- * Converts byte[] to a java object
- *
- * @param bytes
- * @return
- * @throws IOException
- * @throws ClassNotFoundException
- */
- public static Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
- ByteArrayInputStream b = new ByteArrayInputStream(bytes);
- ObjectInputStream o = new ObjectInputStream(b);
- return o.readObject();
- }
-
- public static class Response extends Message implements RpcRouter.RpcReply<Object> {
- private static final long serialVersionUID = 1L;
- private ResponseCode code; // response code
-
- public static enum ResponseCode {
- SUCCESS(200), BADREQUEST(400), TIMEOUT(408), GONE(410), SERVERERROR(500), SERVICEUNAVAILABLE(503);
-
- private final int code;
-
- ResponseCode(int code) {
- this.code = code;
- }
- }
-
- public ResponseCode getCode() {
- return code;
- }
-
- public void setCode(ResponseCode code) {
- this.code = code;
- }
- }
-
- /**
- * Builds a {@link Message} object
- */
- public static class MessageBuilder{
-
- private final Message message;
-
- public MessageBuilder(){
- message = new Message();
- }
-
-
- public MessageBuilder type(MessageType type){
- message.setType(type);
- return this;
- }
-
- public MessageBuilder sender(String sender){
- message.setSender(sender);
- return this;
- }
-
- public MessageBuilder recipient(String recipient){
- message.setRecipient(recipient);
- return this;
- }
-
- public MessageBuilder route(RpcRouter.RouteIdentifier<?, ?, ?> route){
- message.setRoute(route);
- return this;
- }
-
- public MessageBuilder payload(Object obj){
- message.setPayload(obj);
- return this;
- }
-
- public Message build(){
- return message;
- }
- }
-}
-
+++ /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.zeromq.ZMQ;
-
-/**
- * A class encapsulating {@link Message} and the {@link ZMQ.Socket} over which it is transmitted
- */
-public class MessageWrapper {
-
- private Message _message;
- private ZMQ.Socket _receiveSocket;
-
- public MessageWrapper(Message message, ZMQ.Socket receiveSocket) {
- this._message = message;
- this._receiveSocket = receiveSocket;
- }
-
- public Message getMessage() {
- return _message;
- }
-
- public ZMQ.Socket getReceiveSocket() {
- return _receiveSocket;
- }
-}
+++ /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 java.io.Serializable;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-public class RouteIdentifierImpl implements RpcRouter.RouteIdentifier<QName, QName, InstanceIdentifier>,Serializable {
- private static final long serialVersionUID = 1L;
-
- private QName context;
- private QName type;
- private InstanceIdentifier route;
-
- @Override
- public QName getContext() {
- return this.context;
- }
-
- @Override
- public QName getType() {
- return this.type;
- }
-
- @Override
- public InstanceIdentifier getRoute() {
- return this.route;
- }
-
- public void setContext(QName context) {
- this.context = context;
- }
-
- public void setType(QName type) {
- this.type = type;
- }
-
- public void setRoute(InstanceIdentifier route) {
- this.route = route;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- RouteIdentifierImpl that = (RouteIdentifierImpl) o;
-
- if (context == null){
- if (that.getContext() != null) return false;
- }else
- if (!context.equals(that.context)) return false;
-
- if (route == null){
- if (that.getRoute() != null) return false;
- }else
- if (!route.equals(that.route)) return false;
-
- if (type == null){
- if (that.getType() != null) return false;
- }else
- if (!type.equals(that.type)) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- int prime = 31;
- int result = 0;
- result = prime * result + (context == null ? 0:context.hashCode());
- result = prime * result + (type == null ? 0:type.hashCode());
- result = prime * result + (route == null ? 0:route.hashCode());
- return result;
- }
-
- @Override
- public String toString() {
- return "RouteIdentifierImpl{" +
- "context=" + context +
- ", type=" + type +
- ", route=" + route +
- '}';
- }
-}
+++ /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.util;
-
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.ByteArrayInputStream;
-import java.io.StringWriter;
-
-public class XmlUtils {
-
- private static final Logger _logger = LoggerFactory.getLogger(XmlUtils.class);
-
- public static String compositeNodeToXml(CompositeNode cNode){
- if (cNode == null) return new String();
-
- Document domTree = NodeUtils.buildShadowDomTree(cNode);
- StringWriter writer = new StringWriter();
- try {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- transformer.transform(new DOMSource(domTree), new StreamResult(writer));
- } catch (TransformerException e) {
- _logger.error("Error during translation of Document to OutputStream", e);
- }
-
- return writer.toString();
- }
-
- public static CompositeNode xmlToCompositeNode(String xml){
- if (xml==null || xml.length()==0) return null;
-
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(new ByteArrayInputStream(xml.getBytes()));
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /dev/null
-module odl-sal-dom-rpc-remote-cfg {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc";
- prefix "rpc-cluster";
-
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-dom {prefix dom;}
-
- description
- "Service definition for Binding Aware MD-SAL.";
-
- revision "2013-10-28" {
- description
- "Initial revision";
- }
-
- identity remote-rpc-server {
- base config:service-type;
- config:java-class "org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcServer";
- }
-
- identity remote-rpc-client {
- base config:service-type;
- config:java-class "org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient";
- }
-
- identity remote-zeromq-rpc-server {
- base config:module-type;
- config:java-name-prefix ZeroMQServer;
- }
-
- augment "/config:modules/config:module/config:configuration" {
- case remote-zeromq-rpc-server {
- when "/config:modules/config:module/config:type = 'remote-zeromq-rpc-server'";
-
- container dom-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dom:dom-broker-osgi-registry;
- }
- }
- }
-
- leaf port {
- type uint16;
- }
- }
- }
-}
\ No newline at end of file
+++ /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.connector.remoterpc;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.io.IOException;
-
-import junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-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.utils.MessagingUtil;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-
-import com.google.common.base.Optional;
-
-/**
- *
- */
-public class ClientImplTest {
- RoutingTableProvider routingTableProvider;
- ClientImpl client;
- ClientRequestHandler mockHandler;
-
- @Before
- public void setUp() throws Exception {
-
- //mock routing table
- routingTableProvider = mock(RoutingTableProvider.class);
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> mockRoutingTable = new MockRoutingTable<String, String>();
- Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, 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).get();
-
- 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).get();
-
- Assert.assertFalse(result.isSuccessful());
- Assert.assertFalse(result.getErrors().isEmpty());
- Assert.assertNull(result.getResult());
- }
-
-}
+++ /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.connector.remoterpc;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-
-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;
-
-/**
- *
- */
-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.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<Message>(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
-/*
- * 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.connector.remoterpc;
-
-import java.util.HashSet;
-import java.util.Set;
-
-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;
-
-/**
- * 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 addRoutes(Set set, Object o) throws RoutingTableException, SystemException {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void removeRoutes(Set set, Object o) throws RoutingTableException, SystemException {
- //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public void removeGlobalRoute(Object o) throws RoutingTableException, SystemException {
-
- }
-
- @Override
- public Object getGlobalRoute(Object o) throws RoutingTableException, SystemException {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
- @Override
- public Set<String> getRoutes(Object o) {
- Set<String> routes = new HashSet<String>();
- routes.add("localhost:5554");
- return routes;
- }
-
- @Override
- public Object getLastAddedRoute(Object o) {
- return null; //To change body of implemented methods use File | Settings | File Templates.
- }
-
-// @Override
-// public Set<Map.Entry> getAllRoutes() {
-// return Collections.emptySet();
-// }
-
-// @Override
-// public Object getARoute(Object o) {
-// return null;
-// }
-}
+++ /dev/null
-package org.opendaylight.controller.sal.connector.remoterpc;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class RemoteRpcProviderTest {
- @Before
- public void setUp() throws Exception {
-
- }
-
- @After
- public void tearDown() throws Exception {
-
- }
-
- @Test
- public void testSetRoutingTableProvider() throws Exception {
-
- }
-
- @Test
- public void testOnSessionInitiated() throws Exception {
-
- }
-
- @Test
- public void testGetSupportedRpcs() throws Exception {
-
- }
-
- @Test
- public void testGetProviderFunctionality() throws Exception {
-
- }
-
- @Test
- public void testInvokeRpc() throws Exception {
-
- }
-
- @Test
- public void testInvokeRoutedRpc() throws Exception {
-
- }
-
- @Test
- public void testStart() throws Exception {
-
- }
-
- @Test
- public void testClose() throws Exception {
-
- }
-
- @Test
- public void testStop() throws Exception {
-
- }
-}
+++ /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.connector.remoterpc;
-
-import org.junit.Test;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeUtils;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.io.StringWriter;
-
-public class SerilizationTest {
-
- private static final Logger _logger = LoggerFactory.getLogger(SerilizationTest.class);
-
- public void fromXml() {
- }
-
- @Test
- public void toXml() throws FileNotFoundException {
-
- //InputStream xmlStream = SerilizationTest.class.getResourceAsStream("/FourSimpleChildren.xml");
- InputStream xmlStream = SerilizationTest.class.getResourceAsStream("/AddFlow.xml");
- StringWriter writer = new StringWriter();
-
- CompositeNode data = loadCompositeNode(xmlStream);
- Document domTree = NodeUtils.buildShadowDomTree(data);
- try {
- TransformerFactory tf = TransformerFactory.newInstance();
- Transformer transformer = tf.newTransformer();
- transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
- //transformer.setOutputProperty(OutputKeys.METHOD, "xml");
- //transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- //transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
- //transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
- transformer.transform(new DOMSource(domTree), new StreamResult(writer));
- } catch (TransformerException e) {
- _logger.error("Error during translation of Document to OutputStream", e);
- }
-
- _logger.info("Parsed xml [{}]", writer.toString());
- }
-
- // Figure out how to include TestUtils through pom ...was getting errors
- private CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /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 static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-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 junit.framework.Assert;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-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.common.QName;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.zeromq.ZMQ;
-
-import zmq.Ctx;
-import zmq.SocketBase;
-
-import com.google.common.base.Optional;
-
-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);
-
- RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String> mockRoutingTable = new MockRoutingTable<String, String>();
- Optional<RoutingTable<RpcRouter.RouteIdentifier<?, ?, ?>, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable);
- when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable);
-
- when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null);
- when(brokerSession.getSupportedRpcs()).thenReturn(Collections.<QName>emptySet());
- 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 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<Thread>();
- 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 static org.mockito.Mockito.mock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-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;
-
-public class ServerRequestHandlerTest {
-
- ServerRequestHandler handler;
- ZMQ.Context context;
- ExecutorService executorService = Executors.newCachedThreadPool();
- private final int workerCount = 2;
- private final String mockDealerAddress = "inproc://rpc-request-handler";
- private final String mockServerIp = "localhost";
- private final 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<Thread>();
- 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.utils;
-
-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;
-
-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;
-
-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 sendAMessage(final ZMQ.Context context, final String serverAddress, final Message msg)
- 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(msg));
- } 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 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<Void>(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
-package org.opendaylight.controller.sal.connector.remoterpc.utils;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.zeromq.ZMQ;
-
-public class RemoteServerTestClient {
-
-
-
- public static void main(String args[]) throws Exception{
- String serverAddress = "tcp://10.195.128.108:5666";
- ZMQ.Context ctx = ZMQ.context(1);
- ExecutorService executor = Executors.newSingleThreadExecutor();
- RemoteServerTestClient client = new RemoteServerTestClient();
- executor.execute(
- MessagingUtil.sendAMessage(ctx, serverAddress, client.createPingMessage(serverAddress))
- );
- MessagingUtil.sendAMessage(ctx, serverAddress, client.createPingMessage(serverAddress));
-
- Thread.sleep(5000);
- MessagingUtil.closeZmqContext(ctx);
- executor.shutdown();
- }
-
- public Message createPingMessage(String serverAddress){
- Message ping = new Message.MessageBuilder()
- .type(Message.MessageType.PING)
- .sender("localhost:5444")
- .recipient(serverAddress)
- .build();
-
- return ping;
- }
- public Message createAddFlowMessage(String serverAddress ){
-
- RpcRouter.RouteIdentifier<?, ?, ?> routeIdentifier = getAddFlowRpcIdentifier();
-
- Message addFlow = new Message.MessageBuilder()
- .type(Message.MessageType.REQUEST)
- .sender("localhost:5444")
- .recipient(serverAddress)
- .route(routeIdentifier)
- .payload(getAddFlowPayload(1,1))
- .build();
-
- return addFlow;
- }
-
- private RpcRouter.RouteIdentifier<?, ?, ?> getAddFlowRpcIdentifier(){
- throw new UnsupportedOperationException();
- }
-
- private CompositeNode getAddFlowPayload(int flowId, int tableId){
- final String xml =
- "<flow xmlns=\"urn:opendaylight:flow:inventory\">"
- + "<priority>5</priority>"
- + "<flow-name>Foo</flow-name>"
- + "<match>"
- + "<ethernet-match>"
- + "<ethernet-type>"
- + "<type>2048</type>"
- + "</ethernet-type>"
- + "</ethernet-match>"
- + "<ipv4-destination>10.0.10.2/24</ipv4-destination>"
- + "</match>"
- + "<id>" + flowId + "</id>"
- + "<table_id>" + tableId + "</table_id>"
- + "<instructions>"
- + "<instruction>"
- + "<order>0</order>"
- + "<apply-actions>"
- + "<action>"
- + "<order>0</order>"
- + "<dec-nw-ttl/>"
- + "</action>"
- + "</apply-actions>"
- + "</instruction>"
- + "</instructions>"
- + "</flow>";
-
- return XmlUtils.xmlToCompositeNode(xml);
- }
-}
+++ /dev/null
-<add-flow xmlns="urn:opendaylight:flow:service">
- <input>
- <transaction-uri>BA-7</transaction-uri>
- <table_id>4</table_id>
- <priority>5</priority>
- <node>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]
- </node>
- <match>
- <ipv4-destination>10.0.10.2/24</ipv4-destination>
- <ethernet-match>
- <ethernet-type>
- <type>2048</type>
- </ethernet-type>
- </ethernet-match>
- </match>
- <instructions>
- <instruction>
- <order>0</order>
- <apply-actions>
- <action>
- <order>0</order>
- <dec-nw-ttl/>
- </action>
- </apply-actions>
- </instruction>
- </instructions>
- <flow-table>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]
- </flow-table>
- <flow-ref>
- /(urn:opendaylight:inventory?revision=2013-08-19)nodes/(urn:opendaylight:inventory?revision=2013-08-19)node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:1}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]/(urn:opendaylight:flow:inventory?revision=2013-08-19)flow[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=4}]
- </flow-ref>
- <flow-name>Foo</flow-name>
- </input>
-</add-flow>
\ No newline at end of file
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</rpc>
+++ /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>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <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>
-</project>
+++ /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.sample.zeromq.consumer;
-
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.Hashtable;
-import java.util.concurrent.Future;
-
-import org.opendaylight.controller.sal.core.api.AbstractConsumer;
-import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
-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.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.opendaylight.yangtools.yang.data.impl.XmlTreeBuilder;
-
-import javax.xml.stream.XMLStreamException;
-
-public class ExampleConsumer extends AbstractConsumer {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
- private ConsumerSession session;
-
- private ServiceRegistration<ExampleConsumer> thisReg;
- private Logger _logger = LoggerFactory.getLogger(ExampleConsumer.class);
-
- @Override
- public void onSessionInitiated(ConsumerSession session) {
- this.session = session;
- }
-
- public RpcResult<CompositeNode> invokeRpc(QName qname, CompositeNode input) {
- _logger.info("Invoking RPC:[{}] with Input:[{}]", qname.getLocalName(), input);
- RpcResult<CompositeNode> result = null;
- Future<RpcResult<CompositeNode>> future = ExampleConsumer.this.session.rpc(qname, input);
- try {
- result = future.get();
- } catch (Exception e) {
- e.printStackTrace();
- }
- _logger.info("Returning Result:[{}]", result);
- return result;
- }
-
- @Override
- protected void startImpl(BundleContext context){
- thisReg = context.registerService(ExampleConsumer.class, this, new Hashtable<String,String>());
- }
- @Override
- protected void stopImpl(BundleContext context) {
- super.stopImpl(context);
- thisReg.unregister();
- }
-
- public CompositeNode getValidCompositeNodeWithOneSimpleChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/OneSimpleChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithTwoSimpleChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/TwoSimpleChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithFourSimpleChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/FourSimpleChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithOneSimpleOneCompositeChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/OneSimpleOneCompositeChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getValidCompositeNodeWithTwoCompositeChildren() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/TwoCompositeChildren.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getInvalidCompositeNodeSimpleChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/InvalidSimpleChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- public CompositeNode getInvalidCompositeNodeCompositeChild() throws FileNotFoundException {
- InputStream xmlStream = ExampleConsumer.class.getResourceAsStream("/InvalidCompositeChild.xml");
- return loadCompositeNode(xmlStream);
- }
-
- //Note to self: Stolen from TestUtils
- ///Users/alefan/odl/controller4/opendaylight/md-sal/sal-rest-connector/src/test/java/org/opendaylight/controller/sal/restconf/impl/test/TestUtils.java
- // Figure out how to include TestUtils through pom ...was getting errors
- private CompositeNode loadCompositeNode(InputStream xmlInputStream) throws FileNotFoundException {
- if (xmlInputStream == null) {
- throw new IllegalArgumentException();
- }
- Node<?> dataTree;
- try {
- dataTree = XmlTreeBuilder.buildDataTree(xmlInputStream);
- } catch (XMLStreamException e) {
- _logger.error("Error during building data tree from XML", e);
- return null;
- }
- if (dataTree == null) {
- _logger.error("data tree is null");
- return null;
- }
- if (dataTree instanceof SimpleNode) {
- _logger.error("RPC XML was resolved as SimpleNode");
- return null;
- }
- return (CompositeNode) dataTree;
- }
-}
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
-</rpc>
+++ /dev/null
-<rpc>
- <innerinterface1>
- <name>eth1</name>
- <type>ethernet</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface1>
- <innerinterface2>
- <name>error</name>
- <type>ethernet</type>
- <enabled>true</enabled>
- <description>some interface</description>
- </innerinterface2>
-</rpc>
+++ /dev/null
-<rpc>
- <name>error</name>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <innerinterface>
- <name>eth1</name>
- <type>ethernetCsmacd</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface>
-</rpc>
+++ /dev/null
-<rpc>
- <innerinterface1>
- <name>eth1</name>
- <type>ethernet</type>
- <enabled>false</enabled>
- <description>some interface</description>
- </innerinterface1>
- <innerinterface2>
- <name>eth2</name>
- <type>ethernet</type>
- <enabled>true</enabled>
- <description>some interface</description>
- </innerinterface2>
-</rpc>
+++ /dev/null
-<rpc>
- <name>eth0</name>
- <type>ethernetCsmacd</type>
-</rpc>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.1-SNAPSHOT</version>
- <relativePath>../..</relativePath>
- </parent>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <packaging>pom</packaging>
-
- <modules>
- <module>consumer-service</module>
- <module>provider-service</module>
- <module>test-it</module>
- <module>test-nb</module>
- </modules>
- <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>
-
-</project>
+++ /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>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- <packaging>bundle</packaging>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Bundle-Activator>org.opendaylight.controller.sample.zeromq.provider.ExampleProvider</Bundle-Activator>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
-
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- </dependency>
-
- </dependencies>
-</project>
+++ /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.sample.zeromq.provider;
-
-import org.opendaylight.controller.sal.common.util.RpcErrors;
-import org.opendaylight.controller.sal.common.util.Rpcs;
-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;
-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.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class ExampleProvider extends AbstractProvider implements RpcImplementation {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
- private RpcRegistration reg;
-
- private ServiceRegistration thisReg;
-
- private ProviderSession session;
- private Logger _logger = LoggerFactory.getLogger(ExampleProvider.class);
-
- @Override
- public void onSessionInitiated(ProviderSession session) {
- this.session = session;
- }
-
- @Override
- public Set<QName> getSupportedRpcs() {
- Set<QName> supportedRpcs = new HashSet<QName>();
- supportedRpcs.add(QNAME);
- return supportedRpcs;
- }
-
- @Override
- public RpcResult<CompositeNode> invokeRpc(final QName rpc, CompositeNode input) {
- boolean success = false;
- CompositeNode output = null;
- Collection<RpcError> errors = new ArrayList<>();
-
- // Only handle supported RPC calls
- if (getSupportedRpcs().contains(rpc)) {
- if (input == null) {
- errors.add(RpcErrors.getRpcError("app", "tag", "info", RpcError.ErrorSeverity.WARNING, "message:null input", RpcError.ErrorType.RPC, null));
- }
- else {
- if (isErroneousInput(input)) {
- errors.add(RpcErrors.getRpcError("app", "tag", "info", RpcError.ErrorSeverity.ERROR, "message:error", RpcError.ErrorType.RPC, null));
- }
- else {
- success = true;
- output = addSuccessNode(input);
- }
- }
- }
- return Rpcs.getRpcResult(success, output, errors);
- }
-
- // Examines input -- dives into CompositeNodes and finds any value equal to "error"
- private boolean isErroneousInput(CompositeNode input) {
- for (Node<?> n : input.getChildren()) {
- if (n instanceof CompositeNode) {
- if (isErroneousInput((CompositeNode)n)) {
- return true;
- }
- }
- else { //SimpleNode
- if ((input.getChildren().get(0).getValue()).equals("error")) {
- return true;
- }
- }
- }
- return false;
- }
-
- // Adds a child SimpleNode containing the value "success" to the input CompositeNode
- private CompositeNode addSuccessNode(CompositeNode input) {
- List<Node<?>> list = new ArrayList<Node<?>>(input.getChildren());
- SimpleNodeTOImpl<String> simpleNode = new SimpleNodeTOImpl<String>(QNAME, input, "success");
- list.add(simpleNode);
- return new CompositeNodeTOImpl(QNAME, null, list);
- }
-
- @Override
- protected void startImpl(BundleContext context) {
- thisReg = context.registerService(ExampleProvider.class, this, new Hashtable<String, String>());
- }
-
- @Override
- protected void stopImpl(BundleContext context) {
- if (reg != null) {
- try {
- reg.close();
- thisReg.unregister();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
- public void announce(QName name) {
- _logger.debug("Announcing [{}]\n\n\n", name);
- reg = this.session.addRpcImplementation(name, this);
- }
-
-}
+++ /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>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
- <artifactId>sal-remoterpc-connector-test-it</artifactId>
- <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>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>maven-paxexam-plugin</artifactId>
- <executions>
- <execution>
- <id>generate-config</id>
- <goals>
- <goal>generate-depends-file</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- <pluginManagement>
- <plugins>
- <!--This plugin's configuration is used to store Eclipse
- m2e settings only. It has no influence on the Maven build itself. -->
- <plugin>
- <groupId>org.eclipse.m2e</groupId>
- <artifactId>lifecycle-mapping</artifactId>
- <version>${lifecycle.mapping.version}</version>
- <configuration>
- <lifecycleMappingMetadata>
- <pluginExecutions>
- <pluginExecution>
- <pluginExecutionFilter>
- <groupId>
- org.ops4j.pax.exam
- </groupId>
- <artifactId>
- maven-paxexam-plugin
- </artifactId>
- <versionRange>
- [1.2.4,)
- </versionRange>
- <goals>
- <goal>
- generate-depends-file
- </goal>
- </goals>
- </pluginExecutionFilter>
- <action>
- <ignore></ignore>
- </action>
- </pluginExecution>
- </pluginExecutions>
- </lifecycleMappingMetadata>
- </configuration>
- </plugin>
- </plugins>
- </pluginManagement>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>xtend-lib-osgi</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- </dependency>
- <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>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-core-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-api</artifactId>
- </dependency>
- <!--dependency> <groupId>org.opendaylight.yangtools</groupId> <artifactId>yang-data-impl</artifactId>
- <version>${yangtools.version}</version> </dependency -->
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-parser-impl</artifactId>
- <version>${yangtools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>antlr4-runtime-osgi-nohead</artifactId>
- </dependency>
-
- <!-- routing table dependencies -->
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>zeromq-routingtable.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal.implementation</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager.it.implementation</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.stub</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.dependencymanager.shell</artifactId>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>eclipselink</groupId>
- <artifactId>javax.resource</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>ietf-netconf-monitoring</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-binding</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>yang-ext</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.model</groupId>
- <artifactId>opendaylight-l2-types</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-it</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-inventory</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-common</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-connector-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-common-util</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>clustering.services</artifactId>
- </dependency>
-
- <dependency>
- <groupId>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-databind</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-annotations</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>com.fasterxml.jackson.core</groupId>
- <artifactId>jackson-core</artifactId>
- <version>${jackson.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.zeromq</groupId>
- <artifactId>jeromq</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>xtend-lib-osgi</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-binding-broker-impl</artifactId>
- <scope>provided</scope>
- </dependency>
- <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.opendaylight.controller</groupId>
- <artifactId>config-netconf-connector</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>logback-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-persister-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-persister-file-xml-adapter</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-impl</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>netconf-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <version>${exam.version}</version>
- <!-- Compile scope here is intentional, it is used in TestHelper
- class which could be downloaded via nexus and reused in other integration
- tests. -->
- <scope>compile</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>equinoxSDK381</groupId>
- <artifactId>org.eclipse.osgi</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>log4j-over-slf4j</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-core</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-service</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-manager</artifactId>
- <exclusions>
- <exclusion>
- <artifactId>commons-io</artifactId>
- <groupId>commons-io</groupId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.model</groupId>
- <artifactId>model-flow-management</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.yangtools.thirdparty</groupId>
- <artifactId>antlr4-runtime-osgi-nohead</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.sample.zeromq.test.it;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.opendaylight.controller.sal.connector.remoterpc.RemoteRpcClient;
-
-import org.opendaylight.controller.sal.connector.remoterpc.dto.Message;
-import org.opendaylight.controller.sal.core.api.Broker;
-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.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.CompositeNode;
-import org.ops4j.pax.exam.Configuration;
-import org.ops4j.pax.exam.Option;
-import org.ops4j.pax.exam.junit.PaxExam;
-import org.ops4j.pax.exam.util.Filter;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.ServiceReference;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.zeromq.ZMQ;
-
-import javax.inject.Inject;
-
-import java.io.IOException;
-import java.net.URI;
-
-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.ops4j.pax.exam.CoreOptions.*;
-
-@RunWith(PaxExam.class)
-public class RouterTest {
-
- private Logger _logger = LoggerFactory.getLogger(RouterTest.class);
-
- public static final String ODL = "org.opendaylight.controller";
- public static final String YANG = "org.opendaylight.yangtools";
- public static final String SAMPLE = "org.opendaylight.controller.tests";
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
-
- @Inject
- org.osgi.framework.BundleContext ctx;
-
- @Inject
- @Filter(timeout=60*1000)
- Broker broker;
-
- private ZMQ.Context zmqCtx = ZMQ.context(1);
- //private Server router;
- //private ExampleProvider provider;
-
- //@Test
- public void testInvokeRpc() throws Exception{
- //Thread.sleep(1000);
- //Send announcement
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
-
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
-
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
-
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- 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++) {
- RpcResult<CompositeNode> result = router.invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertNotNull(result);
- }
- }
-
- @Test
- public void testInvokeRpcWithValidSimpleNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithOneSimpleChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithValidSimpleNodes() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithFourSimpleChildren();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithValidCompositeNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", "heartbeat");
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getValidCompositeNodeWithTwoCompositeChildren();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertTrue(result.isSuccessful());
- Assert.assertNotNull(result.getResult());
- Assert.assertEquals(0, result.getErrors().size());
- Assert.assertEquals(input.getChildren().size()+1, result.getResult().getChildren().size());
- }
- }
-
- @Test
- public void testInvokeRpcWithNullInput() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, null);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.WARNING, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- @Test
- public void testInvokeRpcWithInvalidSimpleNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getInvalidCompositeNodeSimpleChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.ERROR, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- @Test
- public void testInvokeRpcWithInvalidCompositeNode() throws Exception{
- //Thread.sleep(1500);
-
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- Assert.assertNotNull(providerRef);
- ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
- Assert.assertNotNull(provider);
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- Assert.assertNotNull(consumerRef);
- ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
- Assert.assertNotNull(consumer);
-
- // Provider sends announcement
- _logger.debug("Provider sends announcement [{}]", QNAME.getLocalName());
- provider.announce(QNAME);
- // Consumer invokes RPC
- _logger.debug("Invoking RPC [{}]", QNAME);
- CompositeNode input = consumer.getInvalidCompositeNodeCompositeChild();
- for (int i = 0; i < 3; i++) {
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, input);
- Assert.assertNotNull(result);
- _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
- Assert.assertFalse(result.isSuccessful());
- Assert.assertNull(result.getResult());
- Assert.assertEquals(1, result.getErrors().size());
- Assert.assertEquals(RpcError.ErrorSeverity.ERROR, ((RpcError)result.getErrors().toArray()[0]).getSeverity());
- }
- }
-
- //@Test
- // This method is UNTESTED -- need to get around the bundling issues before I know if this even work
-// public void testInvokeRpcWithValidCompositeNode() throws Exception{
-// Thread.sleep(10000);
-// //Send announcement
-// ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
-// Assert.assertNotNull(providerRef);
-//
-// ExampleProvider provider = (ExampleProvider)ctx.getService(providerRef);
-// Assert.assertNotNull(provider);
-//
-// ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
-// Assert.assertNotNull(consumerRef);
-//
-// ExampleConsumer consumer = (ExampleConsumer)ctx.getService(consumerRef);
-// Assert.assertNotNull(consumer);
-//
-// _logger.debug("Provider sends announcement [{}]", "heartbeat");
-// provider.announce(QNAME);
-// ServiceReference routerRef = ctx.getServiceReference(Client.class);
-// Client router = (Client) ctx.getService(routerRef);
-// _logger.debug("Found router[{}]", router);
-// _logger.debug("Invoking RPC [{}]", QNAME);
-// for (int i = 0; i < 3; i++) {
-// RpcResult<CompositeNode> result = router.getInstance().invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
-// _logger.debug("{}-> Result is: Successful:[{}], Payload:[{}], Errors: [{}]", i, result.isSuccessful(), result.getResult(), result.getErrors());
-// Assert.assertNotNull(result);
-// }
-// }
-
- private Message send(Message msg) throws IOException {
- ZMQ.Socket reqSocket = zmqCtx.socket(ZMQ.REQ);
- reqSocket.connect("tcp://localhost:5555");
- reqSocket.send(Message.serialize(msg));
- Message response = parseMessage(reqSocket);
-
- return response;
- }
-
- /**
- * @param socket
- * @return
- */
- private Message parseMessage(ZMQ.Socket socket) {
-
- Message msg = null;
- try {
- byte[] bytes = socket.recv();
- _logger.debug("Received bytes:[{}]", bytes.length);
- msg = (Message) Message.deserialize(bytes);
- } catch (Throwable t) {
- t.printStackTrace();
- }
- return msg;
- }
-
-
- private void printState(){
- Bundle[] b = ctx.getBundles();
- _logger.debug("\n\nNumber of bundles [{}]\n\n]", b.length);
- for (int i=0;i<b.length;i++){
- _logger.debug("Bundle States {}-{} ",b[i].getSymbolicName(), stateToString(b[i].getState()));
-
- if ( Bundle.INSTALLED == b[i].getState() || (Bundle.RESOLVED == b[i].getState())){
- try {
- b[i].start();
- } catch (BundleException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- private String stateToString(int state) {
- switch (state) {
- case Bundle.ACTIVE:
- return "ACTIVE";
- case Bundle.INSTALLED:
- return "INSTALLED";
- case Bundle.RESOLVED:
- return "RESOLVED";
- case Bundle.UNINSTALLED:
- return "UNINSTALLED";
- default:
- return "Not CONVERTED";
- }
- }
-
- @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("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()
- );
- }
-
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<persisted-snapshots>
- <snapshots>
- <snapshot>
- <required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
- </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: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:impl?module=opendaylight-sal-dom-broker-impl&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:md:sal:remote:rpc?module=odl-sal-dom-rpc-remote-cfg&revision=2013-10-28
- </capability>
- </required-capabilities>
- <configuration>
-
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:schema-service-singleton
- </type>
- <name>yang-schema-service</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:hash-map-data-store
- </type>
- <name>hash-map-data-store</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- prefix:dom-broker-impl
- </type>
- <name>dom-broker</name>
- <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-data-store
- </type>
- <name>ref_hash-map-data-store</name>
- </data-store>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-broker-impl
- </type>
- <name>binding-broker-impl</name>
- <notification-service
- xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
- </type>
- <name>ref_binding-notification-broker</name>
- </notification-service>
- <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-data-broker
- </type>
- <name>ref_binding-data-broker</name>
- </data-broker>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:runtime-generated-mapping
- </type>
- <name>runtime-mapping-singleton</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-notification-broker
- </type>
- <name>binding-notification-broker</name>
- </module>
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- prefix:binding-data-broker
- </type>
- <name>binding-data-broker</name>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-broker-osgi-registry
- </type>
- <name>ref_dom-broker</name>
- </dom-broker>
- <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- binding:binding-dom-mapping-service
- </type>
- <name>ref_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>
- <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:remote:rpc">
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- prefix:dom-broker-osgi-registry
- </type>
- <name>ref_dom-broker</name>
- </dom-broker>
- </module>
- </modules>
-
- <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:schema-service
- </type>
- <instance>
- <name>ref_yang-schema-service</name>
- <provider>
- /config/modules/module[name='schema-service-singleton']/instance[name='yang-schema-service']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
- </type>
- <instance>
- <name>ref_binding-notification-broker</name>
- <provider>
- /config/modules/module[name='binding-notification-broker']/instance[name='binding-notification-broker']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-data-store
- </type>
- <instance>
- <name>ref_hash-map-data-store</name>
- <provider>
- /config/modules/module[name='hash-map-data-store']/instance[name='hash-map-data-store']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-broker-osgi-registry
- </type>
- <instance>
- <name>ref_binding-broker-impl</name>
- <provider>
- /config/modules/module[name='binding-broker-impl']/instance[name='binding-broker-impl']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- binding-impl:binding-dom-mapping-service
- </type>
- <instance>
- <name>ref_runtime-mapping-singleton</name>
- <provider>
- /config/modules/module[name='runtime-generated-mapping']/instance[name='runtime-mapping-singleton']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">
- dom:dom-broker-osgi-registry
- </type>
- <instance>
- <name>ref_dom-broker</name>
- <provider>/config/modules/module[name='dom-broker-impl']/instance[name='dom-broker']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-data-broker
- </type>
- <instance>
- <name>ref_binding-data-broker</name>
- <provider>
- /config/modules/module[name='binding-data-broker']/instance[name='binding-data-broker']
- </provider>
- </instance>
- </service>
- </services>
- </data>
-
- </configuration>
- </snapshot>
- </snapshots>
-</persisted-snapshots>
+++ /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>
-
-
- <logger name="org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort" level="ERROR"/>
-
- <root level="info">
- <appender-ref ref="STDOUT" />
- </root>
-</configuration>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <artifactId>sal-remoterpc-connector-test-parent</artifactId>
- <groupId>org.opendaylight.controller.tests</groupId>
- <version>1.1-SNAPSHOT</version>
- </parent>
-
- <artifactId>sal-remoterpc-connector-test-nb</artifactId>
- <packaging>bundle</packaging>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <version>${bundle.plugin.version}</version>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- </Export-Package>
- <Import-Package>
- com.sun.jersey.spi.container.servlet,
- !org.codehaus.jackson.annotate,
- javax.ws.rs,
- javax.ws.rs.core,
- javax.xml.bind,
- javax.xml.bind.annotation,
- org.slf4j,
- org.apache.catalina.filters,
- !org.codehaus.jackson.jaxrs,
- org.opendaylight.controller.sample.zeromq.provider,
- org.opendaylight.controller.sample.zeromq.consumer,
- org.opendaylight.controller.sal.utils,
- org.opendaylight.yangtools.yang.common,
- org.opendaylight.controller.sal.connector.api,
- org.opendaylight.controller.sal.connector.remoterpc.api;version="[0.4,1)",
- org.opendaylight.controller.sal.connector.remoterpc.impl;version="[0.4,1)",
- org.opendaylight.controller.sal.connector.remoterpc.dto,
- org.opendaylight.controller.sal.connector.remoterpc.util,
- org.osgi.framework,
- com.google.common.base,
- org.opendaylight.yangtools.yang.data.api,
- !org.codehaus.enunciate.jaxrs
-
- </Import-Package>
- <Web-ContextPath>/controller/nb/v2/zmqnb</Web-ContextPath>
- <Jaxrs-Resources>,${classes;ANNOTATION;javax.ws.rs.Path}</Jaxrs-Resources>
- </instructions>
- <manifestLocation>${project.basedir}/src/main/resources/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>containermanager</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>commons.northbound</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-provider</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller.tests</groupId>
- <artifactId>sal-remoterpc-connector-test-consumer</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-remoterpc-connector</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>remoterpc-routingtable.implementation</artifactId>
- </dependency>
- <dependency>
- <groupId>com.google.guava</groupId>
- <artifactId>guava</artifactId>
- </dependency>
- </dependencies>
-
- </project>
+++ /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.tests.zmqrouter.rest;
-
-import org.opendaylight.controller.sal.connector.api.RpcRouter;
-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.impl.RoutingTableImpl;
-import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils;
-import org.opendaylight.controller.sample.zeromq.consumer.ExampleConsumer;
-import org.opendaylight.controller.sample.zeromq.provider.ExampleProvider;
-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.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.io.Serializable;
-import java.net.URI;
-import java.util.Set;
-
-@Path("router")
-public class Router {
- private Logger _logger = LoggerFactory.getLogger(Router.class);
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "heartbeat");
-
-
- @GET
- @Path("/hello")
- @Produces(MediaType.TEXT_PLAIN)
- public String hello() {
- return "Hello";
- }
-
- @GET
- @Path("/announce")
- @Produces(MediaType.TEXT_PLAIN)
- public String announce() {
- _logger.info("Announce request received");
-
- BundleContext ctx = getBundleContext();
- ServiceReference providerRef = ctx.getServiceReference(ExampleProvider.class);
- if (providerRef == null) {
- _logger.debug("Could not get provider reference");
- return "Could not get provider reference";
- }
-
- ExampleProvider provider = (ExampleProvider) ctx.getService(providerRef);
- if (provider == null) {
- _logger.info("Could not get provider service");
- return "Could not get provider service";
- }
-
- provider.announce(QNAME);
- return "Announcement sent ";
-
- }
-
- @GET
- @Path("/rpc")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpc() throws Exception {
- _logger.info("Invoking RPC");
-
- ExampleConsumer consumer = getConsumer();
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getValidCompositeNodeWithOneSimpleChild());
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/rpc-success")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpcSuccess() throws Exception {
- ExampleConsumer consumer = getConsumer();
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getValidCompositeNodeWithFourSimpleChildren()); //TODO: Change this
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/rpc-failure")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRpcFailure() throws Exception {
- ExampleConsumer consumer = getConsumer();
- //RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, consumer.getInvalidCompositeNodeCompositeChild()); //TODO: Change this
- RpcResult<CompositeNode> result = consumer.invokeRpc(QNAME, null); //TODO: Change this
- _logger.info("Result [{}]", result.isSuccessful());
-
- return stringify(result);
- }
-
- @GET
- @Path("/routingtable")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeRoutingTable() {
- _logger.info("Invoking adding an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTableImpl routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RoutingIdentifierImpl rii = new RoutingIdentifierImpl();
- try {
- routingTable.addGlobalRoute(rii.toString(), "172.27.12.1:5000");
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
- String result = routingTable.dumpRoutingTableCache();
-
-
-
-
- _logger.info("Result [{}] routes added for route" + rii + result);
-
- return result;
- }
-
- @GET
- @Path("/routingtabledelete")
- @Produces(MediaType.TEXT_PLAIN)
- public String invokeDeleteRoutingTable() {
- _logger.info("Invoking adding an entry in routing table");
-
- BundleContext ctx = getBundleContext();
- ServiceReference routingTableServiceReference = ctx.getServiceReference(RoutingTable.class);
- if (routingTableServiceReference == null) {
- _logger.debug("Could not get routing table impl reference");
- return "Could not get routingtable referen ";
- }
- RoutingTable routingTable = (RoutingTableImpl) ctx.getService(routingTableServiceReference);
- if (routingTable == null) {
- _logger.info("Could not get routing table service");
- return "Could not get routing table service";
- }
-
-
- RoutingIdentifierImpl rii = new RoutingIdentifierImpl();
- try {
- routingTable.removeGlobalRoute(rii.toString());
- } catch (RoutingTableException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
-
- } catch (SystemException e) {
- _logger.error("error in adding routing identifier" + e.getMessage());
- }
-
- Set<String> routes = routingTable.getRoutes(rii.toString());
-
- StringBuilder stringBuilder = new StringBuilder();
- if (routes != null) {
- for (String route : routes) {
- stringBuilder.append(route);
- }
- } else {
- stringBuilder.append(" successfully");
- }
-
- _logger.info("Result [{}] routes removed for route" + rii + stringBuilder.toString());
-
- return stringBuilder.toString();
- }
-
- private String stringify(RpcResult<CompositeNode> result) {
- CompositeNode node = result.getResult();
- StringBuilder builder = new StringBuilder("result:").append(XmlUtils.compositeNodeToXml(node)).append("\n")
- .append("error:").append(result.getErrors()).append("\n");
-
- return builder.toString();
- }
-
- private BundleContext getBundleContext() {
- ClassLoader tlcl = Thread.currentThread().getContextClassLoader();
- Bundle bundle = null;
-
- if (tlcl instanceof BundleReference) {
- bundle = ((BundleReference) tlcl).getBundle();
- } else {
- _logger.info("Unable to determine the bundle context based on " +
- "thread context classloader.");
- bundle = FrameworkUtil.getBundle(this.getClass());
- }
- return (bundle == null ? null : bundle.getBundleContext());
- }
-
- private ExampleConsumer getConsumer() {
- BundleContext ctx = getBundleContext();
- ServiceReference consumerRef = ctx.getServiceReference(ExampleConsumer.class);
- if (consumerRef == null) {
- _logger.debug("Could not get consumer reference");
- throw new NullPointerException("Could not get consumer reference");
- }
- ExampleConsumer consumer = (ExampleConsumer) ctx.getService(consumerRef);
- if (consumer == null) {
- _logger.info("Could not get consumer service");
- throw new NullPointerException("Could not get consumer service");
- }
- return consumer;
- }
-
- class RoutingIdentifierImpl implements RpcRouter.RouteIdentifier, Serializable {
-
- private final URI namespace = URI.create("http://cisco.com/example");
- private final QName QNAME = new QName(namespace, "global");
- private final QName instance = new QName(URI.create("127.0.0.1"), "local");
-
- @Override
- public QName getContext() {
- return QNAME;
- }
-
- @Override
- public QName getType() {
- return QNAME;
- }
-
- @Override
- 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;
- }
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- version="3.0">
- <servlet>
- <servlet-name>JAXRSZmq</servlet-name>
- <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
- <init-param>
- <param-name>javax.ws.rs.Application</param-name>
- <param-value>org.opendaylight.controller.northbound.commons.NorthboundApplication</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>JAXRSZmq</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
-
-
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>NB api</web-resource-name>
- <url-pattern>/*</url-pattern>
- <http-method>POST</http-method>
- <http-method>GET</http-method>
- <http-method>PUT</http-method>
- <http-method>PATCH</http-method>
- <http-method>DELETE</http-method>
- <http-method>HEAD</http-method>
- </web-resource-collection>
- <auth-constraint>
- <role-name>System-Admin</role-name>
- <role-name>Network-Admin</role-name>
- <role-name>Network-Operator</role-name>
- <role-name>Container-User</role-name>
- </auth-constraint>
- </security-constraint>
-
- <security-role>
- <role-name>System-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Admin</role-name>
- </security-role>
- <security-role>
- <role-name>Network-Operator</role-name>
- </security-role>
- <security-role>
- <role-name>Container-User</role-name>
- </security-role>
-
- <login-config>
- <auth-method>BASIC</auth-method>
- <realm-name>opendaylight</realm-name>
- </login-config>
-</web-app>
import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import javax.activation.UnsupportedDataTypeException;
-
import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-import com.google.gson.stream.JsonWriter;
-
class JsonMapper {
- private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
- private final Set<ListSchemaNode> foundLists = new HashSet<>();
private MountInstance mountPoint;
private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
}
writer.endObject();
-
- foundLeafLists.clear();
- foundLists.clear();
}
private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema)
throws IOException {
checkNotNull(parent);
+ final Set<QName> foundLists = new HashSet<>();
+
Set<DataSchemaNode> parentSchemaChildNodes = parentSchema == null ?
Collections.<DataSchemaNode>emptySet() : parentSchema.getChildNodes();
logger.debug( "No schema found for data node \"" + child.getNodeType() );
- handleNoSchemaFound( writer, child, parent );
+ if( !foundLists.contains( child.getNodeType() ) ) {
+ handleNoSchemaFound( writer, child, parent );
+
+ // Since we don't have a schema, we don't know which nodes are supposed to be
+ // lists so treat every one as a potential list to avoid outputting duplicates.
+
+ foundLists.add( child.getNodeType() );
+ }
}
else if (childSchema instanceof ContainerSchemaNode) {
Preconditions.checkState(child instanceof CompositeNode,
"Data representation of Container should be CompositeNode - " + child.getNodeType());
writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
} else if (childSchema instanceof ListSchemaNode) {
- if (!foundLists.contains(childSchema)) {
+ if (!foundLists.contains( child.getNodeType() ) ) {
Preconditions.checkState(child instanceof CompositeNode,
"Data representation of List should be CompositeNode - " + child.getNodeType());
- foundLists.add((ListSchemaNode) childSchema);
+ foundLists.add( child.getNodeType() );
writeList(writer, parent, (CompositeNode) child, (ListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafListSchemaNode) {
- if (!foundLeafLists.contains(childSchema)) {
+ if (!foundLists.contains( child.getNodeType() ) ) {
Preconditions.checkState(child instanceof SimpleNode<?>,
"Data representation of LeafList should be SimpleNode - " + child.getNodeType());
- foundLeafLists.add((LeafListSchemaNode) childSchema);
+ foundLists.add( child.getNodeType() );
writeLeafList(writer, parent, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafSchemaNode) {
Preconditions.checkState(child instanceof SimpleNode<?>,
"Data representation of LeafList should be SimpleNode - " + child.getNodeType());
writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
+ } else if (childSchema instanceof AnyXmlSchemaNode) {
+ if( child instanceof CompositeNode ) {
+ writeContainer(writer, (CompositeNode) child, null);
+ }
+ else {
+ handleNoSchemaFound( writer, child, parent );
+ }
} else {
throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
+ "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
}
}
+ }
- for (Node<?> child : parent.getValue()) {
- DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchemaChildNodes);
- if (childSchema instanceof LeafListSchemaNode) {
- foundLeafLists.remove(childSchema);
- } else if (childSchema instanceof ListSchemaNode) {
- foundLists.remove(childSchema);
- }
+ private void writeValue( final JsonWriter writer, Object value ) throws IOException {
+ if( value != null ) {
+ writer.value( String.valueOf( value ) );
+ }
+ else {
+ writer.value( "" );
}
}
private void handleNoSchemaFound( final JsonWriter writer, final Node<?> node,
final CompositeNode parent ) throws IOException {
if( node instanceof SimpleNode<?> ) {
- writeName( node, null, writer );
- Object value = node.getValue();
- if( value != null ) {
- writer.value( String.valueOf( value ) );
+ List<SimpleNode<?>> nodeLeafList = parent.getSimpleNodesByName( node.getNodeType() );
+ if( nodeLeafList.size() == 1 ) {
+ writeName( node, null, writer );
+ writeValue( writer, node.getValue() );
+ }
+ else { // more than 1, write as a json array
+ writeName( node, null, writer );
+ writer.beginArray();
+ for( SimpleNode<?> leafNode: nodeLeafList ) {
+ writeValue( writer, leafNode.getValue() );
+ }
+
+ writer.endArray();
}
} else { // CompositeNode
Preconditions.checkState( node instanceof CompositeNode,
"Data representation of Container should be CompositeNode - " + node.getNodeType() );
- writeContainer( writer, (CompositeNode) node, null );
+ List<CompositeNode> nodeList = parent.getCompositesByName( node.getNodeType() );
+ if( nodeList.size() == 1 ) {
+ writeContainer( writer, (CompositeNode) node, null );
+ }
+ else { // more than 1, write as a json array
+ writeList( writer, parent, (CompositeNode) node, null );
+ }
}
}
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
public boolean isInstantiatedDataSchema( final DataSchemaNode node ) {
return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode ||
- node instanceof ContainerSchemaNode || node instanceof ListSchemaNode;
+ node instanceof ContainerSchemaNode || node instanceof ListSchemaNode ||
+ node instanceof AnyXmlSchemaNode;
}
private void addKeyValue( final HashMap<QName, Object> map, final DataSchemaNode node,
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
}
}
- if ((nodeBuilder instanceof CompositeNodeWrapper)) {
- final List<NodeWrapper<?>> children = ((CompositeNodeWrapper) nodeBuilder).getValues();
- for (final NodeWrapper<? extends Object> child : children) {
- final List<DataSchemaNode> potentialSchemaNodes =
- this.controllerContext.findInstanceDataChildrenByName(
- ((DataNodeContainer) schema), child.getLocalName());
+ if ( nodeBuilder instanceof CompositeNodeWrapper ) {
+ if( schema instanceof DataNodeContainer ) {
+ normalizeCompositeNode( (CompositeNodeWrapper)nodeBuilder, (DataNodeContainer)schema,
+ mountPoint, currentAugment );
+ }
+ else if( schema instanceof AnyXmlSchemaNode ) {
+ normalizeAnyXmlNode( (CompositeNodeWrapper)nodeBuilder, (AnyXmlSchemaNode)schema );
+ }
+ }
+ else if ( nodeBuilder instanceof SimpleNodeWrapper ) {
+ normalizeSimpleNode( (SimpleNodeWrapper) nodeBuilder, schema, mountPoint );
+ }
+ else if ((nodeBuilder instanceof EmptyNodeWrapper)) {
+ normalizeEmptyNode( (EmptyNodeWrapper) nodeBuilder, schema );
+ }
+ }
- if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
- StringBuilder builder = new StringBuilder();
- for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
- builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
- .append("\n");
- }
+ private void normalizeAnyXmlNode( CompositeNodeWrapper compositeNode, AnyXmlSchemaNode schema ) {
+ List<NodeWrapper<?>> children = compositeNode.getValues();
+ for( NodeWrapper<? extends Object> child : children ) {
+ child.setNamespace( schema.getQName().getNamespace() );
+ if( child instanceof CompositeNodeWrapper ) {
+ normalizeAnyXmlNode( (CompositeNodeWrapper)child, schema );
+ }
+ }
+ }
- throw new RestconfDocumentedException(
- "Node \"" + child.getLocalName() +
- "\" is added as augment from more than one module. " +
- "Therefore node must have namespace (XML format) or module name (JSON format)." +
- "\nThe node is added as augment from modules with namespaces:\n" + builder,
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
- }
+ private void normalizeEmptyNode( EmptyNodeWrapper emptyNodeBuilder, DataSchemaNode schema ) {
+ if ((schema instanceof LeafSchemaNode)) {
+ emptyNodeBuilder.setComposite(false);
+ }
+ else {
+ if ((schema instanceof ContainerSchemaNode)) {
+ // FIXME: Add presence check
+ emptyNodeBuilder.setComposite(true);
+ }
+ }
+ }
+
+ private void normalizeSimpleNode( SimpleNodeWrapper simpleNode, DataSchemaNode schema,
+ MountInstance mountPoint ) {
+ final Object value = simpleNode.getValue();
+ Object inputValue = value;
+ TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
+ if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
+ if ((value instanceof String)) {
+ inputValue = new IdentityValuesDTO( simpleNode.getNamespace().toString(),
+ (String) value, null, (String) value );
+ } // else value is already instance of IdentityValuesDTO
+ }
+
+ Object outputValue = inputValue;
+
+ if( typeDefinition != null ) {
+ Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
+ outputValue = codec == null ? null : codec.deserialize(inputValue);
+ }
+
+ simpleNode.setValue(outputValue);
+ }
- boolean rightNodeSchemaFound = false;
+ private void normalizeCompositeNode( CompositeNodeWrapper compositeNodeBuilder,
+ DataNodeContainer schema, MountInstance mountPoint,
+ QName currentAugment ) {
+ final List<NodeWrapper<?>> children = compositeNodeBuilder.getValues();
+ for (final NodeWrapper<? extends Object> child : children) {
+ final List<DataSchemaNode> potentialSchemaNodes =
+ this.controllerContext.findInstanceDataChildrenByName(
+ schema, child.getLocalName());
+
+ if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
+ StringBuilder builder = new StringBuilder();
for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
- if (!rightNodeSchemaFound) {
- final QName potentialCurrentAugment =
- this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
- if (child.getQname() != null ) {
- this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
- rightNodeSchemaFound = true;
- }
- }
+ builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
+ .append("\n");
}
- if (!rightNodeSchemaFound) {
- throw new RestconfDocumentedException(
- "Schema node \"" + child.getLocalName() + "\" was not found in module.",
- ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
- }
+ throw new RestconfDocumentedException(
+ "Node \"" + child.getLocalName() +
+ "\" is added as augment from more than one module. " +
+ "Therefore node must have namespace (XML format) or module name (JSON format)." +
+ "\nThe node is added as augment from modules with namespaces:\n" + builder,
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
}
- if ((schema instanceof ListSchemaNode)) {
- final List<QName> listKeys = ((ListSchemaNode) schema).getKeyDefinition();
- for (final QName listKey : listKeys) {
- boolean foundKey = false;
- for (final NodeWrapper<? extends Object> child : children) {
- if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
- foundKey = true;
- }
- }
-
- if (!foundKey) {
- throw new RestconfDocumentedException(
- "Missing key in URI \"" + listKey.getLocalName() +
- "\" of list \"" + schema.getQName().getLocalName() + "\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+ boolean rightNodeSchemaFound = false;
+ for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
+ if (!rightNodeSchemaFound) {
+ final QName potentialCurrentAugment =
+ this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
+ if (child.getQname() != null ) {
+ this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
+ rightNodeSchemaFound = true;
}
}
}
- }
- else {
- if ((nodeBuilder instanceof SimpleNodeWrapper)) {
- final SimpleNodeWrapper simpleNode = ((SimpleNodeWrapper) nodeBuilder);
- final Object value = simpleNode.getValue();
- Object inputValue = value;
- TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
- if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
- if ((value instanceof String)) {
- inputValue = new IdentityValuesDTO( nodeBuilder.getNamespace().toString(),
- (String) value, null, (String) value );
- } // else value is already instance of IdentityValuesDTO
- }
- Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
- Object outputValue = codec == null ? null : codec.deserialize(inputValue);
-
- simpleNode.setValue(outputValue);
+ if (!rightNodeSchemaFound) {
+ throw new RestconfDocumentedException(
+ "Schema node \"" + child.getLocalName() + "\" was not found in module.",
+ ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
}
- else {
- if ((nodeBuilder instanceof EmptyNodeWrapper)) {
- final EmptyNodeWrapper emptyNodeBuilder = ((EmptyNodeWrapper) nodeBuilder);
- if ((schema instanceof LeafSchemaNode)) {
- emptyNodeBuilder.setComposite(false);
- }
- else {
- if ((schema instanceof ContainerSchemaNode)) {
- // FIXME: Add presence check
- emptyNodeBuilder.setComposite(true);
- }
+ }
+
+ if ((schema instanceof ListSchemaNode)) {
+ ListSchemaNode listSchemaNode = (ListSchemaNode)schema;
+ final List<QName> listKeys = listSchemaNode.getKeyDefinition();
+ for (final QName listKey : listKeys) {
+ boolean foundKey = false;
+ for (final NodeWrapper<? extends Object> child : children) {
+ if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
+ foundKey = true;
}
}
+
+ if (!foundKey) {
+ throw new RestconfDocumentedException(
+ "Missing key in URI \"" + listKey.getLocalName() +
+ "\" of list \"" + listSchemaNode.getQName().getLocalName() + "\"",
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+ }
}
}
}
else if (node instanceof LeafSchemaNode) {
return _typeDefinition((LeafSchemaNode)node);
}
+ else if (node instanceof AnyXmlSchemaNode) {
+ return null;
+ }
else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(node).toString());
}
+ static class ComplexAnyXmlVerifier extends LeafVerifier {
+
+ ComplexAnyXmlVerifier() {
+ super( null, JsonToken.BEGIN_OBJECT );
+ }
+
+ @Override
+ void verify( JsonReader reader, String keyName ) throws IOException {
+
+ reader.beginObject();
+ String innerKey = reader.nextName();
+ assertEquals( "Json reader child key for " + keyName, "data", innerKey );
+ assertEquals( "Json token type for key " + innerKey, JsonToken.BEGIN_OBJECT, reader.peek() );
+
+ reader.beginObject();
+ verifyLeaf( reader, innerKey, "leaf1", "leaf1-value" );
+ verifyLeaf( reader, innerKey, "leaf2", "leaf2-value" );
+
+ String nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + innerKey, "leaf-list", nextName );
+ reader.beginArray();
+ assertEquals( "Json value for key " + nextName, "leaf-list-value1", reader.nextString() );
+ assertEquals( "Json value for key " + nextName, "leaf-list-value2", reader.nextString() );
+ reader.endArray();
+
+ nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + innerKey, "list", nextName );
+ reader.beginArray();
+ verifyNestedLists( reader, 1 );
+ verifyNestedLists( reader, 3 );
+ reader.endArray();
+
+ reader.endObject();
+ reader.endObject();
+ }
+
+ void verifyNestedLists( JsonReader reader, int leafNum ) throws IOException {
+ reader.beginObject();
+
+ String nextName = reader.nextName();
+ assertEquals( "Json reader next name", "nested-list", nextName );
+
+ reader.beginArray();
+
+ reader.beginObject();
+ verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum++ );
+ reader.endObject();
+
+ reader.beginObject();
+ verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum );
+ reader.endObject();
+
+ reader.endArray();
+ reader.endObject();
+ }
+
+ void verifyLeaf( JsonReader reader, String parent, String name, String value ) throws IOException {
+ String nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + parent, name, nextName );
+ assertEquals( "Json token type for key " + parent, JsonToken.STRING, reader.peek() );
+ assertEquals( "Json value for key " + nextName, value, reader.nextString() );
+ }
+
+ @Override
+ Object getActualValue( JsonReader reader ) throws IOException {
+ return null;
+ }
+ }
+
@BeforeClass
public static void initialize() {
dataLoad("/cnsn-to-json/simple-data-types");
expectedMap.put( "lfunion14", new StringVerifier( "zero" ) );
expectedMap.put( "lfempty", new EmptyVerifier() );
expectedMap.put( "identityref1", new StringVerifier( "simple-data-types:iden" ) );
+ expectedMap.put( "complex-any", new ComplexAnyXmlVerifier() );
+ expectedMap.put( "simple-any", new StringVerifier( "simple" ) );
+ expectedMap.put( "empty-any", new StringVerifier( "" ) );
while (jReader.hasNext()) {
String keyName = jReader.nextName();
package org.opendaylight.controller.sal.restconf.impl.test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.io.ByteStreams;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
-
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Before;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.io.ByteStreams;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-
/**
* Unit tests for RestconfDocumentedExceptionMapper.
*
errorListEntrySet.iterator().next().getKey() );
assertTrue( "\"error\" Json element is not an Array", errorListElement.isJsonArray() );
+ // As a final check, make sure there aren't multiple "error" array elements. Unfortunately,
+ // the call above to getAsJsonObject().entrySet() will out duplicate "error" elements. So
+ // we'll use regex on the json string to verify this.
+
+ Matcher matcher = Pattern.compile( "\"error\"[ ]*:[ ]*\\[", Pattern.DOTALL ).matcher( bos.toString() );
+ assertTrue( "Expected 1 \"error\" element", matcher.find() );
+ assertFalse( "Found multiple \"error\" elements", matcher.find() );
+
return errorListElement.getAsJsonArray();
}
final ErrorInfoVerifier errorInfoVerifier ) {
JsonElement errorInfoElement = null;
- Map<String, String> actualErrorInfo = null;
Map<String, String> leafMap = Maps.newHashMap();
for( Entry<String, JsonElement> entry: errorEntryElement.getAsJsonObject().entrySet() ) {
String leafName = entry.getKey();
*/
package org.opendaylight.controller.sal.restconf.impl.test.structures;
+import static org.junit.Assert.assertFalse;
import java.util.HashMap;
import java.util.Map;
}
public void addLfLst(LfLst lfLst) {
+ assertFalse( "Found multiple leaf list elements for " + lfLst.getName(),
+ lfLsts.containsKey( lfLst.getName() ) );
lfLsts.put(lfLst.getName(), lfLst);
}
public void addLst(Lst lst) {
+ assertFalse( "Found multiple list elements for " + lst.getName(),
+ lsts.containsKey( lst.getName() ) );
lsts.put(lst.getName(), lst);
}
}
}
-
+ anyxml complex-any;
+
+ anyxml simple-any;
+
+ anyxml empty-any;
}
}
\ No newline at end of file
<lfenum>enum3</lfenum>
<lfbits>bit3 bit2</lfbits>
<lfbinary>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</lfbinary>
- <lfempty />
<lfunion1>324</lfunion1>
<lfunion2>33.3</lfunion2>
<lfunion3>55</lfunion3>
<lfunion12>false</lfunion12>
<lfunion13>b1</lfunion13>
<lfunion14>zero</lfunion14>
+ <lfempty />
<identityref1 xmlns:x="simple:data:types">x:iden</identityref1>
-</cont>
\ No newline at end of file
+ <complex-any>
+ <data>
+ <leaf1>leaf1-value</leaf1>
+ <leaf2>leaf2-value</leaf2>
+
+ <leaf-list>leaf-list-value1</leaf-list>
+ <leaf-list>leaf-list-value2</leaf-list>
+
+ <list>
+ <nested-list>
+ <nested-leaf>nested-value1</nested-leaf>
+ </nested-list>
+ <nested-list>
+ <nested-leaf>nested-value2</nested-leaf>
+ </nested-list>
+ </list>
+
+ <list>
+ <nested-list>
+ <nested-leaf>nested-value3</nested-leaf>
+ </nested-list>
+ <nested-list>
+ <nested-leaf>nested-value4</nested-leaf>
+ </nested-list>
+ </list>
+ </data>
+ </complex-any>
+ <simple-any>simple</simple-any>
+ <empty-any></empty-any>
+</cont>
Set<Capability> capabilities = new HashSet<>();
// [RFC6241] 8.3. Candidate Configuration Capability
capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:candidate:1.0"));
+
+ // TODO rollback on error not supported EditConfigXmlParser:100
// [RFC6241] 8.5. Rollback-on-Error Capability
- capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
+ // capabilities.add(new BasicCapability("urn:ietf:params:netconf:capability:rollback-on-error:1.0"));
Set<Module> modules = yangStoreSnapshot.getModules();
for (Module module : modules) {
package org.opendaylight.controller.netconf.persist.impl;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Function;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Collections2;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.SortedSet;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
-
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.NetconfDocumentedException;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Stopwatch;
-import com.google.common.collect.Collections2;
-
@Immutable
public class ConfigPusher {
private static final Logger logger = LoggerFactory.getLogger(ConfigPusher.class);
ConflictingVersionException lastException;
Stopwatch stopwatch = new Stopwatch().start();
do {
- try (NetconfOperationService operationService = getOperationServiceWithRetries(configSnapshotHolder.getCapabilities(), configSnapshotHolder.toString())) {
+ String idForReporting = configSnapshotHolder.toString();
+ SortedSet<String> expectedCapabilities = checkNotNull(configSnapshotHolder.getCapabilities(),
+ "Expected capabilities must not be null - %s, check %s", idForReporting,
+ configSnapshotHolder.getClass().getName());
+ try (NetconfOperationService operationService = getOperationServiceWithRetries(expectedCapabilities, idForReporting)) {
return pushConfig(configSnapshotHolder, operationService);
} catch (ConflictingVersionException e) {
lastException = e;
private static NetconfMessage createEditConfigMessage(Element dataElement) throws NetconfDocumentedException {
String editConfigResourcePath = "/netconfOp/editConfig.xml";
try (InputStream stream = ConfigPersisterNotificationHandler.class.getResourceAsStream(editConfigResourcePath)) {
- Preconditions.checkNotNull(stream, "Unable to load resource " + editConfigResourcePath);
+ checkNotNull(stream, "Unable to load resource " + editConfigResourcePath);
Document doc = XmlUtil.readXmlToDocument(stream);
private static NetconfMessage getCommitMessage() {
String resource = "/netconfOp/commit.xml";
try (InputStream stream = ConfigPusher.class.getResourceAsStream(resource)) {
- Preconditions.checkNotNull(stream, "Unable to load resource " + resource);
+ checkNotNull(stream, "Unable to load resource " + resource);
return new NetconfMessage(XmlUtil.readXmlToDocument(stream));
} catch (SAXException | IOException e) {
// error reading the xml file bundled into the jar
}
notificationVerifier.assertNotificationCount(2);
- notificationVerifier.assertNotificationContent(0, 0, 0, 9);
- notificationVerifier.assertNotificationContent(1, 4, 3, 9);
+ notificationVerifier.assertNotificationContent(0, 0, 0, 8);
+ notificationVerifier.assertNotificationContent(1, 4, 3, 8);
mockedAggregator.assertSnapshotCount(2);
// Capabilities are stripped for persister
import org.opendaylight.controller.sal.core.NodeConnector;
import org.opendaylight.controller.sal.core.Property;
import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.packet.Ethernet;
import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService;
+import org.opendaylight.controller.sal.packet.PacketException;
import org.opendaylight.controller.sal.packet.PacketResult;
import org.opendaylight.controller.sal.packet.RawPacket;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
import org.openflow.protocol.OFMessage;
import org.openflow.protocol.OFPacketIn;
import org.openflow.protocol.OFPacketOut;
@Override
public void receive(ISwitch sw, OFMessage msg) {
- if (sw == null || msg == null
- || this.pluginOutDataPacketServices == null) {
+ if (sw == null || msg == null || this.pluginOutDataPacketServices == null) {
// Something fishy, we cannot do anything
- logger.debug(
- "sw: {} and/or msg: {} and/or pluginOutDataPacketServices: {} is null!",
- new Object[] { sw, msg, this.pluginOutDataPacketServices });
+ logger.debug("sw: {} and/or msg: {} and/or pluginOutDataPacketServices: {} is null!", new Object[] { sw,
+ msg, this.pluginOutDataPacketServices });
return;
}
logger.debug("Connection service refused DataPacketMuxDemux receive {} {}", sw, msg);
return;
}
- }
- catch (Exception e) {
+ } catch (Exception e) {
return;
}
// pass the parsed packet simply because once the
// packet infra is settled all the packets will passed
// around as parsed and read-only
- for (int i = 0; i < this.iDataPacketListen.size(); i++) {
- IDataPacketListen s = this.iDataPacketListen.get(i);
- if (s.receiveDataPacket(dataPacket).equals(
- PacketResult.CONSUME)) {
+ for (IDataPacketListen s : this.iDataPacketListen) {
+ if (s.receiveDataPacket(dataPacket).equals(PacketResult.CONSUME)) {
logger.trace("Consumed locally data packet");
return;
}
}
- // Now dispatch the packet toward SAL at least for
- // default container, we need to revisit this in a general
- // slicing architecture refresh
- IPluginOutDataPacketService defaultOutService = this.pluginOutDataPacketServices
- .get(GlobalConstants.DEFAULT.toString());
- if (defaultOutService != null) {
- defaultOutService.receiveDataPacket(dataPacket);
- if (logger.isTraceEnabled()) {
- logger.trace(
- "Dispatched to apps a frame of size: {} on " +
- "container: {}: {}", new Object[] {
- ofPacket.getPacketData().length,
- GlobalConstants.DEFAULT.toString(),
- HexEncode.bytesToHexString(dataPacket
- .getPacketData()) });
- }
- }
+ boolean dispatched_to_container = false;
+
// Now check the mapping between nodeConnector and
// Container and later on optimally filter based on
// flowSpec
List<String> containersRX = this.nc2Container.get(p);
if (containersRX != null) {
- for (int i = 0; i < containersRX.size(); i++) {
- String container = containersRX.get(i);
- IPluginOutDataPacketService s = this.pluginOutDataPacketServices
- .get(container);
- if (s != null) {
- // TODO add filtering on a per-flowSpec base
- s.receiveDataPacket(dataPacket);
- if (logger.isTraceEnabled()) {
- logger.trace(
- "Dispatched to apps a frame of size: {}" +
- " on container: {}: {}", new Object[] {
- ofPacket.getPacketData().length,
- container,
- HexEncode.bytesToHexString(dataPacket
- .getPacketData()) });
+ Ethernet frame = new Ethernet();
+ byte data[] = dataPacket.getPacketData();
+ frame.deserialize(data, 0, data.length * NetUtils.NumBitsInAByte);
+ Match packetMatch = frame.getMatch();
+ for (String container : containersRX) {
+ boolean notify = true;
+ List<ContainerFlow> containerFlows = this.container2FlowSpecs.get(container);
+ if (containerFlows != null) {
+ notify = false;
+ for (ContainerFlow cFlow : containerFlows) {
+ if (cFlow.allowsMatch(packetMatch)) {
+ notify = true;
+ break;
+ }
+ }
+ if (notify) {
+ IPluginOutDataPacketService s = this.pluginOutDataPacketServices.get(container);
+ if (s != null) {
+ s.receiveDataPacket(dataPacket);
+ if (logger.isTraceEnabled()) {
+ logger.trace(
+ "Dispatched to apps a frame of size: {}" + " on container: {}: {}",
+ new Object[] { ofPacket.getPacketData().length, container,
+ HexEncode.bytesToHexString(dataPacket.getPacketData()) });
+ }
+ }
+ dispatched_to_container = true;
}
}
}
}
-
+ if (!dispatched_to_container) {
+ // Now dispatch the packet toward SAL for default container
+ IPluginOutDataPacketService defaultOutService = this.pluginOutDataPacketServices
+ .get(GlobalConstants.DEFAULT.toString());
+ if (defaultOutService != null) {
+ defaultOutService.receiveDataPacket(dataPacket);
+ if (logger.isTraceEnabled()) {
+ logger.trace("Dispatched to apps a frame of size: {} on " + "container: {}: {}",
+ new Object[] { ofPacket.getPacketData().length,
+ GlobalConstants.DEFAULT.toString(),
+ HexEncode.bytesToHexString(dataPacket.getPacketData()) });
+ }
+ }
+ }
// This is supposed to be the catch all for all the
// DataPacket hence we will assume it has been handled
return;
} catch (ConstructionException cex) {
+ } catch (PacketException e) {
+ logger.debug("Failed to deserialize raw packet: ", e.getMessage());
}
-
// If we reach this point something went wrong.
return;
} else {
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (!super.equals(obj))
+ }
+ if (!super.equals(obj)) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
+ }
ARP other = (ARP) obj;
if (fieldValues == null) {
- if (other.fieldValues != null)
+ if (other.fieldValues != null) {
return false;
- } else if (!fieldValues.equals(other.fieldValues))
+ }
+ } else if (!fieldValues.equals(other.fieldValues)) {
return false;
+ }
return true;
}
}
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.EtherTypes;
import org.opendaylight.controller.sal.utils.NetUtils;
return this;
}
+ @Override
+ public void populateMatch(Match match) {
+ match.setField(MatchType.DL_SRC, this.getSourceMACAddress());
+ match.setField(MatchType.DL_DST, this.getDestinationMACAddress());
+ match.setField(MatchType.DL_TYPE, this.getEtherType());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import java.util.Map;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
/**
* Class that represents the IEEE 802.1Q objects
return this;
}
+ @Override
+ public void populateMatch(Match match) {
+ match.setField(MatchType.DL_VLAN, this.getVid());
+ match.setField(MatchType.DL_VLAN_PR, this.getPcp());
+ match.setField(MatchType.DL_TYPE, this.getEtherType());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.IPProtocols;
import org.opendaylight.controller.sal.utils.NetUtils;
import org.slf4j.Logger;
corrupted = true;
}
}
+
+ @Override
+ public void populateMatch(Match match) {
+ match.setField(MatchType.NW_SRC, NetUtils.getInetAddress(this.getSourceAddress()));
+ match.setField(MatchType.NW_DST, NetUtils.getInetAddress(this.getDestinationAddress()));
+ match.setField(MatchType.NW_PROTO, this.getProtocol());
+ match.setField(MatchType.NW_TOS, this.getDiffServ());
+ }
}
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.NetUtils;
@Override
public boolean equals(Object obj) {
- if (this == obj)
+ if (this == obj) {
return true;
- if (!super.equals(obj))
+ }
+ if (!super.equals(obj)) {
return false;
- if (getClass() != obj.getClass())
+ }
+ if (getClass() != obj.getClass()) {
return false;
+ }
LLDPTLV other = (LLDPTLV) obj;
if (fieldValues == null) {
- if (other.fieldValues != null)
+ if (other.fieldValues != null) {
return false;
- } else if (!fieldValues.equals(other.fieldValues))
+ }
+ } else if (!fieldValues.equals(other.fieldValues)) {
return false;
+ }
return true;
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import java.util.Map.Entry;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.utils.HexEncode;
import org.opendaylight.controller.sal.utils.NetUtils;
import org.slf4j.Logger;
return true;
}
+ /**
+ * Adds to the passed Match this packet's header fields
+ *
+ * @param match
+ * The Match object to populate
+ */
+ public void populateMatch(Match match) {
+ // To be overridden by derived packet classes which have well known
+ // header fields so that Packet.getMatch would return desired result
+ }
+
+ /**
+ * Returns the Match object containing this packet and its payload
+ * encapsulated packets' header fields
+ *
+ * @return The Match containing the header fields of this packet and of its
+ * payload encapsulated packets
+ */
+ public Match getMatch() {
+ Match match = new Match();
+ Packet packet = this;
+ while (packet != null) {
+ packet.populateMatch(match);
+ packet = packet.getPayload();
+ }
+ return match;
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
/**
* Class that represents the TCP segment objects
return (BitBufferHelper.getShort(fieldValues.get(CHECKSUM)));
}
+ @Override
+ public void populateMatch(Match match) {
+ match.setField(MatchType.TP_SRC, this.getSourcePort());
+ match.setField(MatchType.TP_DST, this.getDestinationPort());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
/**
* Class that represents the UDP datagram objects
fieldValues.put(CHECKSUM, checksum);
return this;
}
+
+ @Override
+ public void populateMatch(Match match) {
+ match.setField(MatchType.TP_SRC, this.getSourcePort());
+ match.setField(MatchType.TP_DST, this.getDestinationPort());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
package org.opendaylight.controller.sal.packet;
+import java.util.Arrays;
+
import junit.framework.Assert;
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.EtherTypes;
public class EthernetTest {
}
+ @Test
+ public void testGetMatch() throws Exception {
+ Ethernet eth = new Ethernet();
+ byte smac[] = { (byte) 0xf0, (byte) 0xde, (byte) 0xf1, (byte) 0x71, (byte) 0x72, (byte) 0x8d };
+ byte dmac[] = { (byte) 0xde, (byte) 0x28, (byte) 0xdb, (byte) 0xb3, (byte) 0x7c, (byte) 0xf8 };
+ short ethType = EtherTypes.IPv4.shortValue();
+ eth.setDestinationMACAddress(dmac);
+ eth.setSourceMACAddress(smac);
+ eth.setEtherType(ethType);
+
+ Match match = eth.getMatch();
+
+ Assert.assertTrue(Arrays.equals(smac, (byte[]) match.getField(MatchType.DL_SRC).getValue()));
+ Assert.assertTrue(Arrays.equals(dmac, (byte[]) match.getField(MatchType.DL_DST).getValue()));
+ Assert.assertEquals(ethType, (short) match.getField(MatchType.DL_TYPE).getValue());
+
+ }
+
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
package org.opendaylight.controller.sal.packet;
import junit.framework.Assert;
+
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.EtherTypes;
import org.opendaylight.controller.sal.utils.NetUtils;
public class IEEE8021QTest {
Assert.assertTrue(data[44] == (byte) 0x09);
Assert.assertTrue(data[45] == (byte) 0xFE);
}
+
+ @Test
+ public void testGetMatchFullPacket() throws Exception {
+ IEEE8021Q dot1q = new IEEE8021Q();
+ byte priority = 4;
+ short vlanId = 59;
+ short ethType = EtherTypes.IPv4.shortValue();
+ dot1q.setPcp(priority);
+ dot1q.setVid(vlanId);
+ dot1q.setEtherType(ethType);
+
+ Match match = dot1q.getMatch();
+
+ Assert.assertEquals(priority, (byte) match.getField(MatchType.DL_VLAN_PR).getValue());
+ Assert.assertEquals(vlanId, (short) match.getField(MatchType.DL_VLAN).getValue());
+ Assert.assertEquals(ethType, (short) match.getField(MatchType.DL_TYPE).getValue());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import junit.framework.Assert;
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.EtherTypes;
import org.opendaylight.controller.sal.utils.IPProtocols;
import org.opendaylight.controller.sal.utils.NetUtils;
Assert.assertFalse(decIcmp.isCorrupted());
Assert.assertTrue(Arrays.equals(icmpRawPayload, decIcmp.getRawPayload()));
}
+
+ @Test
+ public void testGetMatch() throws Exception {
+ IPv4 ip = new IPv4();
+ InetAddress sourceAddress = InetAddress.getByName("172.168.190.15");
+ InetAddress destintationAddress = InetAddress.getByName("23.128.0.11");
+ byte protocol = IPProtocols.TCP.byteValue();
+ byte tos = 7;
+ ip.setVersion((byte) 4);
+ ip.setIdentification((short) 5);
+ ip.setDiffServ(tos);
+ ip.setECN((byte) 0);
+ ip.setTotalLength((short) 84);
+ ip.setFlags((byte) 2);
+ ip.setFragmentOffset((short) 0);
+ ip.setTtl((byte) 64);
+ ip.setProtocol(protocol);
+ ip.setDestinationAddress(destintationAddress);
+ ip.setSourceAddress(sourceAddress);
+
+ Match match = ip.getMatch();
+
+ Assert.assertEquals(sourceAddress, match.getField(MatchType.NW_SRC).getValue());
+ Assert.assertEquals(destintationAddress, match.getField(MatchType.NW_DST).getValue());
+ Assert.assertEquals(protocol, (byte) match.getField(MatchType.NW_PROTO).getValue());
+ Assert.assertEquals(tos, (byte) match.getField(MatchType.NW_TOS).getValue());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
package org.opendaylight.controller.sal.packet;
+import java.net.InetAddress;
+import java.util.Arrays;
import java.util.Map;
import junit.framework.Assert;
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.controller.sal.utils.EtherTypes;
+import org.opendaylight.controller.sal.utils.IPProtocols;
public class PacketTest {
eth.setSourceMACAddress(sMAC);
eth.setEtherType(etherType);
- dMACdata = (byte[]) fCValues.get("DestinationMACAddress");
- sMACdata = (byte[]) fCValues.get("SourceMACAddress");
- etherTypedata = (byte[]) fCValues.get("EtherType");
+ dMACdata = fCValues.get("DestinationMACAddress");
+ sMACdata = fCValues.get("SourceMACAddress");
+ etherTypedata = fCValues.get("EtherType");
Assert.assertTrue(dMACdata[0] == 10);
Assert.assertTrue(dMACdata[1] == 12);
Assert.assertTrue(data[13] == 6);
}
+
+ @Test
+ public void testGetMatch() throws Exception {
+ TCP tcp = new TCP();
+ short sport = (short) 11093;
+ short dport = (short) 23;
+ tcp.setSourcePort(sport);
+ tcp.setDestinationPort(dport);
+
+ IPv4 ip = new IPv4();
+ InetAddress sourceAddress = InetAddress.getByName("192.168.100.100");
+ InetAddress destintationAddress = InetAddress.getByName("192.168.100.101");
+ byte protocol = IPProtocols.TCP.byteValue();
+ byte tos = 5;
+ ip.setVersion((byte) 4);
+ ip.setIdentification((short) 5);
+ ip.setDiffServ(tos);
+ ip.setECN((byte) 0);
+ ip.setTotalLength((short) 84);
+ ip.setFlags((byte) 2);
+ ip.setFragmentOffset((short) 0);
+ ip.setTtl((byte) 64);
+ ip.setProtocol(protocol);
+ ip.setDestinationAddress(destintationAddress);
+ ip.setSourceAddress(sourceAddress);
+ ip.setPayload(tcp);
+
+ IEEE8021Q dot1q = new IEEE8021Q();
+ byte priority = 4;
+ short vlanId = 59;
+ short ethType = EtherTypes.IPv4.shortValue();
+ dot1q.setPcp(priority);
+ dot1q.setVid(vlanId);
+ dot1q.setEtherType(ethType);
+ dot1q.setPayload(ip);
+
+ Ethernet eth = new Ethernet();
+ byte smac[] = { (byte) 0xf0, (byte) 0xde, (byte) 0xf1, (byte) 0x71, (byte) 0x72, (byte) 0x8d };
+ byte dmac[] = { (byte) 0xde, (byte) 0x28, (byte) 0xdb, (byte) 0xb3, (byte) 0x7c, (byte) 0xf8 };
+ eth.setDestinationMACAddress(dmac);
+ eth.setSourceMACAddress(smac);
+ eth.setEtherType(EtherTypes.VLANTAGGED.shortValue());
+ eth.setPayload(dot1q);
+
+ Match match = eth.getMatch();
+
+ Assert.assertTrue(Arrays.equals(smac, (byte[]) match.getField(MatchType.DL_SRC).getValue()));
+ Assert.assertTrue(Arrays.equals(dmac, (byte[]) match.getField(MatchType.DL_DST).getValue()));
+ Assert.assertEquals(priority, (byte) match.getField(MatchType.DL_VLAN_PR).getValue());
+ Assert.assertEquals(vlanId, (short) match.getField(MatchType.DL_VLAN).getValue());
+ Assert.assertEquals(ethType, (short) match.getField(MatchType.DL_TYPE).getValue());
+ Assert.assertEquals(sourceAddress, match.getField(MatchType.NW_SRC).getValue());
+ Assert.assertEquals(destintationAddress, match.getField(MatchType.NW_DST).getValue());
+ Assert.assertEquals(protocol, (byte) match.getField(MatchType.NW_PROTO).getValue());
+ Assert.assertEquals(tos, (byte) match.getField(MatchType.NW_TOS).getValue());
+ Assert.assertEquals(sport, (short) match.getField(MatchType.TP_SRC).getValue());
+ Assert.assertEquals(dport, (short) match.getField(MatchType.TP_DST).getValue());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import junit.framework.Assert;
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
public class TCPTest {
short checksum = tcp.getChecksum();
Assert.assertTrue(checksum == 200);
}
+
+ @Test
+ public void testGetMatch() throws Exception {
+ TCP tcp = new TCP();
+ short sport = (short) 52012;
+ short dport = (short) 40345;
+ tcp.setSourcePort(sport);
+ tcp.setDestinationPort(dport);
+
+ Match match = tcp.getMatch();
+
+ Assert.assertEquals(sport, (short) match.getField(MatchType.TP_SRC).getValue());
+ Assert.assertEquals(dport, (short) match.getField(MatchType.TP_DST).getValue());
+ }
}
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-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,
import junit.framework.Assert;
import org.junit.Test;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchType;
public class UDPTest {
}
+ @Test
+ public void testGetMatch() throws Exception {
+ UDP udp = new UDP();
+ short sport = (short) 33000;
+ short dport = (short) 843;
+ udp.setSourcePort(sport);
+ udp.setDestinationPort(dport);
+
+ Match match = udp.getMatch();
+
+ Assert.assertEquals(sport, (short) match.getField(MatchType.TP_SRC).getValue());
+ Assert.assertEquals(dport, (short) match.getField(MatchType.TP_DST).getValue());
+
+ }
+
}