</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) {
<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.parent</artifactId>
- <version>1.0.2-SNAPSHOT</version>
- <relativePath>../parent</relativePath>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>odlparent</artifactId>
+ <version>1.4.2-SNAPSHOT</version>
+ <relativePath></relativePath>
</parent>
+
+ <groupId>org.opendaylight.controller</groupId>
<artifactId>commons.opendaylight</artifactId>
<version>1.4.2-SNAPSHOT</version>
<packaging>pom</packaging>
</prerequisites>
<properties>
+
<akka.version>2.3.2</akka.version>
<aopalliance.version>1.0.0</aopalliance.version>
<appauth.version>0.4.2-SNAPSHOT</appauth.version>
<commons.io.version>2.4</commons.io.version>
<commons.jasper>7.0.32.v201211201952</commons.jasper>
<commons.juli.version>7.0.32.v201211081135</commons.juli.version>
- <commons.lang.version>2.6</commons.lang.version>
<commons.lang3.version>3.1</commons.lang3.version>
<commons.logback_settings.version>0.0.2-SNAPSHOT</commons.logback_settings.version>
<commons.net.version>3.0.1</commons.net.version>
<commons.tomcat.api>7.0.32.v201211081135</commons.tomcat.api>
<commons.tomcat.util>7.0.32.v201211201952</commons.tomcat.util>
<compiler.version>2.3.2</compiler.version>
+ <commons.httpclient.version>0.1.2-SNAPSHOT</commons.httpclient.version>
<concepts.version>0.5.2-SNAPSHOT</concepts.version>
<config.version>0.2.5-SNAPSHOT</config.version>
<configuration.implementation.version>0.4.3-SNAPSHOT</configuration.implementation.version>
<containermanager.shell.version>0.5.2-SNAPSHOT</containermanager.shell.version>
<containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
<controllermanager.northbound.version>0.0.2-SNAPSHOT</controllermanager.northbound.version>
- <corsfilter.version>7.0.42</corsfilter.version>
- <ctrie.version>0.2.0</ctrie.version>
<devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
<dummy-console.version>1.1.0-SNAPSHOT</dummy-console.version>
<eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<exam.version>3.0.0</exam.version>
<!-- OpenEXI third party lib for netconf-->
+
<exi.nagasena.version>0000.0002.0038.0</exi.nagasena.version>
- <failsafe.version>2.15</failsafe.version>
- <feature.transaction.version>1.0.1</feature.transaction.version>
- <felix.dependencymanager.shell.version>3.0.1</felix.dependencymanager.shell.version>
- <felix.dependencymanager.version>3.1.0</felix.dependencymanager.version>
- <felix.fileinstall.version>3.1.6</felix.fileinstall.version>
- <felix.webconsole.version>4.2.0</felix.webconsole.version>
<filtervalve.version>1.4.2-SNAPSHOT</filtervalve.version>
<findbugs.maven.plugin.version>2.4.0</findbugs.maven.plugin.version>
<flowprogrammer.northbound.version>0.4.2-SNAPSHOT</flowprogrammer.northbound.version>
<forwarding.staticrouting.northbound.version>0.4.2-SNAPSHOT</forwarding.staticrouting.northbound.version>
<forwardingrulesmanager.implementation.version>0.4.2-SNAPSHOT</forwardingrulesmanager.implementation.version>
<forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
- <geminiweb.version>2.2.0.RELEASE</geminiweb.version>
- <gson.version>2.2.4</gson.version>
- <guava.version>14.0.1</guava.version>
<hosttracker.api.version>0.5.2-SNAPSHOT</hosttracker.api.version>
<hosttracker.implementation.version>0.5.2-SNAPSHOT</hosttracker.implementation.version>
<hosttracker.northbound.version>0.4.2-SNAPSHOT</hosttracker.northbound.version>
<ietf-restconf.version>2013.10.19.1-SNAPSHOT</ietf-restconf.version>
<ietf-topology.version>2013.10.21.2-SNAPSHOT</ietf-topology.version>
<ietf-yang-types.version>2010.09.24.4-SNAPSHOT</ietf-yang-types.version>
- <jackson.version>2.3.2</jackson.version>
- <jacoco.version>0.6.2.201302030002</jacoco.version>
- <jar.plugin.version>2.4</jar.plugin.version>
- <java.version.source>1.7</java.version.source>
- <java.version.target>1.7</java.version.target>
- <javassist.version>3.17.1-GA</javassist.version>
- <javax.annotation.version>1.2</javax.annotation.version>
<jdepend.maven.plugin.version>2.0-beta-2</jdepend.maven.plugin.version>
- <!-- Third party version -->
- <jersey-servlet.version>1.17</jersey-servlet.version>
- <jersey.version>1.17</jersey.version>
- <jersey2.publisher.version>4.0</jersey2.publisher.version>
- <jersey2.version>2.8</jersey2.version>
- <jettison.version>1.3.3</jettison.version>
<jmxGeneratorPath>src/main/yang-gen-config</jmxGeneratorPath>
<jolokia-bridge.version>0.0.2-SNAPSHOT</jolokia-bridge.version>
<jolokia.version>1.1.4</jolokia.version>
<lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
<logback.version>1.0.9</logback.version>
<logging.bridge.version>0.4.2-SNAPSHOT</logging.bridge.version>
- <maven.compile.plugin.version>2.5.1</maven.compile.plugin.version>
- <!-- Java Versions -->
- <maven.compiler.source>1.7</maven.compiler.source>
- <maven.compiler.target>1.7</maven.compiler.target>
<maven.plugin.api.version>3.0.5</maven.plugin.api.version>
<mdsal.version>1.1-SNAPSHOT</mdsal.version>
- <mockito.version>1.9.5</mockito.version>
<netconf.version>0.2.5-SNAPSHOT</netconf.version>
- <netty.version>4.0.19.Final</netty.version>
<networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
<networkconfig.neutron.implementation.version>0.4.2-SNAPSHOT</networkconfig.neutron.implementation.version>
<networkconfig.neutron.northbound.version>0.4.2-SNAPSHOT</networkconfig.neutron.northbound.version>
<northbound.hosttracker.version>1.4.2-SNAPSHOT</northbound.hosttracker.version>
<northbound.jolokia.version>1.4.2-SNAPSHOT</northbound.jolokia.version>
<opendaylight-l2-types.version>2013.08.27.4-SNAPSHOT</opendaylight-l2-types.version>
- <org.json.version>20080701</org.json.version>
<osgi-brandfragment.web.version>0.0.2-SNAPSHOT</osgi-brandfragment.web.version>
- <osgi.compendium.version>5.0.0</osgi.compendium.version>
- <osgi.core.version>5.0.0</osgi.core.version>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <projectinfo>2.6</projectinfo>
<propertymavenplugin.version>1.0-alpha-2</propertymavenplugin.version>
<protocol-framework.version>0.5.0-SNAPSHOT</protocol-framework.version>
<protocol_plugins.openflow.version>0.4.2-SNAPSHOT</protocol_plugins.openflow.version>
<protocol_plugins.stub.version>0.4.2-SNAPSHOT</protocol_plugins.stub.version>
- <releaseplugin.version>2.3.2</releaseplugin.version>
<routing.dijkstra_implementation.version>0.4.2-SNAPSHOT</routing.dijkstra_implementation.version>
<sal.connection.version>0.1.2-SNAPSHOT</sal.connection.version>
<sal.implementation.version>0.4.2-SNAPSHOT</sal.implementation.version>
<scala.version>2.11</scala.version>
<security.version>0.4.2-SNAPSHOT</security.version>
<sitedeploy>dav:http://nexus.opendaylight.org/content/sites/site</sitedeploy>
- <siteplugin>3.2</siteplugin>
- <slf4j.version>1.7.2</slf4j.version>
<sonar.branch>${user.name}-private-view</sonar.branch>
<sonar.host.url>https://sonar.opendaylight.org/</sonar.host.url>
<!-- Sonar properties using jacoco to retrieve integration test results -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.language>java</sonar.language>
<sonar.skippedModules>org.openflow.openflowj,net.sf.jung2</sonar.skippedModules>
- <spifly.version>1.0.0</spifly.version>
- <spring-osgi.version>1.2.1</spring-osgi.version>
- <spring-security-karaf.version>3.1.4.RELEASE</spring-security-karaf.version>
- <spring-security.version>3.1.3.RELEASE</spring-security.version>
- <spring.version>3.1.3.RELEASE</spring.version>
<statistics.northbound.version>0.4.2-SNAPSHOT</statistics.northbound.version>
<statisticsmanager.implementation.version>0.4.2-SNAPSHOT</statisticsmanager.implementation.version>
<statisticsmanager.version>0.5.1-SNAPSHOT</statisticsmanager.version>
<topology.web.version>0.4.2-SNAPSHOT</topology.web.version>
<topologymanager.version>0.4.2-SNAPSHOT</topologymanager.version>
<troubleshoot.web.version>0.4.2-SNAPSHOT</troubleshoot.web.version>
- <url.version>1.5.0</url.version>
<usermanager.implementation.version>0.4.2-SNAPSHOT</usermanager.implementation.version>
<usermanager.northbound.version>0.0.2-SNAPSHOT</usermanager.northbound.version>
<usermanager.version>0.4.2-SNAPSHOT</usermanager.version>
- <virgo.version>3.6.0.RELEASE</virgo.version>
<web.version>0.4.2-SNAPSHOT</web.version>
<xtend.dstdir>src/main/xtend-gen</xtend.dstdir>
- <xtend.version>2.4.3</xtend.version>
<yang-ext.version>2013.09.07.4-SNAPSHOT</yang-ext.version>
<yang-jmx-generator.version>1.0.0-SNAPSHOT</yang-jmx-generator.version>
<yangtools.version>0.6.2-SNAPSHOT</yangtools.version>
<dependencyManagement>
<dependencies>
-
+ <!-- project specific dependencies -->
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>ietf-netconf-monitoring</artifactId>
<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>org.osgi.core</artifactId>
<version>${osgi.core.version}</version>
</dependency>
-
- <dependency>
- <groupId>org.ow2.asm</groupId>
- <artifactId>asm-all</artifactId>
- <version>4.1</version>
- </dependency>
- <!-- Visual VM hook -->
- <dependency>
- <groupId>org.ow2.chameleon.management</groupId>
- <artifactId>chameleon-mbeans</artifactId>
- <version>1.0.0</version>
- </dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.aop</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.asm</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.beans</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.context</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.context.support</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.core</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.expression</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.transaction</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.web</artifactId>
- <version>${spring.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>org.springframework.web.servlet</artifactId>
- <version>${spring.version}</version>
- </dependency>
-
- <!-- Spring security -->
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-config</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-core</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-taglibs</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.security</groupId>
- <artifactId>spring-security-web</artifactId>
- <version>${spring-security.version}</version>
- </dependency>
- <dependency>
- <groupId>virgomirror</groupId>
- <artifactId>org.eclipse.jdt.core.compiler.batch</artifactId>
- <version>3.8.0.I20120518-2145</version>
- </dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>${mockito.version}</version>
- <scope>test</scope>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>commons.logback_settings</artifactId>
<version>${yangtools.version}</version>
<scope>test</scope>
</dependency>
- <!-- Add Pax Exam -->
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-native</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit4</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-link-mvn</artifactId>
- <version>${exam.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-aether</artifactId>
- <version>${url.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.osgi</groupId>
- <artifactId>spring-osgi-mock</artifactId>
- <version>${spring-osgi.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>xmlunit</groupId>
- <artifactId>xmlunit</artifactId>
- <version>1.5</version>
- <scope>test</scope>
- </dependency>
</dependencies>
</dependencyManagement>
<ignore></ignore>
</action>
</pluginExecution>
+ <pluginExecution>
+ <pluginExecutionFilter>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>javacc-maven-plugin</artifactId>
+ <versionRange>[0.0,)</versionRange>
+ <goals>
+ <goal>javacc</goal>
+ </goals>
+ </pluginExecutionFilter>
+ <action>
+ <execute>
+ <runOnIncremental>false</runOnIncremental>
+ </execute>
+ </action>
+ </pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</snapshots>
<id>opendaylight-mirror</id>
<name>opendaylight-mirror</name>
- <url>${nexusproxy}/groups/public/</url>
+ <url>http://nexus.opendaylight.org/content/groups/public/</url>
</repository>
<!-- OpenDayLight Snapshot artifact -->
<repository>
</snapshots>
<id>opendaylight-snapshot</id>
<name>opendaylight-snapshot</name>
- <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
+ <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
</repository>
</repositories>
</snapshots>
<id>opendaylight-mirror</id>
<name>opendaylight-mirror</name>
- <url>${nexusproxy}/groups/public/</url>
+ <url>http://nexus.opendaylight.org/content/groups/public/</url>
</pluginRepository>
<!-- OpenDayLight Snapshot artifact -->
<pluginRepository>
</snapshots>
<id>opendaylight-snapshot</id>
<name>opendaylight-snapshot</name>
- <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
+ <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
</pluginRepository>
</pluginRepositories>
<distributionManagement>
<!-- OpenDayLight Released artifact -->
<repository>
<id>opendaylight-release</id>
- <url>${nexusproxy}/repositories/${nexus.repository.release}/</url>
+ <url>http://nexus.opendaylight.org/content/repositories/opendaylight.release/</url>
</repository>
<!-- OpenDayLight Snapshot artifact -->
<snapshotRepository>
<id>opendaylight-snapshot</id>
- <url>${nexusproxy}/repositories/${nexus.repository.snapshot}/</url>
+ <url>http://nexus.opendaylight.org/content/repositories/opendaylight.snapshot/</url>
</snapshotRepository>
<!-- Site deployment -->
<site>
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
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-spi</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-inmemory-datastore</artifactId>
+ <version>1.1-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-netconf-connector</artifactId>
<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:binding:impl">prefix:runtime-generated-mapping</type>
<name>runtime-mapping-singleton</name>
</data-broker>
</module>
+
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-config-datastore-provider</type>
+ <name>config-store-service</name>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </module>
+
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-operational-datastore-provider</type>
+ <name>operational-store-service</name>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </module>
+
<!--
Tree-based in-memory data store. This is the data store which is currently
recommended for single-node deployments.
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
<name>inmemory-data-broker</name>
+
<schema-service>
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
<name>yang-schema-service</name>
</schema-service>
+
+ <config-data-store>
+ <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
+ <name>config-store-service</name>
+ </config-data-store>
+
+ <operational-data-store>
+ <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
+ <name>operational-store-service</name>
+ </operational-data-store>
</module>
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
<provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
</instance>
</service>
+ <service>
+ <type xmlns:config-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store">config-dom-store-spi:config-dom-datastore</type>
+ <instance>
+ <name>config-store-service</name>
+ <provider>/modules/module[type='inmemory-config-datastore-provider'][name='config-store-service']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
+ <instance>
+ <name>operational-store-service</name>
+ <provider>/modules/module[type='inmemory-operational-datastore-provider'][name='operational-store-service']</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>
<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: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:core:spi:config-dom-store?module=opendaylight-config-dom-datastore&revision=2014-06-17</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store?module=opendaylight-operational-dom-datastore&revision=2014-06-17</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider?module=opendaylight-inmemory-datastore-provider&revision=2014-06-17</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">
+
+ <!-- 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>
<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 {
<!-- Documentation -->
<module>sal-rest-docgen</module>
- <!-- Karaf feature -->
- <module>feature</module>
+ <!--InMemory DOM DataStore-->
+ <module>sal-inmemory-datastore</module>
+
+ <!--sal-protocolbuffer-encoding-->
+ <module>sal-protocolbuffer-encoding</module>
+
+ <!-- Karaf feature -->
+ <module>feature</module>
</modules>
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);
*/
package org.opendaylight.controller.sal.binding.api;
-import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.Notification;
public interface NotificationService extends BindingAwareService {
*
* @param notificationType
* @param listener
- * @return Registration for listener. To unregister listener invoke {@link Registration#close()} method.
+ * @return Registration for listener. To unregister listener invoke {@link ListenerRegistration#close()} method.
*/
- <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+ <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(
Class<T> notificationType, NotificationListener<T> listener);
/**
* Listener is registered for all notifications present in implemented interfaces.
*
* @param listener
- * @return Registration for listener. To unregister listener invoke {@link Registration#close()} method.
+ * @return Registration for listener. To unregister listener invoke {@link ListenerRegistration#close()} method.
*/
- Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+ ListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
org.opendaylight.yangtools.yang.binding.NotificationListener listener);
}
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());
mavenBundle(CONTROLLER, "sal-common-util").versionAsInProject(), // //
-
+ mavenBundle(CONTROLLER, "sal-inmemory-datastore").versionAsInProject(), // /
mavenBundle(CONTROLLER, "sal-broker-impl").versionAsInProject(), // //
mavenBundle(CONTROLLER, "sal-core-spi").versionAsInProject().update(), //
</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>
import org.opendaylight.controller.sal.binding.api.data.DataChangeListener;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.concepts.Registration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.Notification;
}
@Override
- public <T extends Notification> Registration<NotificationListener<T>> registerNotificationListener(
+ public <T extends Notification> ListenerRegistration<NotificationListener<T>> registerNotificationListener(
Class<T> notificationType, NotificationListener<T> listener) {
return getNotificationBrokerChecked().registerNotificationListener(notificationType, listener);
}
@Override
- public Registration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
+ public ListenerRegistration<org.opendaylight.yangtools.yang.binding.NotificationListener> registerNotificationListener(
org.opendaylight.yangtools.yang.binding.NotificationListener listener) {
return getNotificationBrokerChecked().registerNotificationListener(listener);
}
/**
*
- * 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();
/**
* {@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();
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-spi</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-inmemory-datastore</artifactId>
+ <version>1.1-SNAPSHOT</version>
+
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>util</artifactId>
org.opendaylight.controller.config.yang.md.sal.dom.statistics,
org.opendaylight.controller.md.sal.dom.broker.impl,
org.opendaylight.controller.md.sal.dom.broker.impl.*,
- org.opendaylight.controller.md.sal.dom.store.impl,
- org.opendaylight.controller.md.sal.dom.store.impl.*,
org.opendaylight.yangtools.yang.util,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*</Private-Package>
<Import-Package>*</Import-Package>
*/
package org.opendaylight.controller.config.yang.md.sal.dom.impl;
-import java.util.Hashtable;
-import java.util.concurrent.Executors;
-
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
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.broker.impl.DOMDataBrokerImpl;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
import org.osgi.framework.BundleContext;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
+import java.util.Hashtable;
+import java.util.concurrent.Executors;
/**
*
@Override
public java.lang.AutoCloseable createInstance() {
ListeningExecutorService storeExecutor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(2));
- InMemoryDOMDataStore operStore = new InMemoryDOMDataStore("DOM-OPER", storeExecutor);
- InMemoryDOMDataStore configStore = new InMemoryDOMDataStore("DOM-CFG", storeExecutor);
+ //Initializing Operational DOM DataStore defaulting to InMemoryDOMDataStore if one is not configured
+ DOMStore operStore = getOperationalDataStoreDependency();
+ if(operStore == null){
+ //we will default to InMemoryDOMDataStore creation
+ operStore = new InMemoryDOMDataStore("DOM-OPER", storeExecutor);
+ //here we will register the SchemaContext listener
+ getSchemaServiceDependency().registerSchemaServiceListener((InMemoryDOMDataStore)operStore);
+ }
+
+ DOMStore configStore = getConfigDataStoreDependency();
+ if(configStore == null){
+ //we will default to InMemoryDOMDataStore creation
+ configStore = new InMemoryDOMDataStore("DOM-CFG", storeExecutor);
+ //here we will register the SchemaContext listener
+ getSchemaServiceDependency().registerSchemaServiceListener((InMemoryDOMDataStore)configStore);
+ }
ImmutableMap<LogicalDatastoreType, DOMStore> datastores = ImmutableMap
.<LogicalDatastoreType, DOMStore> builder().put(LogicalDatastoreType.OPERATIONAL, operStore)
.put(LogicalDatastoreType.CONFIGURATION, configStore).build();
getBundleContext().registerService(DOMDataBroker.class, newDataBroker, new Hashtable<String, String>());
- getSchemaServiceDependency().registerSchemaServiceListener(operStore);
- getSchemaServiceDependency().registerSchemaServiceListener(configStore);
return newDataBroker;
}
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() {
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-/**
- * Exception thrown when a proposed change fails validation before being
- * applied into the Data Tree because the Data Tree has been modified
- * in way that a conflicting
- * node is present.
- */
-public class ConflictingModificationAppliedException extends DataValidationFailedException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- public ConflictingModificationAppliedException(final InstanceIdentifier path, final String message, final Throwable cause) {
- super(path, message, cause);
- }
-
- public ConflictingModificationAppliedException(final InstanceIdentifier path, final String message) {
- super(path, 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.md.sal.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * Interface representing a data tree which can be modified in an MVCC fashion.
- */
-public interface DataTree {
- /**
- * Take a read-only point-in-time snapshot of the tree.
- *
- * @return Data tree snapshot.
- */
- DataTreeSnapshot takeSnapshot();
-
- /**
- * Make the data tree use a new schema context. The context will be used
- * only by subsequent operations.
- *
- * @param newSchemaContext new SchemaContext
- * @throws IllegalArgumentException if the new context is incompatible
- */
- void setSchemaContext(SchemaContext newSchemaContext);
-
- /**
- * Validate whether a particular modification can be applied to the data tree.
- */
- void validate(DataTreeModification modification) throws DataValidationFailedException;
-
- /**
- * Prepare a modification for commit.
- *
- * @param modification
- * @return candidate data tree
- */
- DataTreeCandidate prepare(DataTreeModification modification);
-
- /**
- * Commit a data tree candidate.
- *
- * @param candidate data tree candidate
- */
- void commit(DataTreeCandidate candidate);
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-/**
- * An encapsulation of a validated data tree modification. This candidate
- * is ready for atomic commit to the datastore. It allows access to before-
- * and after-state as it will be seen in to subsequent commit. This capture
- * can be accessed for reference, but cannot be modified and the content
- * is limited to nodes which were affected by the modification from which
- * this instance originated.
- */
-public interface DataTreeCandidate {
- /**
- * Get the candidate tree root node.
- *
- * @return Candidate tree root node
- */
- DataTreeCandidateNode getRootNode();
-
- /**
- * Get the candidate tree root path. This is the path of the root node
- * relative to the root of InstanceIdentifier namespace.
- *
- * @return Relative path of the root node
- */
- InstanceIdentifier getRootPath();
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-import com.google.common.base.Optional;
-
-/**
- * A single node within a {@link DataTreeCandidate}. The nodes are organized
- * in tree hierarchy, reflecting the modification from which this candidate
- * was created. The node itself exposes the before- and after-image of the
- * tree restricted to the modified nodes.
- */
-public interface DataTreeCandidateNode {
- /**
- * Get the node identifier.
- *
- * @return The node identifier.
- */
- PathArgument getIdentifier();
-
- /**
- * Get an unmodifiable iterable of modified child nodes.
- *
- * @return Unmodifiable iterable of modified child nodes.
- */
- Iterable<DataTreeCandidateNode> getChildNodes();
-
- /**
- * Return the type of modification this node is undergoing.
- *
- * @return Node modification type.
- */
- ModificationType getModificationType();
-
- /**
- * Return the before-image of data corresponding to the node.
- *
- * @return Node data as they were present in the tree before
- * the modification was applied.
- */
- Optional<NormalizedNode<?, ?>> getDataAfter();
-
- /**
- * Return the after-image of data corresponding to the node.
- *
- * @return Node data as they will be present in the tree after
- * the modification is applied.
- */
- Optional<NormalizedNode<?, ?>> getDataBefore();
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-/**
- * Class encapsulation of set of modifications to a base tree. This tree is backed
- * by a read-only snapshot and tracks modifications on top of that. The modification
- * has the ability to rebase itself to a new snapshot.
- */
-public interface DataTreeModification extends DataTreeSnapshot {
- /**
- * Delete the node at specified path.
- *
- * @param path Node path
- */
- void delete(InstanceIdentifier path);
-
- /**
- * Merge the specified data with the currently-present data
- * at specified path.
- *
- * @param path Node path
- * @param data Data to be merged
- */
- void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
-
- /**
- * Replace the data at specified path with supplied data.
- *
- * @param path Node path
- * @param data New node data
- */
- void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
-
- /**
- * Finish creation of a modification, making it ready for application
- * to the data tree. Any calls to this object's methods will result
- * in undefined behavior, possibly with an
- * {@link IllegalStateException} being thrown.
- */
- void ready();
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-import com.google.common.base.Optional;
-
-/**
- * Read-only snapshot of a {@link DataTree}. The snapshot is stable and isolated,
- * e.g. data tree changes occurring after the snapshot has been taken are not
- * visible through the snapshot.
- */
-public interface DataTreeSnapshot {
- /**
- * Read a particular node from the snapshot.
- *
- * @param path Path of the node
- * @return Optional result encapsulating the presence and value of the node
- */
- Optional<NormalizedNode<?, ?>> readNode(InstanceIdentifier path);
-
- /**
- * Create a new data tree modification based on this snapshot, using the
- * specified data application strategy.
- *
- * @param strategy data modification strategy
- * @return A new data tree modification
- */
- DataTreeModification newModification();
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Exception thrown when a proposed change fails validation before being
- * applied into the datastore. This can have multiple reasons, for example
- * the datastore has been concurrently modified such that a conflicting
- * node is present, or the modification is structurally incorrect.
- */
-public class DataValidationFailedException extends Exception {
- private static final long serialVersionUID = 1L;
- private final InstanceIdentifier path;
-
- /**
- * Create a new instance.
- *
- * @param path Object path which caused this exception
- * @param message Specific message describing the failure
- */
- public DataValidationFailedException(final InstanceIdentifier path, final String message) {
- this(path, message, null);
- }
- /**
- * Create a new instance, initializing
- *
- * @param path Object path which caused this exception
- * @param message Specific message describing the failure
- * @param cause Exception which triggered this failure, may be null
- */
- public DataValidationFailedException(final InstanceIdentifier path, final String message, final Throwable cause) {
- super(message, cause);
- this.path = Preconditions.checkNotNull(path);
- }
-
- /**
- * Returns the offending object path.
- *
- * @return Path of the offending object
- */
- public InstanceIdentifier getPath() {
- return path;
- }
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-/**
- * Exception thrown when a proposed change fails validation before being
- * applied into the datastore because of incorrect structure of user supplied
- * data.
- *
- */
-public class IncorrectDataStructureException extends DataValidationFailedException {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- public IncorrectDataStructureException(final InstanceIdentifier path, final String message, final Throwable cause) {
- super(path, message, cause);
- }
-
- public IncorrectDataStructureException(final InstanceIdentifier path, final String message) {
- super(path, 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.md.sal.dom.store.impl.tree;
-
-/**
- * Enumeration of all possible node modification states. These are used in
- * data tree modification context to quickly assess what sort of modification
- * the node is undergoing.
- */
-public enum ModificationType {
- /**
- * Node is currently unmodified.
- */
- UNMODIFIED,
-
- /**
- * A child node, either direct or indirect, has been modified. This means
- * that the data representation of this node has potentially changed.
- */
- SUBTREE_MODIFIED,
-
- /**
- * This node has been placed into the tree, potentially completely replacing
- * pre-existing contents.
- */
- WRITE,
-
- /**
- * This node has been deleted along with any of its child nodes.
- */
- DELETE,
-
- /**
- * Node has been written into the tree, but instead of replacing pre-existing
- * contents, it has been merged. This means that any incoming nodes which
- * were present in the tree have been replaced, but their child nodes have
- * been retained.
- */
- MERGE,
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-
-import com.google.common.base.Optional;
-
-/**
- * A tree node which has references to its child leaves. This are typically
- * internal non-data leaves, such as containers, lists, etc.
- *
- * @param <C> Final node type
- */
-public interface StoreTreeNode<C extends StoreTreeNode<C>> {
-
- /**
- * Returns a direct child of the node
- *
- * @param child Identifier of child
- * @return Optional with node if the child is existing, {@link Optional#absent()} otherwise.
- */
- Optional<C> getChild(PathArgument child);
-}
+++ /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.dom.store.impl.tree;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-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.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-
-import com.google.common.base.Strings;
-
-/**
- * Data store tree manipulation utilities.
- */
-public final class StoreUtils {
- private static final int STRINGTREE_INDENT = 4;
-
- private StoreUtils() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- /**
- * Convert a data subtree under a node into a human-readable string format.
- *
- * @param node Data subtree root
- * @return String containing a human-readable form of the subtree.
- */
- public static String toStringTree(final NormalizedNode<?, ?> node) {
- final StringBuilder builder = new StringBuilder();
- toStringTree(builder, node, 0);
- return builder.toString();
- }
-
- private static void toStringTree(final StringBuilder builder, final NormalizedNode<?, ?> node, final int offset) {
- final String prefix = Strings.repeat(" ", offset);
-
- builder.append(prefix).append(toStringTree(node.getIdentifier()));
- if (node instanceof NormalizedNodeContainer<?, ?, ?>) {
- final NormalizedNodeContainer<?, ?, ?> container = (NormalizedNodeContainer<?, ?, ?>) node;
-
- builder.append(" {\n");
- for (NormalizedNode<?, ?> child : container.getValue()) {
- toStringTree(builder, child, offset + STRINGTREE_INDENT);
- }
-
- builder.append(prefix).append('}');
- } else {
- builder.append(' ').append(node.getValue());
- }
- builder.append('\n');
- }
-
- private static String toStringTree(final PathArgument identifier) {
- if (identifier instanceof NodeIdentifierWithPredicates) {
- StringBuilder builder = new StringBuilder();
- builder.append(identifier.getNodeType().getLocalName());
- builder.append(((NodeIdentifierWithPredicates) identifier).getKeyValues().values());
- return builder.toString();
- } else if (identifier instanceof AugmentationIdentifier) {
- return "augmentation";
- }
- return identifier.getNodeType().getLocalName();
- }
-}
+++ /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.dom.store.impl.tree;
-
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-
-/**
- * A set of utility methods for interacting with {@link org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode} objects.
- */
-public final class TreeNodeUtils {
- private TreeNodeUtils() {
- throw new UnsupportedOperationException("Utility class should not be instantiated");
- }
-
- /**
- * Finds a node in tree
- *
- * @param tree Data Tree
- * @param path Path to the node
- * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise.
- */
- public static <T extends StoreTreeNode<T>> Optional<T> findNode(final T tree, final InstanceIdentifier path) {
- Optional<T> current = Optional.<T> of(tree);
- Iterator<PathArgument> pathIter = path.getPath().iterator();
- while (current.isPresent() && pathIter.hasNext()) {
- current = current.get().getChild(pathIter.next());
- }
- return current;
- }
-
- public static <T extends StoreTreeNode<T>> T findNodeChecked(final T tree, final InstanceIdentifier path) {
- T current = tree;
- List<PathArgument> nested = new ArrayList<>(path.getPath().size());
- for(PathArgument pathArg : path.getPath()) {
- Optional<T> potential = current.getChild(pathArg);
- nested.add(pathArg);
- Preconditions.checkArgument(potential.isPresent(),"Child %s is not present in tree.",nested);
- current = potential.get();
- }
- return current;
- }
-
- /**
- * Finds a node or closest parent in the tree
- *
- * @param tree Data Tree
- * @param path Path to the node
- * @return Map.Entry Entry with key which is path to closest parent and value is parent node.
- *
- */
- public static <T extends StoreTreeNode<T>> Map.Entry<InstanceIdentifier, T> findClosest(final T tree, final InstanceIdentifier path) {
- return findClosestsOrFirstMatch(tree, path, Predicates.<T>alwaysFalse());
- }
-
- public static <T extends StoreTreeNode<T>> Map.Entry<InstanceIdentifier, T> findClosestsOrFirstMatch(final T tree, final InstanceIdentifier path, final Predicate<T> predicate) {
- Optional<T> parent = Optional.<T>of(tree);
- Optional<T> current = Optional.<T> of(tree);
-
- int nesting = 0;
- Iterator<PathArgument> pathIter = path.getPath().iterator();
- while (current.isPresent() && pathIter.hasNext() && !predicate.apply(current.get())) {
- parent = current;
- current = current.get().getChild(pathIter.next());
- nesting++;
- }
- if(current.isPresent()) {
- final InstanceIdentifier currentPath = new InstanceIdentifier(path.getPath().subList(0, nesting));
- return new SimpleEntry<InstanceIdentifier,T>(currentPath,current.get());
- }
-
- /*
- * Subtracting 1 from nesting level at this point is safe, because we
- * cannot reach here with nesting == 0: that would mean the above check
- * for current.isPresent() failed, which it cannot, as current is always
- * present. At any rate we check state just to be on the safe side.
- */
- Preconditions.checkState(nesting > 0);
- final InstanceIdentifier parentPath = new InstanceIdentifier(path.getPath().subList(0, nesting - 1));
-
- return new SimpleEntry<InstanceIdentifier,T>(parentPath,parent.get());
- }
-
- public static <T extends StoreTreeNode<T>> Optional<T> getChild(final Optional<T> parent,final PathArgument child) {
- if(parent.isPresent()) {
- return parent.get().getChild(child);
- }
- return Optional.absent();
- }
-
-}
+++ /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.dom.store.impl.tree.data;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-
-import com.google.common.base.Preconditions;
-
-abstract class AbstractDataTreeCandidate implements DataTreeCandidate {
- private final InstanceIdentifier rootPath;
-
- protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath) {
- this.rootPath = Preconditions.checkNotNull(rootPath);
- }
-
- @Override
- public final InstanceIdentifier getRootPath() {
- return rootPath;
- }
-
-}
+++ /dev/null
-package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-
-import com.google.common.base.Optional;
-
-/**
- * An implementation of apply operation which fails to do anything,
- * consistently. An instance of this class is used by the data tree
- * if it does not have a SchemaContext attached and hence cannot
- * perform anything meaningful.
- */
-final class AlwaysFailOperation implements ModificationApplyOperation {
- @Override
- public Optional<TreeNode> apply(final ModifiedNode modification,
- final Optional<TreeNode> storeMeta, final Version version) {
- throw new IllegalStateException("Schema Context is not available.");
- }
-
- @Override
- public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional<TreeNode> storeMetadata) {
- throw new IllegalStateException("Schema Context is not available.");
- }
-
- @Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument child) {
- throw new IllegalStateException("Schema Context is not available.");
- }
-
- @Override
- public void verifyStructure(final ModifiedNode modification) {
- throw new IllegalStateException("Schema Context is not available.");
- }
-}
\ 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.md.sal.dom.store.impl.tree.data;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.AugmentationSchemaProxy;
-import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-
-/**
- * Base strategy for applying changes to a ContainerNode, irrespective of its
- * actual type.
- *
- * @param <T> Type of the container node
- */
-abstract class DataNodeContainerModificationStrategy<T extends DataNodeContainer> extends NormalizedNodeContainerModificationStrategy {
-
- private final T schema;
- private final LoadingCache<PathArgument, ModificationApplyOperation> childCache = CacheBuilder.newBuilder()
- .build(CacheLoader.from(new Function<PathArgument, ModificationApplyOperation>() {
-
- @Override
- public ModificationApplyOperation apply(final PathArgument identifier) {
- if (identifier instanceof AugmentationIdentifier && schema instanceof AugmentationTarget) {
- return from(schema, (AugmentationTarget) schema, (AugmentationIdentifier) identifier);
- }
-
- DataSchemaNode child = schema.getDataChildByName(identifier.getNodeType());
- if (child == null) {
- return null;
- }
- return from(child);
- }
- }));
-
- protected DataNodeContainerModificationStrategy(final T schema,
- final Class<? extends NormalizedNode<?, ?>> nodeClass) {
- super(nodeClass);
- this.schema = schema;
- }
-
- protected T getSchema() {
- return schema;
- }
-
- @Override
- public Optional<ModificationApplyOperation> getChild(final PathArgument identifier) {
- try {
- return Optional.<ModificationApplyOperation> fromNullable(childCache.get(identifier));
- } catch (ExecutionException e) {
- return Optional.absent();
- }
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- protected abstract DataContainerNodeBuilder createBuilder(NormalizedNode<?, ?> original);
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + " [" + schema + "]";
- }
-
- public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy<AugmentationSchema> {
-
- protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) {
- super(createAugmentProxy(schema,resolved), AugmentationNode.class);
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof AugmentationNode);
- return ImmutableAugmentationNodeBuilder.create((AugmentationNode) original);
- }
-
-
- private static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) {
- Set<DataSchemaNode> realChildSchemas = new HashSet<>();
- for(DataSchemaNode augChild : schema.getChildNodes()) {
- realChildSchemas.add(resolved.getDataChildByName(augChild.getQName()));
- }
- return new AugmentationSchemaProxy(schema, realChildSchemas);
- }
- }
-
- public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy<ContainerSchemaNode> {
-
- public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) {
- super(schemaNode, ContainerNode.class);
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof ContainerNode);
- return ImmutableContainerNodeBuilder.create((ContainerNode) original);
- }
- }
-
- public static class ListEntryModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
-
- protected ListEntryModificationStrategy(final ListSchemaNode schema) {
- super(schema, MapEntryNode.class);
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- protected final DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof MapEntryNode);
- return ImmutableMapEntryNodeBuilder.create((MapEntryNode) original);
- }
- }
-
- public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy<ListSchemaNode> {
-
- public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) {
- super(schemaNode, UnkeyedListEntryNode.class);
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- protected DataContainerNodeBuilder createBuilder(final NormalizedNode<?, ?> original) {
- checkArgument(original instanceof UnkeyedListEntryNode);
- return ImmutableUnkeyedListEntryNodeBuilder.create((UnkeyedListEntryNode) original);
- }
- }
-}
\ 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.md.sal.dom.store.impl.tree.data;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataValidationFailedException;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * Read-only snapshot of the data tree.
- */
-final class InMemoryDataTree implements DataTree {
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTree.class);
- private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build();
-
- private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
- private ModificationApplyOperation applyOper = new AlwaysFailOperation();
- private SchemaContext currentSchemaContext;
- private TreeNode rootNode;
-
- public InMemoryDataTree(final TreeNode rootNode, final SchemaContext schemaContext) {
- this.rootNode = Preconditions.checkNotNull(rootNode);
-
- if (schemaContext != null) {
- // Also sets applyOper
- setSchemaContext(schemaContext);
- }
- }
-
- @Override
- public synchronized void setSchemaContext(final SchemaContext newSchemaContext) {
- Preconditions.checkNotNull(newSchemaContext);
-
- LOG.info("Attepting to install schema context {}", newSchemaContext);
-
- /*
- * FIXME: we should walk the schema contexts, both current and new and see
- * whether they are compatible here. Reject incompatible changes.
- */
-
- // Instantiate new apply operation, this still may fail
- final ModificationApplyOperation newApplyOper = SchemaAwareApplyOperation.from(newSchemaContext);
-
- // Ready to change the context now, make sure no operations are running
- rwLock.writeLock().lock();
- try {
- this.applyOper = newApplyOper;
- this.currentSchemaContext = newSchemaContext;
- } finally {
- rwLock.writeLock().unlock();
- }
- }
-
- @Override
- public InMemoryDataTreeSnapshot takeSnapshot() {
- rwLock.readLock().lock();
- try {
- return new InMemoryDataTreeSnapshot(currentSchemaContext, rootNode, applyOper);
- } finally {
- rwLock.readLock().unlock();
- }
- }
-
- @Override
- public void validate(final DataTreeModification modification) throws DataValidationFailedException {
- Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
-
- final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
- m.getStrategy().checkApplicable(PUBLIC_ROOT_PATH, m.getRootModification(), Optional.<TreeNode>of(rootNode));
- }
-
- @Override
- public synchronized DataTreeCandidate prepare(final DataTreeModification modification) {
- Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass());
-
- final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification;
- final ModifiedNode root = m.getRootModification();
-
- if (root.getType() == ModificationType.UNMODIFIED) {
- return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root);
- }
-
- rwLock.writeLock().lock();
- try {
- final Optional<TreeNode> newRoot = m.getStrategy().apply(m.getRootModification(),
- Optional.<TreeNode>of(rootNode), rootNode.getSubtreeVersion().next());
- Preconditions.checkState(newRoot.isPresent(), "Apply strategy failed to produce root node");
- return new InMemoryDataTreeCandidate(PUBLIC_ROOT_PATH, root, rootNode, newRoot.get());
- } finally {
- rwLock.writeLock().unlock();
- }
- }
-
- @Override
- public synchronized void commit(final DataTreeCandidate candidate) {
- if (candidate instanceof NoopDataTreeCandidate) {
- return;
- }
-
- Preconditions.checkArgument(candidate instanceof InMemoryDataTreeCandidate, "Invalid candidate class %s", candidate.getClass());
- final InMemoryDataTreeCandidate c = (InMemoryDataTreeCandidate)candidate;
-
- LOG.debug("Updating datastore from {} to {}", rootNode, c.getAfterRoot());
-
- if (LOG.isTraceEnabled()) {
- LOG.trace("Data Tree is {}", StoreUtils.toStringTree(c.getAfterRoot().getData()));
- }
-
- // Ready to change the context now, make sure no operations are running
- rwLock.writeLock().lock();
- try {
- Preconditions.checkState(c.getBeforeRoot() == rootNode,
- String.format("Store tree %s and candidate base %s differ.", rootNode, c.getBeforeRoot()));
- this.rootNode = c.getAfterRoot();
- } finally {
- rwLock.writeLock().unlock();
- }
- }
-}
+++ /dev/null
-package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidateNode;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
-final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate {
- private static abstract class AbstractNode implements DataTreeCandidateNode {
- private final ModifiedNode mod;
- private final TreeNode newMeta;
- private final TreeNode oldMeta;
-
- protected AbstractNode(final ModifiedNode mod,
- final TreeNode oldMeta, final TreeNode newMeta) {
- this.newMeta = newMeta;
- this.oldMeta = oldMeta;
- this.mod = Preconditions.checkNotNull(mod);
- }
-
- protected final ModifiedNode getMod() {
- return mod;
- }
-
- protected final TreeNode getNewMeta() {
- return newMeta;
- }
-
- protected final TreeNode getOldMeta() {
- return oldMeta;
- }
-
- private static final TreeNode childMeta(final TreeNode parent, final PathArgument id) {
- if (parent != null) {
- return parent.getChild(id).orNull();
- } else {
- return null;
- }
- }
-
- @Override
- public Iterable<DataTreeCandidateNode> getChildNodes() {
- return Iterables.transform(mod.getChildren(), new Function<ModifiedNode, DataTreeCandidateNode>() {
- @Override
- public DataTreeCandidateNode apply(final ModifiedNode input) {
- final PathArgument id = input.getIdentifier();
- return new ChildNode(input, childMeta(oldMeta, id), childMeta(newMeta, id));
- }
- });
- }
-
- @Override
- public ModificationType getModificationType() {
- return mod.getType();
- }
-
- private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
- if (meta != null) {
- return Optional.<NormalizedNode<?,?>>of(meta.getData());
- } else {
- return Optional.absent();
- }
- }
-
- @Override
- public Optional<NormalizedNode<?, ?>> getDataAfter() {
- return optionalData(newMeta);
- }
-
- @Override
- public Optional<NormalizedNode<?, ?>> getDataBefore() {
- return optionalData(oldMeta);
- }
- }
-
- private static final class ChildNode extends AbstractNode {
- public ChildNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
- super(mod, oldMeta, newMeta);
- }
-
- @Override
- public PathArgument getIdentifier() {
- return getMod().getIdentifier();
- }
- }
-
- private static final class RootNode extends AbstractNode {
- public RootNode(final ModifiedNode mod, final TreeNode oldMeta, final TreeNode newMeta) {
- super(mod, oldMeta, newMeta);
- }
-
- @Override
- public PathArgument getIdentifier() {
- throw new IllegalStateException("Attempted to get identifier of the root node");
- }
- }
-
- private final RootNode root;
-
- InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final ModifiedNode modificationRoot,
- final TreeNode beforeRoot, final TreeNode afterRoot) {
- super(rootPath);
- this.root = new RootNode(modificationRoot, beforeRoot, afterRoot);
- }
-
- TreeNode getAfterRoot() {
- return root.getNewMeta();
- }
-
- TreeNode getBeforeRoot() {
- return root.getOldMeta();
- }
-
- @Override
- public DataTreeCandidateNode getRootNode() {
- return root;
- }
-}
+++ /dev/null
-package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeFactory;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNodeFactory;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.Version;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-/**
- * A factory for creating in-memory data trees.
- */
-public final class InMemoryDataTreeFactory implements DataTreeFactory {
- private static final InMemoryDataTreeFactory INSTANCE = new InMemoryDataTreeFactory();
-
- private InMemoryDataTreeFactory() {
- // Never instantiated externally
- }
-
- @Override
- public InMemoryDataTree create() {
- final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME);
- final NormalizedNode<?, ?> data = Builders.containerBuilder().withNodeIdentifier(root).build();
-
- return new InMemoryDataTree(TreeNodeFactory.createTreeNode(data, Version.initial()), null);
- }
-
- /**
- * Get an instance of this factory. This method cannot fail.
- *
- * @return Data tree factory instance.
- */
- public static final InMemoryDataTreeFactory getInstance() {
- return INSTANCE;
- }
-}
+++ /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.dom.store.impl.tree.data;
-
-import java.util.Map.Entry;
-
-import javax.annotation.concurrent.GuardedBy;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-final class InMemoryDataTreeModification implements DataTreeModification {
- private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class);
- private final ModificationApplyOperation strategyTree;
- private final InMemoryDataTreeSnapshot snapshot;
- private final ModifiedNode rootNode;
-
- @GuardedBy("this")
- private boolean sealed = false;
-
- InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) {
- this.snapshot = Preconditions.checkNotNull(snapshot);
- this.strategyTree = Preconditions.checkNotNull(resolver);
- this.rootNode = ModifiedNode.createUnmodified(snapshot.getRootNode());
- }
-
- ModifiedNode getRootModification() {
- return rootNode;
- }
-
- ModificationApplyOperation getStrategy() {
- return strategyTree;
- }
-
- @Override
- public synchronized void write(final InstanceIdentifier path, final NormalizedNode<?, ?> value) {
- checkSealed();
- resolveModificationFor(path).write(value);
- }
-
- @Override
- public synchronized void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
- checkSealed();
- mergeImpl(resolveModificationFor(path),data);
- }
-
- private void mergeImpl(final OperationWithModification op,final NormalizedNode<?,?> data) {
-
- if(data instanceof NormalizedNodeContainer<?,?,?>) {
- @SuppressWarnings({ "rawtypes", "unchecked" })
- NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
- for(NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
- PathArgument childId = child.getIdentifier();
- mergeImpl(op.forChild(childId), child);
- }
- }
- op.merge(data);
- }
-
- @Override
- public synchronized void delete(final InstanceIdentifier path) {
- checkSealed();
- resolveModificationFor(path).delete();
- }
-
- @Override
- public synchronized Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
- /*
- * Walk the tree from the top, looking for the first node between root and
- * the requested path which has been modified. If no such node exists,
- * we use the node itself.
- */
- final Entry<InstanceIdentifier, ModifiedNode> entry = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, ModifiedNode.IS_TERMINAL_PREDICATE);
- final InstanceIdentifier key = entry.getKey();
- final ModifiedNode mod = entry.getValue();
-
- final Optional<TreeNode> result = resolveSnapshot(key, mod);
- if (result.isPresent()) {
- NormalizedNode<?, ?> data = result.get().getData();
- return NormalizedNodeUtils.findNode(key, data, path);
- } else {
- return Optional.absent();
- }
- }
-
- private Optional<TreeNode> resolveSnapshot(final InstanceIdentifier path,
- final ModifiedNode modification) {
- final Optional<Optional<TreeNode>> potentialSnapshot = modification.getSnapshotCache();
- if(potentialSnapshot.isPresent()) {
- return potentialSnapshot.get();
- }
-
- try {
- return resolveModificationStrategy(path).apply(modification, modification.getOriginal(),
- snapshot.getRootNode().getSubtreeVersion().next());
- } catch (Exception e) {
- LOG.error("Could not create snapshot for {}:{}", path,modification,e);
- throw e;
- }
- }
-
- private ModificationApplyOperation resolveModificationStrategy(final InstanceIdentifier path) {
- LOG.trace("Resolving modification apply strategy for {}", path);
- return TreeNodeUtils.findNodeChecked(strategyTree, path);
- }
-
- private OperationWithModification resolveModificationFor(final InstanceIdentifier path) {
- ModifiedNode modification = rootNode;
- // We ensure strategy is present.
- ModificationApplyOperation operation = resolveModificationStrategy(path);
- for (PathArgument pathArg : path.getPath()) {
- modification = modification.modifyChild(pathArg);
- }
- return OperationWithModification.from(operation, modification);
- }
-
- @Override
- public synchronized void ready() {
- Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
- sealed = true;
- rootNode.seal();
- }
-
- @GuardedBy("this")
- private void checkSealed() {
- Preconditions.checkState(!sealed, "Data Tree is sealed. No further modifications allowed.");
- }
-
- @Override
- public String toString() {
- return "MutableDataTree [modification=" + rootNode + "]";
- }
-
- @Override
- public synchronized DataTreeModification newModification() {
- Preconditions.checkState(sealed, "Attempted to chain on an unsealed modification");
-
- if(rootNode.getType() == ModificationType.UNMODIFIED) {
- return snapshot.newModification();
- }
-
- /*
- * FIXME: Add advanced transaction chaining for modification of not rebased
- * modification.
- *
- * Current computation of tempRoot may yeld incorrect subtree versions
- * if there are multiple concurrent transactions, which may break
- * versioning preconditions for modification of previously occured write,
- * directly nested under parent node, since node version is derived from
- * subtree version.
- *
- * For deeper nodes subtree version is derived from their respective metadata
- * nodes, so this incorrect root subtree version is not affecting us.
- */
- TreeNode originalSnapshotRoot = snapshot.getRootNode();
- Optional<TreeNode> tempRoot = strategyTree.apply(rootNode, Optional.of(originalSnapshotRoot), originalSnapshotRoot.getSubtreeVersion().next());
-
- InMemoryDataTreeSnapshot tempTree = new InMemoryDataTreeSnapshot(snapshot.getSchemaContext(), tempRoot.get(), strategyTree);
- return tempTree.newModification();
- }
-}
+++ /dev/null
-package org.opendaylight.controller.md.sal.dom.store.impl.tree.data;
-
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
-import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-
-final class InMemoryDataTreeSnapshot implements DataTreeSnapshot {
- private final ModificationApplyOperation applyOper;
- private final SchemaContext schemaContext;
- private final TreeNode rootNode;
-
- InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final TreeNode rootNode,
- final ModificationApplyOperation applyOper) {
- this.schemaContext = Preconditions.checkNotNull(schemaContext);
- this.rootNode = Preconditions.checkNotNull(rootNode);
- this.applyOper = Preconditions.checkNotNull(applyOper);
- }
-
- TreeNode getRootNode() {
- return rootNode;
- }
-
- SchemaContext getSchemaContext() {
- return schemaContext;
- }
-
- @Override
- public Optional<NormalizedNode<?, ?>> readNode(final InstanceIdentifier path) {
- return NormalizedNodeUtils.findNode(rootNode.getData(), path);
- }
-
- @Override
- public InMemoryDataTreeModification newModification() {
- return new InMemoryDataTreeModification(this, applyOper);