From: Ed Warnicke Date: Tue, 20 May 2014 21:55:37 +0000 (+0000) Subject: Merge "Cosmetics: check in pom.xml files as _sort_pom_ wants them to be" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~49 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=a31a4448ea6665317f4af41ae26d804829418c04;hp=9e326273260d1ff5d34da8f0c39648a94e97ac68 Merge "Cosmetics: check in pom.xml files as _sort_pom_ wants them to be" --- diff --git a/.gitignore b/.gitignore index 6fc003be27..f8cf74f826 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ classes out/ .externalToolBuilders maven-eclipse.xml +.DS_STORE +.metadata diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index b1f10ffa6e..89fd22d5a2 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -1392,6 +1392,16 @@ concepts ${yangtools.version} + + org.opendaylight.yangtools + object-cache-api + ${yangtools.version} + + + org.opendaylight.yangtools + object-cache-guava + ${yangtools.version} + org.opendaylight.yangtools restconf-client-api diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 04818e78c6..48e661f196 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -1129,6 +1129,14 @@ org.opendaylight.yangtools concepts + + org.opendaylight.yangtools + object-cache-api + + + org.opendaylight.yangtools + object-cache-guava + org.opendaylight.yangtools restconf-client-api diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend index 00ce312335..57682bc6c9 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend @@ -11,13 +11,17 @@ import java.util.Arrays import java.util.Dictionary import java.util.Hashtable import org.apache.felix.dm.Component +import org.opendaylight.controller.clustering.services.IClusterGlobalServices import org.opendaylight.controller.sal.binding.api.BindingAwareBroker import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext -import org.opendaylight.controller.sal.binding.api.BindingAwareConsumer +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext +import org.opendaylight.controller.sal.binding.api.BindingAwareProvider import org.opendaylight.controller.sal.binding.api.NotificationService import org.opendaylight.controller.sal.binding.api.data.DataBrokerService import org.opendaylight.controller.sal.binding.api.data.DataProviderService +import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter import org.opendaylight.controller.sal.compatibility.topology.TopologyAdapter +import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase import org.opendaylight.controller.sal.core.Node import org.opendaylight.controller.sal.core.NodeConnector @@ -26,6 +30,7 @@ import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerSer import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService import org.opendaylight.controller.sal.inventory.IPluginInInventoryService import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService +import org.opendaylight.controller.sal.packet.IPluginInDataPacketService import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService import org.opendaylight.controller.sal.reader.IPluginInReadService import org.opendaylight.controller.sal.reader.IPluginOutReadService @@ -34,22 +39,15 @@ import org.opendaylight.controller.sal.topology.IPluginOutTopologyService import org.opendaylight.controller.sal.utils.GlobalConstants import org.opendaylight.controller.sal.utils.INodeConnectorFactory import org.opendaylight.controller.sal.utils.INodeFactory -import org.opendaylight.controller.clustering.services.IClusterGlobalServices -import org.opendaylight.controller.sal.packet.IPluginInDataPacketService - import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.OpendaylightFlowStatisticsService import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.table.statistics.rev131215.OpendaylightFlowTableStatisticsService import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.topology.discovery.rev130819.FlowTopologyDiscoveryService +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService import org.opendaylight.yang.gen.v1.urn.opendaylight.port.statistics.rev131214.OpendaylightPortStatisticsService import org.osgi.framework.BundleContext import static org.opendaylight.controller.sal.compatibility.NodeMapping.* -import org.opendaylight.controller.sal.compatibility.topology.TopologyProvider -import org.opendaylight.controller.sal.compatibility.adsal.DataPacketServiceAdapter -import org.opendaylight.controller.sal.binding.api.BindingAwareProvider -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext class ComponentActivator extends ComponentActivatorAbstractBase { diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend index f54defdf14..8908504f15 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/InventoryAndReadAdapter.xtend @@ -10,11 +10,13 @@ package org.opendaylight.controller.sal.compatibility import java.util.ArrayList import java.util.Collections import java.util.List +import java.util.Map import java.util.Set -import java.util.ArrayList; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.locks.Lock +import java.util.concurrent.locks.ReentrantLock +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader import org.opendaylight.controller.sal.binding.api.data.DataBrokerService import org.opendaylight.controller.sal.binding.api.data.DataProviderService import org.opendaylight.controller.sal.core.Edge @@ -76,10 +78,6 @@ import org.slf4j.LoggerFactory import static extension org.opendaylight.controller.sal.common.util.Arguments.* import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import java.util.concurrent.ConcurrentHashMap -import java.util.Map -import java.util.HashMap class InventoryAndReadAdapter implements IPluginInReadService, IPluginInInventoryService, diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend index 9a19e10417..2d490564e1 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend @@ -8,9 +8,9 @@ package org.opendaylight.controller.sal.compatibility.topology import com.google.common.collect.FluentIterable -import java.util.Collections import java.util.List import java.util.concurrent.CopyOnWriteArrayList +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader import org.opendaylight.controller.sal.core.ConstructionException import org.opendaylight.controller.sal.core.Edge import org.opendaylight.controller.sal.core.Node @@ -21,13 +21,12 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology. import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier +import org.slf4j.LoggerFactory import static com.google.common.base.Preconditions.* + import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector -import org.slf4j.LoggerFactory class TopologyMapping { private static val LOG = LoggerFactory.getLogger(TopologyMapping); diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java index 63c5664a0c..81ccb35cd9 100644 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java @@ -10,8 +10,8 @@ package org.opendaylight.controller.sal.compatibility.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP; import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP; +import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP; import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP; import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP; @@ -19,17 +19,53 @@ import java.util.ArrayList; import java.util.List; import org.junit.Test; -import org.opendaylight.controller.sal.action.*; +import org.opendaylight.controller.sal.action.Action; +import org.opendaylight.controller.sal.action.Flood; +import org.opendaylight.controller.sal.action.FloodAll; +import org.opendaylight.controller.sal.action.HwPath; +import org.opendaylight.controller.sal.action.Loopback; +import org.opendaylight.controller.sal.action.PopVlan; +import org.opendaylight.controller.sal.action.PushVlan; +import org.opendaylight.controller.sal.action.SetDlDst; +import org.opendaylight.controller.sal.action.SetDlSrc; +import org.opendaylight.controller.sal.action.SetDlType; +import org.opendaylight.controller.sal.action.SetNextHop; +import org.opendaylight.controller.sal.action.SetNwDst; +import org.opendaylight.controller.sal.action.SetNwSrc; +import org.opendaylight.controller.sal.action.SetNwTos; +import org.opendaylight.controller.sal.action.SetTpDst; +import org.opendaylight.controller.sal.action.SetTpSrc; +import org.opendaylight.controller.sal.action.SetVlanCfi; +import org.opendaylight.controller.sal.action.SetVlanId; +import org.opendaylight.controller.sal.action.SetVlanPcp; +import org.opendaylight.controller.sal.action.SwPath; import org.opendaylight.controller.sal.compatibility.MDFlowMapping; import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils; import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.match.MatchType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.pop.vlan.action._case.PopVlanAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch; @@ -140,7 +176,7 @@ public class TestFromSalConversionsUtils { if (layer4Match instanceof SctpMatch) { assertEquals("Sctp source port is incorrect.", 0xffff, (int) ((SctpMatch) layer4Match) .getSctpSourcePort().getValue()); - assertEquals("Sctp dest port is incorrect.", (int) 0xfffe, (int) ((SctpMatch) layer4Match) + assertEquals("Sctp dest port is incorrect.", 0xfffe, (int) ((SctpMatch) layer4Match) .getSctpDestinationPort().getValue()); sctpFound = true; } @@ -151,9 +187,9 @@ public class TestFromSalConversionsUtils { assertEquals("Wrong protocol", TCP, match.getIpMatch().getIpProtocol().byteValue()); layer4Match = match.getLayer4Match(); if (layer4Match instanceof TcpMatch) { - assertEquals("Tcp source port is incorrect.", (int) 0xabcd, (int) ((TcpMatch) layer4Match) + assertEquals("Tcp source port is incorrect.", 0xabcd, (int) ((TcpMatch) layer4Match) .getTcpSourcePort().getValue()); - assertEquals("Tcp dest port is incorrect.", (int) 0xdcba, (int) ((TcpMatch) layer4Match) + assertEquals("Tcp dest port is incorrect.", 0xdcba, (int) ((TcpMatch) layer4Match) .getTcpDestinationPort().getValue()); sctpFound = true; } @@ -164,9 +200,9 @@ public class TestFromSalConversionsUtils { assertEquals("Wrong protocol", UDP, match.getIpMatch().getIpProtocol().byteValue()); layer4Match = match.getLayer4Match(); if (layer4Match instanceof UdpMatch) { - assertEquals("Udp source port is incorrect.", (int) 0xcdef, (int) ((UdpMatch) layer4Match) + assertEquals("Udp source port is incorrect.", 0xcdef, (int) ((UdpMatch) layer4Match) .getUdpSourcePort().getValue()); - assertEquals("Udp dest port is incorrect.", (int) 0xfedc, (int) ((UdpMatch) layer4Match) + assertEquals("Udp dest port is incorrect.", 0xfedc, (int) ((UdpMatch) layer4Match) .getUdpDestinationPort().getValue()); sctpFound = true; } @@ -227,13 +263,13 @@ public class TestFromSalConversionsUtils { assertEquals("Wrong value of vlad ID in PushVlanAction.", (Integer) 4095, ((PushVlanActionCase) innerAction).getPushVlanAction().getVlanId().getValue()); } else if (innerAction instanceof SetDlDstActionCase) { - assertEquals("Wrong MAC destination address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", + assertEquals("Wrong MAC destination address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", ((SetDlDstActionCase) innerAction).getSetDlDstAction().getAddress().getValue()); } else if (innerAction instanceof SetDlSrcActionCase) { - assertEquals("Wrong MAC source address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", + assertEquals("Wrong MAC source address in SetDlDstAction.", "ff:ee:dd:cc:bb:aa", ((SetDlSrcActionCase) innerAction).getSetDlSrcAction().getAddress().getValue()); } else if (innerAction instanceof SetDlTypeActionCase) { - assertEquals("Wrong data link type in SetDlTypeAction.", (long) 513, + assertEquals("Wrong data link type in SetDlTypeAction.", 513, (long) ((SetDlTypeActionCase) innerAction).getSetDlTypeAction().getDlType().getValue()); } else if (innerAction instanceof SetNextHopActionCase) { Address address = ((SetNextHopActionCase) innerAction).getSetNextHopAction().getAddress(); diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java index 3f9d5c7854..f1be5c6922 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingToNormalizedNodeCodec.java @@ -13,18 +13,17 @@ import java.util.AbstractMap.SimpleEntry; import java.util.LinkedList; import java.util.List; import java.util.Map.Entry; -import java.util.concurrent.Callable; 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.yangtools.concepts.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; @@ -44,6 +43,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; +import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -364,9 +364,9 @@ public class BindingToNormalizedNodeCodec implements SchemaContextListener { } else if (List.class.isAssignableFrom(returnType)) { try { return ClassLoaderUtils.withClassLoader(method.getDeclaringClass().getClassLoader(), - new Callable() { + new Supplier() { @Override - public Class call() { + public Class get() { Type listResult = ClassLoaderUtils.getFirstGenericParameter(method .getGenericReturnType()); if (listResult instanceof Class diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java index ddc79ae075..e08e9a4e05 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBackwardsCompatibleDataBroker.java @@ -443,9 +443,6 @@ public class ForwardedBackwardsCompatibleDataBroker extends AbstractForwardedDat } private static class BackwardsCompatibleConfigurationDataChangeInvoker implements BindingDataChangeListener, Delegator { - - - @SuppressWarnings("rawtypes") private final org.opendaylight.controller.md.sal.common.api.data.DataChangeListener delegate; public BackwardsCompatibleConfigurationDataChangeInvoker(final DataChangeListener listener) { diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java index b27c80d784..5bbebe6f1b 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingIndependentConnector.java @@ -62,7 +62,6 @@ import org.opendaylight.controller.sal.core.api.notify.NotificationListener; import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.concepts.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.BaseIdentity; @@ -73,12 +72,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.Notification; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -import org.opendaylight.yangtools.yang.data.api.Node; -import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; import org.opendaylight.yangtools.yang.data.impl.codec.DeserializationException; import org.slf4j.Logger; @@ -87,7 +85,6 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.Futures; @@ -736,224 +733,13 @@ public class BindingIndependentConnector implements // } } checkState(targetMethod != null, "Rpc method not found"); - Optional> outputClass = BindingReflections.resolveRpcOutputClass(targetMethod); - Optional> inputClass = BindingReflections - .resolveRpcInputClass(targetMethod); - - RpcInvocationStrategy strategy = null; - if (outputClass.isPresent()) { - if (inputClass.isPresent()) { - strategy = new DefaultInvocationStrategy(rpc, targetMethod, outputClass.get(), inputClass - .get()); - } else { - strategy = new NoInputInvocationStrategy(rpc, targetMethod, outputClass.get()); - } - } else if (inputClass.isPresent()) { - strategy = new NoOutputInvocationStrategy(rpc, targetMethod, inputClass.get()); - } else { - strategy = new NoInputNoOutputInvocationStrategy(rpc, targetMethod); - } - return strategy; + return new RpcInvocationStrategy(rpc,targetMethod, mappingService, biRpcRegistry); } }); } } - private abstract class RpcInvocationStrategy { - - protected final Method targetMethod; - protected final QName rpc; - - public RpcInvocationStrategy(final QName rpc, final Method targetMethod) { - this.targetMethod = targetMethod; - this.rpc = rpc; - } - - public abstract Future> forwardToDomBroker(DataObject input); - - public abstract RpcResult uncheckedInvoke(RpcService rpcService, CompositeNode domInput) - throws Exception; - - public RpcResult invokeOn(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - return uncheckedInvoke(rpcService, domInput); - } - } - - private class DefaultInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings("rawtypes") - private final WeakReference outputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public DefaultInvocationStrategy(final QName rpc, final Method targetMethod, final Class outputClass, - final Class inputClass) { - super(rpc, targetMethod); - this.outputClass = new WeakReference(outputClass); - this.inputClass = new WeakReference(inputClass); - } - - @SuppressWarnings("unchecked") - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (futureResult == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = futureResult.get(); - final Object resultObj = bindingResult.getResult(); - if (resultObj instanceof DataObject) { - final CompositeNode output = mappingService.toDataDom((DataObject) resultObj); - return Rpcs.getRpcResult(true, output, Collections. emptySet()); - } - return Rpcs.getRpcResult(true); - } - - @Override - public ListenableFuture> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry == null) { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - Object baResultValue = null; - if (input.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), - input.getResult()); - } - return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors()); - } - }); - } - } - - private class NoInputInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference outputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public NoInputInvocationStrategy(final QName rpc, final Method targetMethod, final Class outputClass) { - super(rpc, targetMethod); - this.outputClass = new WeakReference(outputClass); - } - - @SuppressWarnings("unchecked") - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - Future> futureResult = (Future>) targetMethod.invoke(rpcService); - if (futureResult == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = futureResult.get(); - final Object resultObj = bindingResult.getResult(); - if (resultObj instanceof DataObject) { - final CompositeNode output = mappingService.toDataDom((DataObject) resultObj); - return Rpcs.getRpcResult(true, output, Collections. emptySet()); - } - return Rpcs.getRpcResult(true); - } - - @Override - public Future> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry != null) { - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - Object baResultValue = null; - if (input.getResult() != null) { - baResultValue = mappingService.dataObjectFromDataDom(outputClass.get(), - input.getResult()); - } - return Rpcs.getRpcResult(input.isSuccessful(), baResultValue, input.getErrors()); - } - }); - } else { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - } - } - - private class NoInputNoOutputInvocationStrategy extends RpcInvocationStrategy { - - public NoInputNoOutputInvocationStrategy(final QName rpc, final Method targetMethod) { - super(rpc, targetMethod); - } - - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - @SuppressWarnings("unchecked") - Future> result = (Future>) targetMethod.invoke(rpcService); - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(bindingResult.isSuccessful(), bindingResult.getErrors()); - } - - @Override - public Future> forwardToDomBroker(final DataObject input) { - return Futures.immediateFuture(null); - } - } - - private class NoOutputInvocationStrategy extends RpcInvocationStrategy { - - @SuppressWarnings("rawtypes") - private final WeakReference inputClass; - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public NoOutputInvocationStrategy(final QName rpc, final Method targetMethod, - final Class inputClass) { - super(rpc, targetMethod); - this.inputClass = new WeakReference(inputClass); - } - - @Override - public RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) - throws Exception { - DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); - Future> result = (Future>) targetMethod.invoke(rpcService, bindingInput); - if (result == null) { - return Rpcs.getRpcResult(false); - } - RpcResult bindingResult = result.get(); - return Rpcs.getRpcResult(true); - } - - @Override - public ListenableFuture> forwardToDomBroker(final DataObject input) { - if (biRpcRegistry == null) { - return Futures.> immediateFuture(Rpcs.getRpcResult(false)); - } - - CompositeNode xml = mappingService.toDataDom(input); - CompositeNode wrappedXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); - - return Futures.transform(biRpcRegistry.invokeRpc(rpc, wrappedXml), - new Function, RpcResult>() { - @Override - public RpcResult apply(final RpcResult input) { - return Rpcs. getRpcResult(input.isSuccessful(), null, input.getErrors()); - } - }); - } - } - public boolean isRpcForwarding() { return rpcForwarding; } diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java new file mode 100644 index 0000000000..d08b217e71 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategy.java @@ -0,0 +1,164 @@ +/* + ** Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved. + ** + ** This program and the accompanying materials are made available under the + ** terms of the Eclipse Public License v1.0 which accompanies this distribution, + ** and is available at http://www.eclipse.org/legal/epl-v10.html + **/ + +package org.opendaylight.controller.sal.binding.impl.connect.dom; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.Future; + +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode; +import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +/* + * RPC's can have both input, output, one or the other, or neither. + * + * This class handles the permutations and provides two means of invocation: + * 1. forwardToDomBroker + * 2. + * + * Weak References to the input and output classes are used to allow these classes to + * be from another OSGi bundle/class loader which may come and go. + * + */ +public class RpcInvocationStrategy { + + private final BindingIndependentMappingService mappingService; + private final RpcProvisionRegistry biRpcRegistry; + protected final Method targetMethod; + protected final QName rpc; + + @SuppressWarnings("rawtypes") + private final WeakReference inputClass; + + @SuppressWarnings("rawtypes") + private final WeakReference outputClass; + + @SuppressWarnings({ "rawtypes" }) + public RpcInvocationStrategy(final QName rpc, + final Method targetMethod, + final BindingIndependentMappingService mappingService, + final RpcProvisionRegistry biRpcRegistry ) { + + this.targetMethod = targetMethod; + this.rpc = rpc; + + Optional> outputClassOption = BindingReflections.resolveRpcOutputClass(targetMethod); + Optional> inputClassOption = BindingReflections.resolveRpcInputClass(targetMethod); + + if ( outputClassOption != null && outputClassOption.isPresent() ) { + this.outputClass = new WeakReference(outputClassOption.get() ) ; + } else { + this.outputClass = null ; + } + if ( inputClassOption != null && inputClassOption.isPresent() ) { + this.inputClass = new WeakReference(inputClassOption.get() ) ; + } else { + this.inputClass = null ; + } + + this.mappingService = mappingService; + this.biRpcRegistry = biRpcRegistry; + } + + @SuppressWarnings({ "unchecked" }) + public ListenableFuture> forwardToDomBroker(final DataObject input) { + + if(biRpcRegistry == null) { + return Futures.> immediateFuture(Rpcs.getRpcResult(false)); + } + + CompositeNode inputXml = null; + if( input != null ) { + CompositeNode xml = mappingService.toDataDom(input); + inputXml = ImmutableCompositeNode.create(rpc, ImmutableList.> of(xml)); + } else { + inputXml = ImmutableCompositeNode.create( rpc, Collections.>emptyList() ); + } + + Function, RpcResult> transformationFunction = + new Function, RpcResult>() { + @Override + public RpcResult apply(RpcResult result) { + + Object output = null; + + if( getOutputClass() != null ) { + if (result.getResult() != null) { + output = mappingService.dataObjectFromDataDom(getOutputClass().get(), + result.getResult()); + } + } + + return Rpcs.getRpcResult(result.isSuccessful(), output, result.getErrors()); + } + }; + + return Futures.transform(biRpcRegistry.invokeRpc(rpc, inputXml), transformationFunction); + } + + @SuppressWarnings("unchecked") + private RpcResult uncheckedInvoke(final RpcService rpcService, final CompositeNode domInput) throws Exception { + + Future> futureResult = null; + + if( inputClass != null ){ + DataContainer bindingInput = mappingService.dataObjectFromDataDom(inputClass.get(), domInput); + futureResult = (Future>) targetMethod.invoke(rpcService, bindingInput); + + } else { + futureResult = (Future>) targetMethod.invoke(rpcService); + } + + if (futureResult == null) { + return Rpcs.getRpcResult(false); + } + + RpcResult bindingResult = futureResult.get(); + + Collection errors = bindingResult.getErrors(); + if( errors == null ) { + errors = Collections.emptySet(); + } + + final Object resultObj = bindingResult.getResult(); + CompositeNode output = null; + if (resultObj instanceof DataObject) { + output = mappingService.toDataDom((DataObject)resultObj); + } + return Rpcs.getRpcResult( bindingResult.isSuccessful(), output, errors); + } + + public RpcResult invokeOn(final RpcService rpcService, final CompositeNode domInput) throws Exception { + return uncheckedInvoke(rpcService, domInput); + } + + @SuppressWarnings("rawtypes") + public WeakReference getOutputClass() { + return outputClass; + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java new file mode 100644 index 0000000000..c5aea8f2ab --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RpcInvocationStrategyTest.java @@ -0,0 +1,267 @@ +/* +* Copyright (c) 2014 Brocade Communications Systems, Inc. and others. All rights reserved. +* +* This program and the accompanying materials are made available under the +* terms of the Eclipse Public License v1.0 which accompanies this distribution, +* and is available at http://www.eclipse.org/legal/epl-v10.html +*/ +package org.opendaylight.controller.sal.binding.impl.connect.dom; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.RpcService; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService; + +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +public class RpcInvocationStrategyTest { + + @Mock + private BindingIndependentMappingService mockMappingService; + @Mock + private RpcProvisionRegistry mockbiRpcRegistry; + + private RpcInvocationStrategy rpcInvocationStrategy; + private ListenableFuture> futureDataObj; + private ListenableFuture> futureCompNode; + private final RpcError rpcError = mock(RpcError.class); + private final Collection errors = new ArrayList(); + + private final CompositeNode inputInvokeOn = mock(CompositeNode.class); + private final CompositeNode outputInvokeOn = mock(CompositeNode.class); + + private final DataObject toDataDomInput = mock(DataObject.class); + private final CompositeNode toDataDomReturn = mock(CompositeNode.class); + private final CompositeNode invokeRpcResult = mock(CompositeNode.class); + + private final DataObject inputForward = mock(DataObject.class); + private final DataObject outputForward = mock(DataObject.class); + + private QName mockQName; + private URI urn; + + private final MockRpcService mockRpcService = new MockRpcService(); + + public class MockRpcService implements RpcService { + + public Future rpcnameWithInputNoOutput(DataObject input) { + return futureDataObj; + } + + public Future> rpcnameWithInputWithOutput(DataObject input) { + return futureDataObj; + } + + public Future> rpcnameNoInputWithOutput() { + return futureDataObj; + } + + public Future rpcnameNoInputNoOutput() { + return futureDataObj; + } + } + + public RpcInvocationStrategyTest() { + MockitoAnnotations.initMocks(this); + } + + @Before + public void testInit() throws Exception { + urn = new URI(new String("urn:a:valid:urn")); + } + + private void setupForForwardToDom(boolean hasOutput, boolean hasInput, int expectedErrorSize) { + + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult result = Rpcs.getRpcResult(true, invokeRpcResult, errors); + futureCompNode = Futures.immediateFuture(result); + if( hasInput ) + { + when(mockMappingService.toDataDom(inputForward)).thenReturn(toDataDomReturn); + } + when(mockbiRpcRegistry.invokeRpc(eq(mockQName), any(CompositeNode.class))).thenReturn( + futureCompNode); + if (hasOutput) { + when( + mockMappingService.dataObjectFromDataDom(eq(rpcInvocationStrategy + .getOutputClass().get()), any(CompositeNode.class))).thenReturn( + outputForward); + } + + } + + private void validateForwardToDomBroker(ListenableFuture> forwardToDomBroker, + boolean expectedSuccess, DataObject expectedResult, int expectedErrorSize) + throws InterruptedException, ExecutionException { + assertNotNull(forwardToDomBroker); + assertEquals(expectedSuccess, forwardToDomBroker.get().isSuccessful()); + assertEquals(expectedResult, forwardToDomBroker.get().getResult()); + assertEquals(expectedErrorSize, forwardToDomBroker.get().getErrors().size()); + } + + private void setupTestMethod(String rpcName, String testMethodName, boolean hasInput) + throws NoSuchMethodException { + mockQName = new QName(urn, new Date(0L), new String("prefix"), new String(rpcName)); + java.lang.reflect.Method rpcMethod = hasInput ? MockRpcService.class.getMethod(rpcName, + DataObject.class) : MockRpcService.class.getMethod(rpcName); + rpcInvocationStrategy = new RpcInvocationStrategy(mockQName, rpcMethod, mockMappingService, + mockbiRpcRegistry); + } + + /* + * forwardToDomBroker tests + */ + @Test + public void testForwardToDomBroker_WithInputNoOutput() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", "testForwardToDomBroker_WithInputNoOutput", + true); + setupForForwardToDom(false, true, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + + validateForwardToDomBroker(forwardToDomBroker, true, null, 0); + } + + @Test + public void testForwardToDomBroker_WithInputNoOutput_error() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", + "testForwardToDomBroker_WithInputNoOutput_error", true); + setupForForwardToDom(false, true, 1); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + + validateForwardToDomBroker(forwardToDomBroker, true, null, 1); + } + + @Test + public void testForwardToDomBroker_WithInputWithOutput() throws Exception { + setupTestMethod("rpcnameWithInputWithOutput", "testForwardToDomBroker_WithInputWithOutput", + true); + setupForForwardToDom(true, true, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(inputForward); + validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0); + } + + @Test + public void testForwardToDomBroker_NoInputWithOutput() throws Exception { + setupTestMethod("rpcnameNoInputWithOutput", "testForwardToDomBroker_NoInputWithOutput", + false); + setupForForwardToDom(true, false, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(null); + validateForwardToDomBroker(forwardToDomBroker, true, outputForward, 0); + } + + @Test + public void testForwardToDomBroker_NoInputNoOutput() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testForwardToDomBroker_NoInputNoOutput", false); + setupForForwardToDom(false, false, 0); + ListenableFuture> forwardToDomBroker = rpcInvocationStrategy + .forwardToDomBroker(null); + validateForwardToDomBroker(forwardToDomBroker, true, null, 0); + } + + /* + * invokeOn Tests + */ + private void setupRpcResultsWithOutput(int expectedErrorSize) { + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors); + futureCompNode = Futures.immediateFuture(resultCompNode); + RpcResult resultDataObj = Rpcs.getRpcResult(true, toDataDomInput, errors); + futureDataObj = Futures.immediateFuture(resultDataObj); + + when(mockMappingService.toDataDom(toDataDomInput)).thenReturn(outputInvokeOn); + } + + private void setupRpcResultsNoOutput(int expectedErrorSize) { + if (expectedErrorSize > 0) + errors.add(rpcError); + RpcResult resultCompNode = Rpcs.getRpcResult(true, inputInvokeOn, errors); + futureCompNode = Futures.immediateFuture(resultCompNode); + RpcResult resultDataObj = Rpcs.getRpcResult(true, null, errors); + futureDataObj = Futures.immediateFuture(resultDataObj); + } + + private void validateReturnedImmediateFuture( + ListenableFuture> immediateFuture, boolean expectedSuccess, + CompositeNode expectedReturn, int expectedErrorSize) throws InterruptedException, + ExecutionException { + assertNotNull(immediateFuture); + assertEquals(expectedSuccess, immediateFuture.get().isSuccessful()); + assertEquals(expectedReturn, immediateFuture.get().getResult()); + assertEquals(expectedErrorSize, immediateFuture.get().getErrors().size()); + } + + @Test + public void testInvokeOn_NoInputNoOutput() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false); + setupRpcResultsNoOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 0); + } + + @Test + public void testInvokeOn_NoInputNoOutput_errors() throws Exception { + setupTestMethod("rpcnameNoInputNoOutput", "testInvokeOn_NoInputNoOutput", false); + setupRpcResultsNoOutput(1); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 1); + } + + @Test + public void testInvokeOn_WithInputNoOutput() throws Exception { + setupTestMethod("rpcnameWithInputNoOutput", "testInvokeOn_WithInputNoOutput", true); + setupRpcResultsNoOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, null, 0); + } + + @Test + public void testInvokeOn_WithInputWithOutput() throws Exception { + setupTestMethod("rpcnameWithInputWithOutput", "testInvokeOn_WithInputWithOutput", true); + setupRpcResultsWithOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0); + } + + @Test + public void testInvokeOn_NoInputWithOutput() throws Exception { + setupTestMethod("rpcnameNoInputWithOutput", "testInvokeOn_NoInputWithOutput", false); + setupRpcResultsWithOutput(0); + ListenableFuture> immediateFuture = Futures + .immediateFuture(rpcInvocationStrategy.invokeOn(mockRpcService, inputInvokeOn)); + validateReturnedImmediateFuture(immediateFuture, true, outputInvokeOn, 0); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java similarity index 98% rename from opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java rename to opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java index 6b2568aba7..02870c4ef7 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPuts.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/bugfix/MultipleAugmentationPutsTest.java @@ -48,7 +48,7 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; -public class MultipleAugmentationPuts extends AbstractDataServiceTest implements DataChangeListener { +public class MultipleAugmentationPutsTest extends AbstractDataServiceTest implements DataChangeListener { private static final QName NODE_ID_QNAME = QName.create(Node.QNAME, "id"); private static final String NODE_ID = "openflow:1"; @@ -76,7 +76,7 @@ public class MultipleAugmentationPuts extends AbstractDataServiceTest implements * * @throws Exception */ - @Test + @Test( timeout = 15000) public void testAugmentSerialization() throws Exception { baDataService.registerDataChangeListener(NODES_INSTANCE_ID_BA, this); diff --git a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java index f869254dcf..a7c6b0c66f 100644 --- a/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java +++ b/opendaylight/md-sal/sal-common-impl/src/main/java/org/opendaylight/controller/md/sal/common/impl/util/compat/DataNormalizationOperation.java @@ -285,7 +285,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { ImmutableMap.Builder keys = ImmutableMap.builder(); for (QName key : keyDefinition) { @@ -325,7 +325,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.unkeyedListEntryBuilder().withNodeIdentifier(getIdentifier()); } @@ -343,7 +343,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.containerBuilder().withNodeIdentifier(getIdentifier()); } @@ -377,7 +377,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.orderedLeafSetBuilder().withNodeIdentifier(getIdentifier()); } @@ -397,7 +397,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier()); } @@ -602,7 +602,7 @@ public abstract class DataNormalizationOperation impleme } @Override - protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { + protected NormalizedNodeContainerBuilder createBuilder(final CompositeNode compositeNode) { return Builders.choiceBuilder().withNodeIdentifier(getIdentifier()); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java index b2217a6f0a..5b34fba69a 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleDataBroker.java @@ -1,36 +1,28 @@ package org.opendaylight.controller.md.sal.dom.broker.impl.compat; import org.opendaylight.controller.md.sal.common.api.RegistrationListener; -import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; -import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandlerRegistration; import org.opendaylight.controller.md.sal.common.api.data.DataReader; import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; -import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener; import org.opendaylight.controller.sal.common.DataStoreIdentifier; import org.opendaylight.controller.sal.core.api.data.DataChangeListener; import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction; import org.opendaylight.controller.sal.core.api.data.DataProviderService; import org.opendaylight.controller.sal.core.api.data.DataValidator; import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; -import org.opendaylight.yangtools.concepts.Delegator; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.Registration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; public class BackwardsCompatibleDataBroker implements DataProviderService, SchemaContextListener { - DOMDataBroker backingBroker; - DataNormalizer normalizer; - private final ListenerRegistry fakeRegistry = ListenerRegistry.create(); - + private final DOMDataBroker backingBroker; + private DataNormalizer normalizer; public BackwardsCompatibleDataBroker(final DOMDataBroker newBiDataImpl) { backingBroker = newBiDataImpl; @@ -43,7 +35,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem @Override public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) { - BackwardsCompatibleTransaction tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer); + final BackwardsCompatibleTransaction tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer); try { return tx.readConfigurationData(legacyPath); } finally { @@ -53,7 +45,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem @Override public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) { - BackwardsCompatibleTransaction tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer); + final BackwardsCompatibleTransaction tx = BackwardsCompatibleTransaction.readOnlyTransaction(backingBroker.newReadOnlyTransaction(),normalizer); try { return tx.readOperationalData(legacyPath); } finally { @@ -67,9 +59,19 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem } @Override - public ListenerRegistration registerDataChangeListener(final InstanceIdentifier path, + public ListenerRegistration registerDataChangeListener(final InstanceIdentifier legacyPath, final DataChangeListener listener) { - return fakeRegistry .register(listener); + final InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath); + + final TranslatingListenerInvoker translatingCfgListener = + TranslatingListenerInvoker.createConfig(listener, normalizer); + translatingCfgListener.register(backingBroker, normalizedPath); + + final TranslatingListenerInvoker translatingOpListener = + TranslatingListenerInvoker.createOperational(listener, normalizer); + translatingOpListener.register(backingBroker, normalizedPath); + + return new DelegateListenerRegistration(translatingCfgListener, translatingOpListener, listener); } @Override @@ -90,7 +92,7 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem return null; } - // Obsolote functionality + // Obsolete functionality @Override public void addValidator(final DataStoreIdentifier store, final DataValidator validator) { @@ -124,25 +126,26 @@ public class BackwardsCompatibleDataBroker implements DataProviderService, Schem throw new UnsupportedOperationException("Data Reader contract is not supported."); } - private final class TranslatingListenerInvoker implements DOMDataChangeListener, Delegator { - + private static class DelegateListenerRegistration implements ListenerRegistration { + private final TranslatingListenerInvoker translatingCfgListener; + private final TranslatingListenerInvoker translatingOpListener; + private final DataChangeListener listener; - private DataChangeListener delegate; + public DelegateListenerRegistration(final TranslatingListenerInvoker translatingCfgListener, final TranslatingListenerInvoker translatingOpListener, final DataChangeListener listener) { + this.translatingCfgListener = translatingCfgListener; + this.translatingOpListener = translatingOpListener; + this.listener = listener; + } @Override - public void onDataChanged(final AsyncDataChangeEvent> normalizedChange) { - - DataChangeEvent legacyChange = null; - delegate.onDataChanged(legacyChange); + public void close() { + translatingCfgListener.close(); + translatingOpListener.close(); } @Override - public DataChangeListener getDelegate() { - - return delegate; + public DataChangeListener getInstance() { + return listener; } - - } - } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java new file mode 100644 index 0000000000..827e4ca63d --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingDataChangeEvent.java @@ -0,0 +1,233 @@ +/* + * 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.broker.impl.compat; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException; +import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +import com.google.common.collect.Maps; + +public abstract class TranslatingDataChangeEvent implements + DataChangeEvent { + + private TranslatingDataChangeEvent() { + } + + public static DataChangeEvent createOperational( + final AsyncDataChangeEvent> change, final DataNormalizer normalizer) { + return new OperationalChangeEvent(change, normalizer); + } + + public static DataChangeEvent createConfiguration( + final AsyncDataChangeEvent> change, final DataNormalizer normalizer) { + return new ConfigurationChangeEvent(change, normalizer); + } + + @Override + public Map getCreatedOperationalData() { + return Collections.emptyMap(); + } + + @Override + public Map getCreatedConfigurationData() { + return Collections.emptyMap(); + } + + @Override + public Map getUpdatedOperationalData() { + return Collections.emptyMap(); + } + + @Override + public Map getUpdatedConfigurationData() { + return Collections.emptyMap(); + } + + @Override + public Set getRemovedConfigurationData() { + return Collections.emptySet(); + } + + @Override + public Set getRemovedOperationalData() { + return Collections.emptySet(); + } + + @Override + public Map getOriginalConfigurationData() { + return Collections.emptyMap(); + } + + @Override + public Map getOriginalOperationalData() { + return Collections.emptyMap(); + } + + @Override + public CompositeNode getOriginalConfigurationSubtree() { + return null; + } + + @Override + public CompositeNode getOriginalOperationalSubtree() { + return null; + } + + @Override + public CompositeNode getUpdatedConfigurationSubtree() { + return null; + } + + @Override + public CompositeNode getUpdatedOperationalSubtree() { + return null; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private final static class OperationalChangeEvent extends TranslatingDataChangeEvent { + + private final AsyncDataChangeEvent> delegate; + private final DataNormalizer normalizer; + private Map updatedCache; + + public OperationalChangeEvent(final AsyncDataChangeEvent> change, + final DataNormalizer normalizer) { + this.delegate = change; + this.normalizer = normalizer; + } + + @Override + public Map getCreatedOperationalData() { + return transformToLegacy(normalizer, delegate.getCreatedData()); + } + + + @Override + public Set getRemovedOperationalData() { + return delegate.getRemovedPaths(); + } + + @Override + public CompositeNode getOriginalOperationalSubtree() { + // first argument is unused + return normalizer.toLegacy(null, delegate.getOriginalSubtree()); + } + + @Override + public CompositeNode getUpdatedOperationalSubtree() { + // first argument is unused + return normalizer.toLegacy(null, delegate.getUpdatedSubtree()); + } + + @Override + public Map getOriginalOperationalData() { + return transformToLegacy(normalizer, delegate.getOriginalData()); + } + + @Override + public Map getUpdatedOperationalData() { + if(updatedCache == null) { + final Map updated = transformToLegacy(normalizer, delegate.getUpdatedData()); + final Map created = getCreatedConfigurationData(); + final HashMap updatedComposite = new HashMap<>(created.size() + updated.size()); + updatedComposite.putAll(created); + updatedComposite.putAll(updated); + updatedCache = Collections.unmodifiableMap(updatedComposite); + } + return updatedCache; + } + + @Override + public String toString() { + return "OperationalChangeEvent [delegate=" + delegate + "]"; + } + + } + + private static Map transformToLegacy(final DataNormalizer normalizer, final Map> nodes) { + final Map legacy = Maps.newHashMap(); + + for (final Map.Entry> entry : nodes.entrySet()) { + try { + legacy.put(normalizer.toLegacy(entry.getKey()), normalizer.toLegacy(entry.getKey(), entry.getValue())); + } catch (final DataNormalizationException e) { + throw new IllegalStateException("Unable to transform data change event to legacy format", e); + } + } + return legacy; + } + + private final static class ConfigurationChangeEvent extends TranslatingDataChangeEvent { + + private final AsyncDataChangeEvent> delegate; + private final DataNormalizer normalizer; + private Map updatedCache; + + public ConfigurationChangeEvent(final AsyncDataChangeEvent> change, + final DataNormalizer normalizer) { + this.delegate = change; + this.normalizer = normalizer; + } + + @Override + public Map getCreatedConfigurationData() { + return transformToLegacy(normalizer, delegate.getCreatedData()); + } + + + @Override + public Set getRemovedConfigurationData() { + return delegate.getRemovedPaths(); + } + + @Override + public CompositeNode getOriginalConfigurationSubtree() { + // first argument is unused + return normalizer.toLegacy(null, delegate.getOriginalSubtree()); + } + + @Override + public CompositeNode getUpdatedConfigurationSubtree() { + // first argument is unused + return normalizer.toLegacy(null, delegate.getUpdatedSubtree()); + } + + @Override + public Map getOriginalConfigurationData() { + return transformToLegacy(normalizer, delegate.getOriginalData()); + } + + @Override + public Map getUpdatedConfigurationData() { + if(updatedCache == null) { + final Map updated = transformToLegacy(normalizer, delegate.getUpdatedData()); + final Map created = getCreatedConfigurationData(); + final HashMap updatedComposite = new HashMap<>(created.size() + updated.size()); + updatedComposite.putAll(created); + updatedComposite.putAll(updated); + updatedCache = Collections.unmodifiableMap(updatedComposite); + } + return updatedCache; + } + + @Override + public String toString() { + return "ConfigurationChangeEvent [delegate=" + delegate + "]"; + } + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java new file mode 100644 index 0000000000..1ce252df98 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/TranslatingListenerInvoker.java @@ -0,0 +1,99 @@ +/* + * 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.broker.impl.compat; + +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener; +import org.opendaylight.controller.sal.core.api.data.DataChangeListener; +import org.opendaylight.yangtools.concepts.Delegator; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; + +abstract class TranslatingListenerInvoker implements AutoCloseable, DOMDataChangeListener, Delegator { + + private final DataChangeListener delegate; + private final DataNormalizer normalizer; + protected ListenerRegistration reg; + + protected TranslatingListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) { + this.delegate = listener; + this.normalizer = normalizer; + } + + static TranslatingListenerInvoker createConfig(final DataChangeListener listener, final DataNormalizer normalizer) { + return new TranslatingConfigListenerInvoker(listener, normalizer); + } + + static TranslatingListenerInvoker createOperational(final DataChangeListener listener, final DataNormalizer normalizer) { + return new TranslatingOperationalListenerInvoker(listener, normalizer); + } + + @Override + public void onDataChanged(final AsyncDataChangeEvent> normalizedChange) { + delegate.onDataChanged(getLegacyEvent(normalizer, normalizedChange)); + } + + abstract DataChangeEvent getLegacyEvent(final DataNormalizer normalizer, + final AsyncDataChangeEvent> normalizedChange); + + @Override + public DataChangeListener getDelegate() { + return delegate; + } + + abstract void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath); + + @Override + public void close() { + if (reg != null) { + reg.close(); + } + } + + static final class TranslatingConfigListenerInvoker extends TranslatingListenerInvoker { + + public TranslatingConfigListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) { + super(listener, normalizer); + } + + DataChangeEvent getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent> normalizedChange) { + return TranslatingDataChangeEvent.createConfiguration(normalizedChange, normalizer); + } + + @Override + void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) { + reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, normalizedPath, this, + AsyncDataBroker.DataChangeScope.SUBTREE); + } + } + + static final class TranslatingOperationalListenerInvoker extends TranslatingListenerInvoker { + + public TranslatingOperationalListenerInvoker(final DataChangeListener listener, final DataNormalizer normalizer) { + super(listener, normalizer); + } + + DataChangeEvent getLegacyEvent(final DataNormalizer normalizer, final AsyncDataChangeEvent> normalizedChange) { + return TranslatingDataChangeEvent.createOperational(normalizedChange, normalizer); + } + + @Override + void register(final DOMDataBroker backingBroker, final InstanceIdentifier normalizedPath) { + reg = backingBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, normalizedPath, this, + AsyncDataBroker.DataChangeScope.SUBTREE); + } + } + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java deleted file mode 100644 index 6baf7647bd..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataPreconditionFailedException.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl; - -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; - -public class DataPreconditionFailedException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 596430355175413427L; - private final InstanceIdentifier path; - - public DataPreconditionFailedException(final InstanceIdentifier path) { - this.path = path; - } - - public DataPreconditionFailedException(final InstanceIdentifier path,final String message) { - super(message); - this.path = path; - } - - - public DataPreconditionFailedException(final InstanceIdentifier path,final Throwable cause) { - super(cause); - this.path = path; - } - - public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause) { - super(message, cause); - this.path = path; - } - - public DataPreconditionFailedException(final InstanceIdentifier path,final String message, final Throwable cause, final boolean enableSuppression, - final boolean writableStackTrace) { - super(message, cause, enableSuppression, writableStackTrace); - this.path = path; - } - - public InstanceIdentifier getPath() { - return path; - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java deleted file mode 100644 index 3124199006..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/DataTree.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.md.sal.dom.store.impl; - -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -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.data.impl.schema.NormalizedNodeUtils; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; - -/** - * Read-only snapshot of the data tree. - */ -final class DataTree { - public static final class Snapshot { - private final SchemaContext schemaContext; - private final StoreMetadataNode rootNode; - - @VisibleForTesting - Snapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode) { - this.schemaContext = Preconditions.checkNotNull(schemaContext); - this.rootNode = Preconditions.checkNotNull(rootNode); - } - - public SchemaContext getSchemaContext() { - return schemaContext; - } - - public Optional> readNode(final InstanceIdentifier path) { - return NormalizedNodeUtils.findNode(rootNode.getData(), path); - } - - // FIXME: this is a leak of information - @Deprecated - StoreMetadataNode getRootNode() { - return rootNode; - } - - @Override - public String toString() { - return rootNode.getSubtreeVersion().toString(); - } - } - - private static final Logger LOG = LoggerFactory.getLogger(DataTree.class); - private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); - private StoreMetadataNode rootNode; - private SchemaContext currentSchemaContext; - - private DataTree(StoreMetadataNode rootNode, final SchemaContext schemaContext) { - this.rootNode = Preconditions.checkNotNull(rootNode); - this.currentSchemaContext = schemaContext; - } - - 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. - */ - - // Ready to change the context now, make sure no operations are running - rwLock.writeLock().lock(); - try { - this.currentSchemaContext = newSchemaContext; - } finally { - rwLock.writeLock().unlock(); - } - } - - public static DataTree create(final SchemaContext schemaContext) { - final NodeIdentifier root = new NodeIdentifier(SchemaContext.NAME); - final NormalizedNode data = Builders.containerBuilder().withNodeIdentifier(root).build(); - - return new DataTree(StoreMetadataNode.createEmpty(data), schemaContext); - } - - public Snapshot takeSnapshot() { - rwLock.readLock().lock(); - - try { - return new Snapshot(currentSchemaContext, rootNode); - } finally { - rwLock.readLock().unlock(); - } - } - - public void commitSnapshot(Snapshot currentSnapshot, StoreMetadataNode newDataTree) { - // Ready to change the context now, make sure no operations are running - rwLock.writeLock().lock(); - try { - Preconditions.checkState(currentSnapshot.rootNode == rootNode, - String.format("Store snapshot %s and transaction snapshot %s differ.", - rootNode, currentSnapshot.rootNode)); - - this.rootNode = newDataTree; - } finally { - rwLock.writeLock().unlock(); - } - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index 7d2ff30b1f..9e11fc70fc 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -9,7 +9,6 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; -import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.increase; import java.util.Collections; import java.util.concurrent.Callable; @@ -17,10 +16,13 @@ import java.util.concurrent.atomic.AtomicLong; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; +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.DataTreeSnapshot; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.InMemoryDataTreeFactory; import org.opendaylight.controller.sal.core.spi.data.DOMStore; import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; @@ -31,7 +33,6 @@ import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.concepts.ListenerRegistration; 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.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaContextListener; @@ -42,22 +43,17 @@ import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedLong; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; public class InMemoryDOMDataStore implements DOMStore, Identifiable, SchemaContextListener { - private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataStore.class); - private static final InstanceIdentifier PUBLIC_ROOT_PATH = InstanceIdentifier.builder().build(); - + private final DataTree dataTree = InMemoryDataTreeFactory.getInstance().create(); + private final ListenerTree listenerTree = ListenerTree.create(); + private final AtomicLong txCounter = new AtomicLong(0); private final ListeningExecutorService executor; private final String name; - private final AtomicLong txCounter = new AtomicLong(0); - private final ListenerTree listenerTree = ListenerTree.create(); - private final DataTree dataTree = DataTree.create(null); - private ModificationApplyOperation operationTree = new AlwaysFailOperation(); public InMemoryDOMDataStore(final String name, final ListeningExecutorService executor) { this.name = Preconditions.checkNotNull(name); @@ -76,25 +72,17 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public DOMStoreReadWriteTransaction newReadWriteTransaction() { - return new SnapshotBackedReadWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree); + return new SnapshotBackedReadWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this); } @Override public DOMStoreWriteTransaction newWriteOnlyTransaction() { - return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this, operationTree); + return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this); } @Override public synchronized void onGlobalContextUpdated(final SchemaContext ctx) { - /* - * Order of operations is important: dataTree may reject the context - * and creation of ModificationApplyOperation may fail. So pre-construct - * the operation, then update the data tree and then move the operation - * into view. - */ - final ModificationApplyOperation newOperationTree = SchemaAwareApplyOperationRoot.from(ctx); dataTree.setSchemaContext(ctx); - operationTree = newOperationTree; } @Override @@ -145,28 +133,6 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch return name + "-" + txCounter.getAndIncrement(); } - private void commit(final DataTree.Snapshot currentSnapshot, final StoreMetadataNode newDataTree, - final ResolveDataChangeEventsTask listenerResolver) { - LOG.debug("Updating Store snaphot version: {} with version:{}", currentSnapshot, newDataTree.getSubtreeVersion()); - - if (LOG.isTraceEnabled()) { - LOG.trace("Data Tree is {}", StoreUtils.toStringTree(newDataTree.getData())); - } - - /* - * The commit has to occur atomically with regard to listener - * registrations. - */ - synchronized (this) { - dataTree.commitSnapshot(currentSnapshot, newDataTree); - - for (ChangeListenerNotifyTask task : listenerResolver.call()) { - LOG.trace("Scheduling invocation of listeners: {}", task); - executor.submit(task); - } - } - } - private static abstract class AbstractDOMStoreTransaction implements DOMStoreTransaction { private final Object identifier; @@ -197,10 +163,10 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } private static final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements - DOMStoreReadTransaction { - private DataTree.Snapshot stableSnapshot; + DOMStoreReadTransaction { + private DataTreeSnapshot stableSnapshot; - public SnapshotBackedReadTransaction(final Object identifier, final DataTree.Snapshot snapshot) { + public SnapshotBackedReadTransaction(final Object identifier, final DataTreeSnapshot snapshot) { super(identifier); this.stableSnapshot = Preconditions.checkNotNull(snapshot); LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot); @@ -221,15 +187,15 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } private static class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements - DOMStoreWriteTransaction { - private MutableDataTree mutableTree; + DOMStoreWriteTransaction { + private DataTreeModification mutableTree; private InMemoryDOMDataStore store; private boolean ready = false; - public SnapshotBackedWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot, - final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) { + public SnapshotBackedWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot, + final InMemoryDOMDataStore store) { super(identifier); - mutableTree = MutableDataTree.from(snapshot, applyOper); + mutableTree = snapshot.newModification(); this.store = store; LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot); } @@ -295,7 +261,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch return store.submit(this); } - protected MutableDataTree getMutatedView() { + protected DataTreeModification getMutatedView() { return mutableTree; } @@ -306,18 +272,18 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch } private static class SnapshotBackedReadWriteTransaction extends SnapshotBackedWriteTransaction implements - DOMStoreReadWriteTransaction { + DOMStoreReadWriteTransaction { - protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTree.Snapshot snapshot, - final InMemoryDOMDataStore store, final ModificationApplyOperation applyOper) { - super(identifier, snapshot, store, applyOper); + protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot, + final InMemoryDOMDataStore store) { + super(identifier, snapshot, store); } @Override public ListenableFuture>> read(final InstanceIdentifier path) { LOG.trace("Tx: {} Read: {}", getIdentifier(), path); try { - return Futures.immediateFuture(getMutatedView().read(path)); + return Futures.immediateFuture(getMutatedView().readNode(path)); } catch (Exception e) { LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e); throw e; @@ -328,63 +294,40 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch private class ThreePhaseCommitImpl implements DOMStoreThreePhaseCommitCohort { private final SnapshotBackedWriteTransaction transaction; - private final NodeModification modification; + private final DataTreeModification modification; - private DataTree.Snapshot storeSnapshot; - private Optional proposedSubtree; private ResolveDataChangeEventsTask listenerResolver; + private DataTreeCandidate candidate; public ThreePhaseCommitImpl(final SnapshotBackedWriteTransaction writeTransaction) { this.transaction = writeTransaction; - this.modification = transaction.getMutatedView().getRootModification(); + this.modification = transaction.getMutatedView(); } @Override public ListenableFuture canCommit() { - final DataTree.Snapshot snapshotCapture = dataTree.takeSnapshot(); - final ModificationApplyOperation snapshotOperation = operationTree; - return executor.submit(new Callable() { - @Override - public Boolean call() throws Exception { - Boolean applicable = false; + public Boolean call() { try { - snapshotOperation.checkApplicable(PUBLIC_ROOT_PATH, modification, - Optional.of(snapshotCapture.getRootNode())); - applicable = true; + dataTree.validate(modification); + LOG.debug("Store Transaction: {} can be committed", transaction.getIdentifier()); + return true; } catch (DataPreconditionFailedException e) { LOG.warn("Store Tx: {} Data Precondition failed for {}.",transaction.getIdentifier(),e.getPath(),e); - applicable = false; + return false; } - LOG.debug("Store Transaction: {} : canCommit : {}", transaction.getIdentifier(), applicable); - return applicable; } }); } @Override public ListenableFuture preCommit() { - storeSnapshot = dataTree.takeSnapshot(); - if (modification.getModificationType() == ModificationType.UNMODIFIED) { - return Futures.immediateFuture(null); - } return executor.submit(new Callable() { - @Override - public Void call() throws Exception { - StoreMetadataNode metadataTree = storeSnapshot.getRootNode(); - - proposedSubtree = operationTree.apply(modification, Optional.of(metadataTree), - increase(metadataTree.getSubtreeVersion())); - - listenerResolver = ResolveDataChangeEventsTask.create() // - .setRootPath(PUBLIC_ROOT_PATH) // - .setBeforeRoot(Optional.of(metadataTree)) // - .setAfterRoot(proposedSubtree) // - .setModificationRoot(modification) // - .setListenerRoot(listenerTree); - + public Void call() { + candidate = dataTree.prepare(modification); + listenerResolver = ResolveDataChangeEventsTask.create(candidate, listenerTree); return null; } }); @@ -392,48 +335,32 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch @Override public ListenableFuture abort() { - storeSnapshot = null; - proposedSubtree = null; + if (candidate != null) { + candidate.close(); + candidate = null; + } + return Futures. immediateFuture(null); } @Override public ListenableFuture commit() { - if (modification.getModificationType() == ModificationType.UNMODIFIED) { - return Futures.immediateFuture(null); + checkState(candidate != null, "Proposed subtree must be computed"); + + /* + * The commit has to occur atomically with regard to listener + * registrations. + */ + synchronized (this) { + dataTree.commit(candidate); + + for (ChangeListenerNotifyTask task : listenerResolver.call()) { + LOG.trace("Scheduling invocation of listeners: {}", task); + executor.submit(task); + } } - checkState(proposedSubtree != null, "Proposed subtree must be computed"); - checkState(storeSnapshot != null, "Proposed subtree must be computed"); - // return ImmediateFuture<>; - InMemoryDOMDataStore.this.commit(storeSnapshot, proposedSubtree.get(), listenerResolver); return Futures. immediateFuture(null); } - - } - - private static final class AlwaysFailOperation implements ModificationApplyOperation { - - @Override - public Optional apply(final NodeModification modification, - final Optional storeMeta, final UnsignedLong subtreeVersion) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - public Optional getChild(final PathArgument child) { - throw new IllegalStateException("Schema Context is not available."); - } - - @Override - public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { - throw new IllegalStateException("Schema Context is not available."); - } - } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java index 44d50166af..db9bb0fef2 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java @@ -8,7 +8,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl; import static org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.builder; -import static org.opendaylight.controller.md.sal.dom.store.impl.StoreUtils.append; +import static org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils.append; import java.util.Collection; import java.util.Collections; @@ -22,11 +22,12 @@ import java.util.concurrent.Callable; import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.Builder; import org.opendaylight.controller.md.sal.dom.store.impl.DOMImmutableDataChangeEvent.SimpleEventFactory; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Node; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ListenerTree.Walker; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.NodeModification; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.StoreMetadataNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; @@ -38,6 +39,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; +import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; @@ -62,61 +64,18 @@ import com.google.common.collect.Multimap; * * */ -public class ResolveDataChangeEventsTask implements Callable> { +final class ResolveDataChangeEventsTask implements Callable> { private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class); private static final DOMImmutableDataChangeEvent NO_CHANGE = builder(DataChangeScope.BASE).build(); - private InstanceIdentifier rootPath; - private ListenerTree listenerRoot; - private NodeModification modificationRoot; - private Optional beforeRoot; - private Optional afterRoot; private final Multimap events = HashMultimap.create(); + private final DataTreeCandidate candidate; + private final ListenerTree listenerRoot; - protected InstanceIdentifier getRootPath() { - return rootPath; - } - - protected ResolveDataChangeEventsTask setRootPath(final InstanceIdentifier rootPath) { - this.rootPath = rootPath; - return this; - } - - protected ListenerTree getListenerRoot() { - return listenerRoot; - } - - protected ResolveDataChangeEventsTask setListenerRoot(final ListenerTree listenerRoot) { - this.listenerRoot = listenerRoot; - return this; - } - - protected NodeModification getModificationRoot() { - return modificationRoot; - } - - protected ResolveDataChangeEventsTask setModificationRoot(final NodeModification modificationRoot) { - this.modificationRoot = modificationRoot; - return this; - } - - protected Optional getBeforeRoot() { - return beforeRoot; - } - - protected ResolveDataChangeEventsTask setBeforeRoot(final Optional beforeRoot) { - this.beforeRoot = beforeRoot; - return this; - } - - protected Optional getAfterRoot() { - return afterRoot; - } - - protected ResolveDataChangeEventsTask setAfterRoot(final Optional afterRoot) { - this.afterRoot = afterRoot; - return this; - } + public ResolveDataChangeEventsTask(DataTreeCandidate candidate, ListenerTree listenerTree) { + this.candidate = Preconditions.checkNotNull(candidate); + this.listenerRoot = Preconditions.checkNotNull(listenerTree); + } /** * Resolves and creates Notification Tasks @@ -129,11 +88,10 @@ public class ResolveDataChangeEventsTask implements Callable call() { - LOG.trace("Resolving events for {}", modificationRoot); - try (final Walker w = listenerRoot.getWalker()) { - resolveAnyChangeEvent(rootPath, Collections.singleton(w.getRootNode()), modificationRoot, beforeRoot, - afterRoot); + resolveAnyChangeEvent(candidate.getRootPath(), Collections.singleton(w.getRootNode()), + candidate.getModificationRoot(), Optional.fromNullable(candidate.getBeforeRoot()), + Optional.fromNullable(candidate.getAfterRoot())); return createNotificationTasks(); } } @@ -556,7 +514,7 @@ public class ResolveDataChangeEventsTask implements Callable data); + void write(InstanceIdentifier path, NormalizedNode data); + void seal(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java new file mode 100644 index 0000000000..a94acc5658 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeSnapshot.java @@ -0,0 +1,37 @@ +/* + * 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> 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(); +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java similarity index 98% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java index e1da9a7381..7e783f927d 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/StoreUtils.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl; +package org.opendaylight.controller.md.sal.dom.store.impl.tree; import java.util.Set; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java new file mode 100644 index 0000000000..b2faf79565 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AbstractDataTreeCandidate.java @@ -0,0 +1,33 @@ +/* + * 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; + private final NodeModification modificationRoot; + + protected AbstractDataTreeCandidate(final InstanceIdentifier rootPath, NodeModification modificationRoot) { + this.rootPath = Preconditions.checkNotNull(rootPath); + this.modificationRoot = Preconditions.checkNotNull(modificationRoot); + } + + @Override + public final InstanceIdentifier getRootPath() { + return rootPath; + } + + @Override + public final NodeModification getModificationRoot() { + return modificationRoot; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java new file mode 100644 index 0000000000..4e3aa49113 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/AlwaysFailOperation.java @@ -0,0 +1,31 @@ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +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.primitives.UnsignedLong; + +final class AlwaysFailOperation implements ModificationApplyOperation { + + @Override + public Optional apply(final NodeModification modification, + final Optional storeMeta, final UnsignedLong subtreeVersion) { + throw new IllegalStateException("Schema Context is not available."); + } + + @Override + public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional storeMetadata) { + throw new IllegalStateException("Schema Context is not available."); + } + + @Override + public Optional getChild(final PathArgument child) { + throw new IllegalStateException("Schema Context is not available."); + } + + @Override + public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { + throw new IllegalStateException("Schema Context is not available."); + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java new file mode 100644 index 0000000000..5a300a071d --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTree.java @@ -0,0 +1,136 @@ +/* + * 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.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; +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.StoreUtils; +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 com.google.common.base.Optional; +import com.google.common.base.Preconditions; + +/** + * 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 StoreMetadataNode rootNode; + + public InMemoryDataTree(StoreMetadataNode 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(DataTreeModification modification) throws DataPreconditionFailedException { + 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.of(rootNode)); + } + + @Override + public synchronized DataTreeCandidate prepare(DataTreeModification modification) { + Preconditions.checkArgument(modification instanceof InMemoryDataTreeModification, "Invalid modification class %s", modification.getClass()); + + final InMemoryDataTreeModification m = (InMemoryDataTreeModification)modification; + final NodeModification root = m.getRootModification(); + + if (root.getModificationType() == ModificationType.UNMODIFIED) { + return new NoopDataTreeCandidate(PUBLIC_ROOT_PATH, root); + } + + rwLock.writeLock().lock(); + try { + // FIXME: rootNode needs to be a read-write snapshot here... + final Optional newRoot = m.getStrategy().apply(m.getRootModification(), Optional.of(rootNode), StoreUtils.increase(rootNode.getSubtreeVersion())); + 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(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 Store snapshot version: {} with version:{}", rootNode.getSubtreeVersion(), c.getAfterRoot().getSubtreeVersion()); + + 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 snapshot %s and transaction snapshot %s differ.", rootNode, c.getBeforeRoot())); + this.rootNode = c.getAfterRoot(); + } finally { + rwLock.writeLock().unlock(); + } + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java new file mode 100644 index 0000000000..93719b7f53 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeCandidate.java @@ -0,0 +1,32 @@ +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; + +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; + +import com.google.common.base.Preconditions; + +final class InMemoryDataTreeCandidate extends AbstractDataTreeCandidate { + private final StoreMetadataNode newRoot; + private final StoreMetadataNode oldRoot; + + InMemoryDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot, + final StoreMetadataNode oldRoot, final StoreMetadataNode newRoot) { + super(rootPath, modificationRoot); + this.newRoot = Preconditions.checkNotNull(newRoot); + this.oldRoot = Preconditions.checkNotNull(oldRoot); + } + + @Override + public void close() { + // FIXME: abort operation here :) + } + + @Override + public StoreMetadataNode getBeforeRoot() { + return oldRoot; + } + + @Override + public StoreMetadataNode getAfterRoot() { + return newRoot; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java new file mode 100644 index 0000000000..7614611ab2 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeFactory.java @@ -0,0 +1,35 @@ +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.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(StoreMetadataNode.createEmpty(data), null); + } + + /** + * Get an instance of this factory. This method cannot fail. + * + * @return Data tree factory instance. + */ + public static final InMemoryDataTreeFactory getInstance() { + return INSTANCE; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java similarity index 69% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java index 1002cd54b5..df3ef8b7e1 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java @@ -5,15 +5,15 @@ * 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; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkState; import java.util.Map.Entry; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; @@ -26,28 +26,42 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; -/* - * FIXME: the thread safety of concurrent write/delete/read/seal operations - * needs to be evaluated. - */ -class MutableDataTree { - private static final Logger LOG = LoggerFactory.getLogger(MutableDataTree.class); - private final AtomicBoolean sealed = new AtomicBoolean(); +final class InMemoryDataTreeModification implements DataTreeModification { + private static final Logger LOG = LoggerFactory.getLogger(InMemoryDataTreeModification.class); + + /* + * FIXME: the thread safety of concurrent write/delete/read/seal operations + * needs to be evaluated. + */ + private static final AtomicIntegerFieldUpdater SEALED_UPDATER = + AtomicIntegerFieldUpdater.newUpdater(InMemoryDataTreeModification.class, "sealed"); + private volatile int sealed = 0; + private final ModificationApplyOperation strategyTree; - private final NodeModification rootModification; - private final DataTree.Snapshot snapshot; + private final InMemoryDataTreeSnapshot snapshot; + private final NodeModification rootNode; - private MutableDataTree(final DataTree.Snapshot snapshot, final ModificationApplyOperation strategyTree) { + InMemoryDataTreeModification(final InMemoryDataTreeSnapshot snapshot, final ModificationApplyOperation resolver) { this.snapshot = Preconditions.checkNotNull(snapshot); - this.strategyTree = Preconditions.checkNotNull(strategyTree); - this.rootModification = NodeModification.createUnmodified(snapshot.getRootNode()); + this.strategyTree = Preconditions.checkNotNull(resolver); + this.rootNode = NodeModification.createUnmodified(snapshot.getRootNode()); } + NodeModification getRootModification() { + return rootNode; + } + + ModificationApplyOperation getStrategy() { + return strategyTree; + } + + @Override public void write(final InstanceIdentifier path, final NormalizedNode value) { checkSealed(); resolveModificationFor(path).write(value); } + @Override public void merge(final InstanceIdentifier path, final NormalizedNode data) { checkSealed(); mergeImpl(resolveModificationFor(path),data); @@ -66,13 +80,15 @@ class MutableDataTree { op.merge(data); } + @Override public void delete(final InstanceIdentifier path) { checkSealed(); resolveModificationFor(path).delete(); } - public Optional> read(final InstanceIdentifier path) { - Entry modification = TreeNodeUtils.findClosestsOrFirstMatch(rootModification, path, NodeModification.IS_TERMINAL_PREDICATE); + @Override + public Optional> readNode(final InstanceIdentifier path) { + Entry modification = TreeNodeUtils.findClosestsOrFirstMatch(rootNode, path, NodeModification.IS_TERMINAL_PREDICATE); Optional result = resolveSnapshot(modification); if (result.isPresent()) { @@ -110,7 +126,7 @@ class MutableDataTree { } private OperationWithModification resolveModificationFor(final InstanceIdentifier path) { - NodeModification modification = rootModification; + NodeModification modification = rootNode; // We ensure strategy is present. ModificationApplyOperation operation = resolveModificationStrategy(path); for (PathArgument pathArg : path.getPath()) { @@ -119,26 +135,25 @@ class MutableDataTree { return OperationWithModification.from(operation, modification); } - public static MutableDataTree from(final DataTree.Snapshot snapshot, final ModificationApplyOperation resolver) { - return new MutableDataTree(snapshot, resolver); - } - + @Override public void seal() { - final boolean success = sealed.compareAndSet(false, true); + final boolean success = SEALED_UPDATER.compareAndSet(this, 0, 1); Preconditions.checkState(success, "Attempted to seal an already-sealed Data Tree."); - rootModification.seal(); + rootNode.seal(); } private void checkSealed() { - checkState(!sealed.get(), "Data Tree is sealed. No further modifications allowed."); + checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed."); } - protected NodeModification getRootModification() { - return rootModification; + @Override + public String toString() { + return "MutableDataTree [modification=" + rootNode + "]"; } @Override - public String toString() { - return "MutableDataTree [modification=" + rootModification + "]"; + public DataTreeModification newModification() { + // FIXME: transaction chaining + throw new UnsupportedOperationException("Implement this as part of transaction chaining"); } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java new file mode 100644 index 0000000000..ce2d8c9bd4 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeSnapshot.java @@ -0,0 +1,47 @@ +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.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 StoreMetadataNode rootNode; + + InMemoryDataTreeSnapshot(final SchemaContext schemaContext, final StoreMetadataNode rootNode, + final ModificationApplyOperation applyOper) { + this.schemaContext = Preconditions.checkNotNull(schemaContext); + this.rootNode = Preconditions.checkNotNull(rootNode); + this.applyOper = Preconditions.checkNotNull(applyOper); + } + + StoreMetadataNode getRootNode() { + return rootNode; + } + + SchemaContext getSchemaContext() { + return schemaContext; + } + + @Override + public Optional> readNode(final InstanceIdentifier path) { + return NormalizedNodeUtils.findNode(rootNode.getData(), path); + } + + @Override + public InMemoryDataTreeModification newModification() { + return new InMemoryDataTreeModification(this, applyOper); + } + + @Override + public String toString() { + return rootNode.getSubtreeVersion().toString(); + } + +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java similarity index 83% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationApplyOperation.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java index 361be6800c..5b4cd565e5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java @@ -5,10 +5,9 @@ * 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; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; @@ -38,7 +37,7 @@ import com.google.common.primitives.UnsignedLong; * * */ -public interface ModificationApplyOperation extends StoreTreeNode { +interface ModificationApplyOperation extends StoreTreeNode { /** * @@ -80,14 +79,14 @@ public interface ModificationApplyOperation extends StoreTreeNode getChild(PathArgument child); /** - * - * Checks if provided node modification could be applied to current metadata node. - * - * @param modification Modification - * @param current Metadata Node to which modification should be applied - * @return true if modification is applicable - * false if modification is no applicable + * + * Checks if provided node modification could be applied to current metadata node. + * + * @param modification Modification + * @param current Metadata Node to which modification should be applied + * @return true if modification is applicable + * false if modification is no applicable * @throws DataPreconditionFailedException - */ + */ void checkApplicable(InstanceIdentifier path, NodeModification modification, Optional current) throws DataPreconditionFailedException; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java similarity index 91% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java index b16e907120..9d2e965ff7 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationType.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; public enum ModificationType { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java similarity index 96% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java index 4f650c1711..18179afd50 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkState; @@ -14,6 +14,7 @@ import java.util.Map; import javax.annotation.concurrent.GuardedBy; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; @@ -31,6 +32,7 @@ import com.google.common.base.Predicate; * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}. * */ +// FIXME: hide this class public class NodeModification implements StoreTreeNode, Identifiable { public static final Predicate IS_TERMINAL_PREDICATE = new Predicate() { @@ -67,7 +69,7 @@ public class NodeModification implements StoreTreeNode, Identi * * @return */ - public NormalizedNode getWritenValue() { + public NormalizedNode getWrittenValue() { return value; } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java new file mode 100644 index 0000000000..1782da2835 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NoopDataTreeCandidate.java @@ -0,0 +1,31 @@ +/* + * 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.yangtools.yang.data.api.InstanceIdentifier; + +final class NoopDataTreeCandidate extends AbstractDataTreeCandidate { + protected NoopDataTreeCandidate(final InstanceIdentifier rootPath, final NodeModification modificationRoot) { + super(rootPath, modificationRoot); + } + + @Override + public void close() { + // NO-OP + } + + @Override + public StoreMetadataNode getBeforeRoot() { + return null; + } + + @Override + public StoreMetadataNode getAfterRoot() { + return null; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java similarity index 89% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java index 780291e70f..fda8407a95 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java @@ -5,17 +5,15 @@ * 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; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; import com.google.common.primitives.UnsignedLong; -public class OperationWithModification { +final class OperationWithModification { private final NodeModification modification; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java similarity index 93% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java index afe9653394..02244d9f98 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkArgument; @@ -15,10 +15,8 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutionException; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreNodeCompositeBuilder; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; @@ -70,7 +68,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMap; import com.google.common.primitives.UnsignedLong; -public abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { +abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { public static SchemaAwareApplyOperation from(final DataSchemaNode schemaNode) { if (schemaNode instanceof ContainerSchemaNode) { @@ -111,15 +109,17 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper public static SchemaAwareApplyOperation from(final DataNodeContainer resolvedTree, final AugmentationTarget augSchemas, final AugmentationIdentifier identifier) { AugmentationSchema augSchema = null; - allAugments: for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { - boolean containsAll = true; - for (DataSchemaNode child : potential.getChildNodes()) { - if (identifier.getPossibleChildNames().contains(child.getQName())) { - augSchema = potential; - break allAugments; + + allAugments: + for (AugmentationSchema potential : augSchemas.getAvailableAugmentations()) { + for (DataSchemaNode child : potential.getChildNodes()) { + if (identifier.getPossibleChildNames().contains(child.getQName())) { + augSchema = potential; + break allAugments; + } } } - } + if (augSchema != null) { return new AugmentationModificationStrategy(augSchema, resolvedTree); } @@ -135,11 +135,11 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper @Override public void verifyStructure(final NodeModification modification) throws IllegalArgumentException { if (modification.getModificationType() == ModificationType.WRITE) { - verifyWritenStructure(modification.getWritenValue()); + verifyWrittenStructure(modification.getWrittenValue()); } } - protected abstract void verifyWritenStructure(NormalizedNode writenValue); + protected abstract void verifyWrittenStructure(NormalizedNode writtenValue); @Override public void checkApplicable(final InstanceIdentifier path,final NodeModification modification, final Optional current) throws DataPreconditionFailedException { @@ -233,8 +233,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper protected abstract StoreMetadataNode applySubtreeChange(NodeModification modification, StoreMetadataNode currentMeta, UnsignedLong subtreeVersion); - public static abstract class ValueNodeModificationStrategy extends - SchemaAwareApplyOperation { + public static abstract class ValueNodeModificationStrategy extends SchemaAwareApplyOperation { private final T schema; private final Class> nodeClass; @@ -246,8 +245,8 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } @Override - protected void verifyWritenStructure(final NormalizedNode writenValue) { - checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass); + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { + checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); } @Override @@ -274,7 +273,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper final Optional currentMeta, final UnsignedLong subtreeVersion) { UnsignedLong nodeVersion = subtreeVersion; return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion) - .setData(modification.getWritenValue()).build(); + .setData(modification.getWrittenValue()).build(); } @Override @@ -329,13 +328,20 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper @SuppressWarnings("rawtypes") @Override - protected void verifyWritenStructure(final NormalizedNode writenValue) { - checkArgument(nodeClass.isInstance(writenValue), "Node should must be of type %s", nodeClass); - checkArgument(writenValue instanceof NormalizedNodeContainer); - NormalizedNodeContainer writenCont = (NormalizedNodeContainer) writenValue; - for (Object child : writenCont.getValue()) { + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { + checkArgument(nodeClass.isInstance(writtenValue), "Node should must be of type %s", nodeClass); + checkArgument(writtenValue instanceof NormalizedNodeContainer); + + NormalizedNodeContainer container = (NormalizedNodeContainer) writtenValue; + for (Object child : container.getValue()) { checkArgument(child instanceof NormalizedNode); - NormalizedNode childNode = (NormalizedNode) child; + + /* + * FIXME: fail-fast semantics: + * + * We can validate the data structure here, aborting the commit + * before it ever progresses to being committed. + */ } } @@ -343,7 +349,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper protected StoreMetadataNode applyWrite(final NodeModification modification, final Optional currentMeta, final UnsignedLong subtreeVersion) { - NormalizedNode newValue = modification.getWritenValue(); + NormalizedNode newValue = modification.getWrittenValue(); final UnsignedLong nodeVersion; if (currentMeta.isPresent()) { @@ -436,8 +442,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper protected abstract NormalizedNodeContainerBuilder createBuilder(NormalizedNode original); } - public static abstract class DataNodeContainerModificationStrategy extends - NormalizedNodeContainerModificationStrategy { + public static abstract class DataNodeContainerModificationStrategy extends NormalizedNodeContainerModificationStrategy { private final T schema; private final LoadingCache childCache = CacheBuilder.newBuilder() @@ -487,8 +492,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } - public static class ContainerModificationStrategy extends - DataNodeContainerModificationStrategy { + public static class ContainerModificationStrategy extends DataNodeContainerModificationStrategy { public ContainerModificationStrategy(final ContainerSchemaNode schemaNode) { super(schemaNode, ContainerNode.class); @@ -502,8 +506,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } } - public static class UnkeyedListItemModificationStrategy extends - DataNodeContainerModificationStrategy { + public static class UnkeyedListItemModificationStrategy extends DataNodeContainerModificationStrategy { public UnkeyedListItemModificationStrategy(final ListSchemaNode schemaNode) { super(schemaNode, UnkeyedListEntryNode.class); @@ -517,8 +520,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } } - public static class AugmentationModificationStrategy extends - DataNodeContainerModificationStrategy { + public static class AugmentationModificationStrategy extends DataNodeContainerModificationStrategy { protected AugmentationModificationStrategy(final AugmentationSchema schema, final DataNodeContainer resolved) { super(createAugmentProxy(schema,resolved), AugmentationNode.class); @@ -534,12 +536,10 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper public static class ChoiceModificationStrategy extends NormalizedNodeContainerModificationStrategy { - private final ChoiceNode schema; private final Map childNodes; public ChoiceModificationStrategy(final ChoiceNode schemaNode) { super(org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode.class); - this.schema = schemaNode; ImmutableMap.Builder child = ImmutableMap.builder(); for (ChoiceCaseNode caze : schemaNode.getCases()) { @@ -653,7 +653,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper @Override protected StoreMetadataNode applyWrite(final NodeModification modification, final Optional currentMeta, final UnsignedLong subtreeVersion) { - return StoreMetadataNode.createRecursively(modification.getWritenValue(), subtreeVersion); + return StoreMetadataNode.createRecursively(modification.getWrittenValue(), subtreeVersion); } @Override @@ -665,7 +665,7 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } @Override - protected void verifyWritenStructure(final NormalizedNode writenValue) { + protected void verifyWrittenStructure(final NormalizedNode writtenValue) { } @@ -737,10 +737,6 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper } } - public void verifyIdentifier(final PathArgument identifier) { - - } - public static AugmentationSchema createAugmentProxy(final AugmentationSchema schema, final DataNodeContainer resolved) { Set realChildSchemas = new HashSet<>(); for(DataSchemaNode augChild : schema.getChildNodes()) { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java similarity index 97% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java index b8ad7368b5..8addb89bd1 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreMetadataNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreMetadataNode.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import static com.google.common.base.Preconditions.checkState; @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; @@ -23,6 +24,7 @@ import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.primitives.UnsignedLong; +// FIXME: this should not be public public class StoreMetadataNode implements Immutable, Identifiable, StoreTreeNode { private final UnsignedLong nodeVersion; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreNodeCompositeBuilder.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java similarity index 96% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreNodeCompositeBuilder.java rename to opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java index a66a1d5b1c..6bce4fff0c 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreNodeCompositeBuilder.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/StoreNodeCompositeBuilder.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl.tree; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder; @@ -20,7 +20,7 @@ import com.google.common.primitives.UnsignedLong; * */ @SuppressWarnings("rawtypes") -public class StoreNodeCompositeBuilder { +class StoreNodeCompositeBuilder { private final StoreMetadataNode.Builder metadata; diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend index 9cbf4282e4..357a516b57 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend @@ -8,29 +8,22 @@ package org.opendaylight.controller.sal.dom.broker import java.util.Hashtable +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker +import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry import org.opendaylight.controller.sal.core.api.data.DataBrokerService import org.opendaylight.controller.sal.core.api.data.DataProviderService import org.opendaylight.controller.sal.core.api.data.DataStore import org.opendaylight.controller.sal.core.api.model.SchemaService -import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener import org.opendaylight.controller.sal.core.api.mount.MountProvisionService import org.opendaylight.controller.sal.core.api.mount.MountService import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareDataStoreAdapter import org.opendaylight.controller.sal.dom.broker.impl.SchemaAwareRpcBroker +import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier +import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener import org.osgi.framework.BundleContext import org.osgi.framework.ServiceRegistration -import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProviders -import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry -import org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker -import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl -import com.google.common.util.concurrent.MoreExecutors -import com.google.common.collect.ImmutableMap -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType -import org.opendaylight.controller.sal.core.spi.data.DOMStore -import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore -import java.util.concurrent.Executors -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker class BrokerConfigActivator implements AutoCloseable { diff --git a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java similarity index 81% rename from opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java rename to opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java index 0445c47c6b..8940e55d32 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/ModificationMetadataTreeTest.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationMetadataTreeTest.java @@ -1,4 +1,11 @@ -package org.opendaylight.controller.md.sal.dom.store.impl; +/* + * 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 org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -19,7 +26,9 @@ import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.ma import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode; +import org.opendaylight.controller.md.sal.dom.store.impl.TestModel; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; @@ -89,14 +98,16 @@ public class ModificationMetadataTreeTest { .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) // .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) // .build()) // - .build(); + .build(); private SchemaContext schemaContext; + private ModificationApplyOperation applyOper; @Before public void prepare() { schemaContext = TestModel.createTestContext(); assertNotNull("Schema context must not be null.", schemaContext); + applyOper = SchemaAwareApplyOperation.from(schemaContext); } /** @@ -131,16 +142,16 @@ public class ModificationMetadataTreeTest { .withNodeIdentifier(new NodeIdentifier(TEST_QNAME)) .withChild( mapNodeBuilder(OUTER_LIST_QNAME) - .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID)) - .withChild(BAR_NODE).build()).build(); + .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID)) + .withChild(BAR_NODE).build()).build(); } @Test public void basicReadWrites() { - MutableDataTree modificationTree = MutableDataTree.from(new DataTree.Snapshot(schemaContext, - StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5))), + DataTreeModification modificationTree = new InMemoryDataTreeModification(new InMemoryDataTreeSnapshot(schemaContext, + StoreMetadataNode.createRecursively(createDocumentOne(), UnsignedLong.valueOf(5)), applyOper), new SchemaAwareApplyOperationRoot(schemaContext)); - Optional> originalBarNode = modificationTree.read(OUTER_LIST_2_PATH); + Optional> originalBarNode = modificationTree.readNode(OUTER_LIST_2_PATH); assertTrue(originalBarNode.isPresent()); assertSame(BAR_NODE, originalBarNode.get()); @@ -149,22 +160,23 @@ public class ModificationMetadataTreeTest { // reads node to /outer-list/1/inner_list/two/value // and checks if node is already present - Optional> barTwoCModified = modificationTree.read(TWO_TWO_VALUE_PATH); + Optional> barTwoCModified = modificationTree.readNode(TWO_TWO_VALUE_PATH); assertTrue(barTwoCModified.isPresent()); assertEquals(ImmutableNodes.leafNode(VALUE_QNAME, "test"), barTwoCModified.get()); // delete node to /outer-list/1/inner_list/two/value modificationTree.delete(TWO_TWO_VALUE_PATH); - Optional> barTwoCAfterDelete = modificationTree.read(TWO_TWO_VALUE_PATH); + Optional> barTwoCAfterDelete = modificationTree.readNode(TWO_TWO_VALUE_PATH); assertFalse(barTwoCAfterDelete.isPresent()); } - public MutableDataTree createEmptyModificationTree() { + public DataTreeModification createEmptyModificationTree() { /** * Creates empty Snapshot with associated schema context. */ - DataTree t = DataTree.create(schemaContext); + DataTree t = InMemoryDataTreeFactory.getInstance().create(); + t.setSchemaContext(schemaContext); /** * @@ -172,15 +184,13 @@ public class ModificationMetadataTreeTest { * context. * */ - MutableDataTree modificationTree = MutableDataTree.from(t.takeSnapshot(), new SchemaAwareApplyOperationRoot( - schemaContext)); - return modificationTree; + return t.takeSnapshot().newModification(); } @Test public void createFromEmptyState() { - MutableDataTree modificationTree = createEmptyModificationTree(); + DataTreeModification modificationTree = createEmptyModificationTree(); /** * Writes empty container node to /test * @@ -195,14 +205,14 @@ public class ModificationMetadataTreeTest { /** * Reads list node from /test/outer-list */ - Optional> potentialOuterList = modificationTree.read(OUTER_LIST_PATH); + Optional> potentialOuterList = modificationTree.readNode(OUTER_LIST_PATH); assertTrue(potentialOuterList.isPresent()); /** * Reads container node from /test and verifies that it contains test * node */ - Optional> potentialTest = modificationTree.read(TEST_PATH); + Optional> potentialTest = modificationTree.readNode(TEST_PATH); ContainerNode containerTest = assertPresentAndType(potentialTest, ContainerNode.class); /** @@ -217,23 +227,23 @@ public class ModificationMetadataTreeTest { @Test public void writeSubtreeReadChildren() { - MutableDataTree modificationTree = createEmptyModificationTree(); + DataTreeModification modificationTree = createEmptyModificationTree(); modificationTree.write(TEST_PATH, createTestContainer()); - Optional> potential = modificationTree.read(TWO_TWO_PATH); - MapEntryNode node = assertPresentAndType(potential, MapEntryNode.class); + Optional> potential = modificationTree.readNode(TWO_TWO_PATH); + assertPresentAndType(potential, MapEntryNode.class); } @Test public void writeSubtreeDeleteChildren() { - MutableDataTree modificationTree = createEmptyModificationTree(); + DataTreeModification modificationTree = createEmptyModificationTree(); modificationTree.write(TEST_PATH, createTestContainer()); // We verify data are present - Optional> potentialBeforeDelete = modificationTree.read(TWO_TWO_PATH); - MapEntryNode node = assertPresentAndType(potentialBeforeDelete, MapEntryNode.class); + Optional> potentialBeforeDelete = modificationTree.readNode(TWO_TWO_PATH); + assertPresentAndType(potentialBeforeDelete, MapEntryNode.class); modificationTree.delete(TWO_TWO_PATH); - Optional> potentialAfterDelete = modificationTree.read(TWO_TWO_PATH); + Optional> potentialAfterDelete = modificationTree.readNode(TWO_TWO_PATH); assertFalse(potentialAfterDelete.isPresent()); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperationRoot.java b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java similarity index 95% rename from opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperationRoot.java rename to opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java index 8a539ff36e..f2cc533207 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperationRoot.java +++ b/opendaylight/md-sal/sal-dom-broker/src/test/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperationRoot.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.controller.md.sal.dom.store.impl; +package org.opendaylight.controller.md.sal.dom.store.impl.tree.data; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java index 89274c9ad5..1839de1597 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/config/yang/md/sal/connector/netconf/NetconfConnectorModule.java @@ -17,8 +17,10 @@ import java.io.File; import java.io.InputStream; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.URI; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.opendaylight.controller.md.sal.common.api.data.DataChangeEvent; import org.opendaylight.controller.netconf.client.NetconfClientDispatcher; import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl; import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration; @@ -27,8 +29,10 @@ import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClient import org.opendaylight.controller.netconf.client.conf.NetconfReconnectingClientConfigurationBuilder; import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword; import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.connect.netconf.InventoryUtils; import org.opendaylight.controller.sal.connect.netconf.NetconfDevice; import org.opendaylight.controller.sal.connect.netconf.NetconfDeviceListener; +import org.opendaylight.controller.sal.core.api.data.DataChangeListener; import org.opendaylight.protocol.framework.ReconnectStrategy; import org.opendaylight.protocol.framework.ReconnectStrategyFactory; import org.opendaylight.protocol.framework.TimedReconnectStrategy; @@ -36,6 +40,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.inventory.rev140108.NetconfNode; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.opendaylight.yangtools.yang.model.util.repo.AbstractCachingSchemaSourceProvider; import org.opendaylight.yangtools.yang.model.util.repo.FilesystemSchemaCachingProvider; import org.opendaylight.yangtools.yang.model.util.repo.SchemaSourceProvider; diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java index 8f95e73b15..e721084763 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImpl.java @@ -180,10 +180,10 @@ public class ClientImpl implements RemoteRpcClient { * @param routeId route identifier * @return remote network address */ - private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier routeId){ + private String lookupRemoteAddressForGlobalRpc(RpcRouter.RouteIdentifier routeId){ checkNotNull(routeId, "route must not be null"); - Optional> routingTable = routingTableProvider.getRoutingTable(); + Optional, String>> routingTable = routingTableProvider.getRoutingTable(); checkNotNull(routingTable.isPresent(), "Routing table is null"); String address = null; @@ -202,10 +202,10 @@ public class ClientImpl implements RemoteRpcClient { * @param routeId route identifier * @return remote network address */ - private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier routeId){ + private String lookupRemoteAddressForRpc(RpcRouter.RouteIdentifier routeId){ checkNotNull(routeId, "route must not be null"); - Optional> routingTable = routingTableProvider.getRoutingTable(); + Optional, String>> routingTable = routingTableProvider.getRoutingTable(); checkNotNull(routingTable.isPresent(), "Routing table is null"); String address = routingTable.get().getLastAddedRoute(routeId); @@ -230,7 +230,7 @@ public class ClientImpl implements RemoteRpcClient { */ private void closeZmqContext() { ExecutorService exec = Executors.newSingleThreadExecutor(); - FutureTask zmqTermination = new FutureTask(new Runnable() { + FutureTask zmqTermination = new FutureTask(new Runnable() { @Override public void run() { diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/Context.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/Context.java index 9e66c20613..37bff7b7bb 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/Context.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/Context.java @@ -7,19 +7,19 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import org.zeromq.ZMQ; - import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; +import org.zeromq.ZMQ; + /** * Provides a ZeroMQ Context object */ public class Context { - private ZMQ.Context zmqContext = ZMQ.context(1); + private final ZMQ.Context zmqContext = ZMQ.context(1); private String uri; private final String DEFAULT_RPC_PORT = "5554"; @@ -69,7 +69,7 @@ public class Context { */ private String findIpAddress() { String hostAddress = null; - Enumeration e = null; + Enumeration e = null; try { e = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e1) { @@ -79,7 +79,7 @@ public class Context { NetworkInterface n = (NetworkInterface) e.nextElement(); - Enumeration ee = n.getInetAddresses(); + Enumeration ee = n.getInetAddresses(); while (ee.hasMoreElements()) { InetAddress i = (InetAddress) ee.nextElement(); if ((i instanceof Inet4Address) && (i.isSiteLocalAddress())) diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java index a564a0ad04..94e3232f17 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcClient.java @@ -8,14 +8,11 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import org.opendaylight.controller.sal.core.api.RpcImplementation; -import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation; - public interface RemoteRpcClient extends AutoCloseable{ void setRoutingTableProvider(RoutingTableProvider provider); - + void stop(); - + void start(); } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java index 53fbb929bb..76df25682e 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RemoteRpcProvider.java @@ -58,7 +58,7 @@ public class RemoteRpcProvider implements private ProviderSession brokerSession; private RpcProvisionRegistry rpcProvisionRegistry; private BundleContext context; - private ServiceTracker clusterTracker; + private ServiceTracker clusterTracker; public RemoteRpcProvider(ServerImpl server, ClientImpl client) { this.server = server; @@ -170,8 +170,8 @@ public class RemoteRpcProvider implements } - private RoutingTable getRoutingTable(){ - Optional> routingTable = + private RoutingTable, String> getRoutingTable(){ + Optional, String>> routingTable = routingTableProvider.getRoutingTable(); checkState(routingTable.isPresent(), "Routing table is null"); @@ -191,7 +191,7 @@ public class RemoteRpcProvider implements RouteIdentifierImpl routeId = new RouteIdentifierImpl(); routeId.setType(rpc); - RoutingTable routingTable = getRoutingTable(); + RoutingTable, String> routingTable = getRoutingTable(); try { routingTable.addGlobalRoute(routeId, server.getServerAddress()); @@ -212,7 +212,7 @@ public class RemoteRpcProvider implements RouteIdentifierImpl routeId = new RouteIdentifierImpl(); routeId.setType(rpc); - RoutingTable routingTable = getRoutingTable(); + RoutingTable, String> routingTable = getRoutingTable(); try { routingTable.removeGlobalRoute(routeId); @@ -245,9 +245,9 @@ public class RemoteRpcProvider implements * * @param announcements */ - private void announce(Set announcements) { + private void announce(Set> announcements) { _logger.debug("Announcing [{}]", announcements); - RoutingTable routingTable = getRoutingTable(); + RoutingTable, String> routingTable = getRoutingTable(); try { routingTable.addRoutes(announcements, server.getServerAddress()); } catch (RoutingTableException | SystemException e) { @@ -259,9 +259,9 @@ public class RemoteRpcProvider implements * * @param removals */ - private void remove(Set removals){ + private void remove(Set> removals){ _logger.debug("Removing [{}]", removals); - RoutingTable routingTable = getRoutingTable(); + RoutingTable, String> routingTable = getRoutingTable(); try { routingTable.removeRoutes(removals, server.getServerAddress()); } catch (RoutingTableException | SystemException e) { @@ -274,9 +274,9 @@ public class RemoteRpcProvider implements * @param changes * @return */ - private Set getRouteIdentifiers(Map> changes) { + private Set> getRouteIdentifiers(Map> changes) { RouteIdentifierImpl routeId = null; - Set routeIdSet = new HashSet(); + Set> routeIdSet = new HashSet<>(); for (RpcRoutingContext context : changes.keySet()){ routeId = new RouteIdentifierImpl(); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java index 71bab288e6..d960303fcf 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/RoutingTableProvider.java @@ -8,25 +8,24 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; import org.opendaylight.controller.sal.connector.api.RpcRouter; -import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener; import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable; -import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl; import org.opendaylight.controller.sal.connector.remoterpc.impl.RoutingTableImpl; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; +import com.google.common.base.Optional; + public class RoutingTableProvider implements AutoCloseable { @SuppressWarnings("rawtypes") final ServiceTracker tracker; - private RoutingTableImpl routingTableImpl = null; + private RoutingTableImpl routingTableImpl = null; //final private RouteChangeListener routeChangeListener; - - + + public RoutingTableProvider(BundleContext ctx){//,RouteChangeListener rcl) { @SuppressWarnings("rawtypes") ServiceTracker rawTracker = new ServiceTracker<>(ctx, RoutingTable.class, null); @@ -35,14 +34,14 @@ public class RoutingTableProvider implements AutoCloseable { //routeChangeListener = rcl; } - - public Optional> getRoutingTable() { + + public Optional, String>> getRoutingTable() { @SuppressWarnings("unchecked") - RoutingTable tracked = tracker.getService(); + RoutingTable, String> tracked = tracker.getService(); if(tracked instanceof RoutingTableImpl){ if(routingTableImpl != tracked){ - routingTableImpl= (RoutingTableImpl)tracked; + routingTableImpl= (RoutingTableImpl)tracked; //routingTableImpl.setRouteChangeListener(routeChangeListener); } } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java index d256b998d4..3acea356ce 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImpl.java @@ -7,48 +7,33 @@ */ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.common.collect.Sets; -import org.opendaylight.controller.md.sal.common.api.routing.RouteChange; -import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener; -import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable; -import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException; -import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException; -import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl; -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; -import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; -import org.opendaylight.controller.sal.core.api.RpcRegistrationListener; -import org.opendaylight.controller.sal.core.api.RpcRoutingContext; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.zeromq.ZMQ; - import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.yangtools.yang.common.QName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.zeromq.ZMQ; + +import com.google.common.base.Optional; +import com.google.common.base.Preconditions; /** * ZeroMq based implementation of RpcRouter. */ public class ServerImpl implements RemoteRpcServer { - private Logger _logger = LoggerFactory.getLogger(ServerImpl.class); + private final Logger _logger = LoggerFactory.getLogger(ServerImpl.class); private ExecutorService serverPool; protected ServerRequestHandler handler; @@ -63,7 +48,7 @@ public class ServerImpl implements RemoteRpcServer { private volatile State status = State.STOPPED; private String serverAddress; - private int port; + private final int port; public static enum State { STARTING, STARTED, STOPPED; @@ -167,7 +152,7 @@ public class ServerImpl implements RemoteRpcServer { */ private void closeZmqContext() { ExecutorService exec = Executors.newSingleThreadExecutor(); - FutureTask zmqTermination = new FutureTask(new Runnable() { + FutureTask zmqTermination = new FutureTask(new Runnable() { @Override public void run() { @@ -249,7 +234,7 @@ public class ServerImpl implements RemoteRpcServer { * @return */ private String findIpAddress() { - Enumeration e = null; + Enumeration e = null; try { e = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e1) { @@ -260,7 +245,7 @@ public class ServerImpl implements RemoteRpcServer { NetworkInterface n = (NetworkInterface) e.nextElement(); - Enumeration ee = n.getInetAddresses(); + Enumeration ee = n.getInetAddresses(); while (ee.hasMoreElements()) { InetAddress i = (InetAddress) ee.nextElement(); _logger.debug("Trying address {}", i); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandler.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandler.java index 2041f03afb..a25387d297 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandler.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandler.java @@ -8,38 +8,39 @@ package org.opendaylight.controller.sal.connector.remoterpc; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Future; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + import org.opendaylight.controller.sal.connector.api.RpcRouter; import org.opendaylight.controller.sal.connector.remoterpc.dto.Message; -import org.opendaylight.controller.sal.connector.remoterpc.dto.RouteIdentifierImpl; import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils; import org.opendaylight.controller.sal.core.api.Broker; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.zeromq.ZMQ; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Collection; -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicInteger; - /** * */ public class ServerRequestHandler implements AutoCloseable{ - private Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class); + private final Logger _logger = LoggerFactory.getLogger(ServerRequestHandler.class); private final String DEFAULT_NAME = "remote-rpc-worker"; - private String dealerAddress; - private String serverAddress; - private int workerCount; - private ZMQ.Context context; - private Broker.ProviderSession broker; + private final String dealerAddress; + private final String serverAddress; + private final int workerCount; + private final ZMQ.Context context; + private final Broker.ProviderSession broker; private RequestHandlerThreadPool workerPool; private final AtomicInteger threadId = new AtomicInteger(); @@ -87,7 +88,7 @@ public class ServerRequestHandler implements AutoCloseable{ * Worker to handles RPC request */ private class Worker implements Runnable { - private String name; + private final String name; public Worker(int id){ this.name = DEFAULT_NAME + "-" + id; @@ -187,7 +188,7 @@ public class ServerRequestHandler implements AutoCloseable{ } class MessageHandler{ - private ZMQ.Socket socket; + private final ZMQ.Socket socket; private Message message; //parsed message received on zmq server port private boolean messageForBroker = false; //if the message is valid and not a "ping" message @@ -236,7 +237,7 @@ public class ServerRequestHandler implements AutoCloseable{ CompositeNode payload = (result != null) ? result.getResult() : null; String recipient = null; - RpcRouter.RouteIdentifier routeId = null; + RpcRouter.RouteIdentifier routeId = null; if (message != null) { recipient = message.getSender(); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/Message.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/Message.java index 21d02be7d7..cbcfe3e2a9 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/Message.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/main/java/org/opendaylight/controller/sal/connector/remoterpc/dto/Message.java @@ -41,7 +41,7 @@ public class Message implements Serializable { private MessageType type; private String sender; private String recipient; - private RpcRouter.RouteIdentifier route; + private RpcRouter.RouteIdentifier route; private Object payload; public MessageType getType() { @@ -60,11 +60,11 @@ public class Message implements Serializable { this.sender = sender; } - public RpcRouter.RouteIdentifier getRoute() { + public RpcRouter.RouteIdentifier getRoute() { return route; } - public void setRoute(RpcRouter.RouteIdentifier route) { + public void setRoute(RpcRouter.RouteIdentifier route) { this.route = route; } @@ -123,7 +123,7 @@ public class Message implements Serializable { return o.readObject(); } - public static class Response extends Message implements RpcRouter.RpcReply { + public static class Response extends Message implements RpcRouter.RpcReply { private static final long serialVersionUID = 1L; private ResponseCode code; // response code @@ -173,7 +173,7 @@ public class Message implements Serializable { return this; } - public MessageBuilder route(RpcRouter.RouteIdentifier route){ + public MessageBuilder route(RpcRouter.RouteIdentifier route){ message.setRoute(route); return this; } diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java index 0fa12e351c..f8d14ce62e 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientImplTest.java @@ -40,8 +40,8 @@ public class ClientImplTest { //mock routing table routingTableProvider = mock(RoutingTableProvider.class); - RoutingTable mockRoutingTable = new MockRoutingTable(); - Optional> optionalRoutingTable = Optional.fromNullable(mockRoutingTable); + RoutingTable, String> mockRoutingTable = new MockRoutingTable(); + Optional, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable); when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable); //mock ClientRequestHandler diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientRequestHandlerTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientRequestHandlerTest.java index 1edd004d37..09188683cd 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientRequestHandlerTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ClientRequestHandlerTest.java @@ -99,7 +99,7 @@ public class ClientRequestHandlerTest { private Message handleMessageWithTimeout(final Message request) { Message response = null; - FutureTask task = new FutureTask(new Callable() { + FutureTask task = new FutureTask(new Callable() { @Override public Message call() { diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java index 0fe0155bb6..179051e4d4 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/MockRoutingTable.java @@ -7,16 +7,13 @@ */ package org.opendaylight.controller.sal.connector.remoterpc; -import org.opendaylight.controller.sal.connector.remoterpc.api.RouteChangeListener; +import java.util.HashSet; +import java.util.Set; + import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable; import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTableException; import org.opendaylight.controller.sal.connector.remoterpc.api.SystemException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - /** * Mock implementation of routing table */ @@ -59,7 +56,7 @@ public class MockRoutingTable implements RoutingTable { } @Override - public Set getRoutes(Object o) { + public Set getRoutes(Object o) { Set routes = new HashSet(); routes.add("localhost:5554"); return routes; diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java index 886ff426c7..7ffdf17ce7 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerImplTest.java @@ -8,28 +8,34 @@ package org.opendaylight.controller.sal.connector.remoterpc; -import com.google.common.base.Optional; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadPoolExecutor; + import junit.framework.Assert; -import org.junit.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.opendaylight.controller.sal.connector.api.RpcRouter; import org.opendaylight.controller.sal.connector.remoterpc.api.RoutingTable; import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil; import org.opendaylight.controller.sal.core.api.Broker; import org.opendaylight.controller.sal.core.api.RpcRegistrationListener; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.zeromq.ZMQ; + import zmq.Ctx; import zmq.SocketBase; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import com.google.common.base.Optional; public class ServerImplTest { @@ -68,12 +74,12 @@ public class ServerImplTest { server = new ServerImpl(port); server.setBrokerSession(brokerSession); - RoutingTable mockRoutingTable = new MockRoutingTable(); - Optional> optionalRoutingTable = Optional.fromNullable(mockRoutingTable); + RoutingTable, String> mockRoutingTable = new MockRoutingTable(); + Optional, String>> optionalRoutingTable = Optional.fromNullable(mockRoutingTable); when(routingTableProvider.getRoutingTable()).thenReturn(optionalRoutingTable); when(brokerSession.addRpcRegistrationListener(listener)).thenReturn(null); - when(brokerSession.getSupportedRpcs()).thenReturn(Collections.EMPTY_SET); + when(brokerSession.getSupportedRpcs()).thenReturn(Collections.emptySet()); when(brokerSession.rpc(null, mock(CompositeNode.class))).thenReturn(null); server.start(); Thread.sleep(5000);//wait for server to start @@ -178,7 +184,7 @@ public class ServerImplTest { Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); - List foundThreads = new ArrayList(); + List foundThreads = new ArrayList(); for (Thread t : threads) { if (t.getName().startsWith(name)) foundThreads.add(t); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandlerTest.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandlerTest.java index 6e39867e53..e5fbc761b4 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandlerTest.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/ServerRequestHandlerTest.java @@ -7,7 +7,15 @@ package org.opendaylight.controller.sal.connector.remoterpc; +import static org.mockito.Mockito.mock; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import junit.framework.Assert; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -15,22 +23,15 @@ import org.opendaylight.controller.sal.connector.remoterpc.utils.MessagingUtil; import org.opendaylight.controller.sal.core.api.Broker; import org.zeromq.ZMQ; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static org.mockito.Mockito.mock; - public class ServerRequestHandlerTest { ServerRequestHandler handler; ZMQ.Context context; ExecutorService executorService = Executors.newCachedThreadPool(); - private int workerCount = 2; - private String mockDealerAddress = "inproc://rpc-request-handler"; - private String mockServerIp = "localhost"; - private int mockServerPort = 5554; + private final int workerCount = 2; + private final String mockDealerAddress = "inproc://rpc-request-handler"; + private final String mockServerIp = "localhost"; + private final int mockServerPort = 5554; @Before public void setUp() throws Exception { @@ -98,7 +99,7 @@ public class ServerRequestHandlerTest { Thread[] threads = new Thread[Thread.activeCount()]; Thread.enumerate(threads); - List foundThreads = new ArrayList(); + List foundThreads = new ArrayList(); for (Thread t : threads) { if (t.getName().startsWith(name)) foundThreads.add(t); diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/MessagingUtil.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/MessagingUtil.java index a68ee574f3..883aa52f3f 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/MessagingUtil.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/MessagingUtil.java @@ -7,12 +7,6 @@ package org.opendaylight.controller.sal.connector.remoterpc.utils; -import junit.framework.Assert; -import org.opendaylight.controller.sal.connector.remoterpc.dto.Message; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.zeromq.ZMQ; - import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; @@ -21,6 +15,13 @@ import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; +import junit.framework.Assert; + +import org.opendaylight.controller.sal.connector.remoterpc.dto.Message; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.zeromq.ZMQ; + public class MessagingUtil { private static final Logger _logger = LoggerFactory.getLogger(MessagingUtil.class); @@ -160,7 +161,7 @@ public class MessagingUtil { if (context == null) return; ExecutorService exec = Executors.newSingleThreadExecutor(); - FutureTask zmqTermination = new FutureTask(new Runnable() { + FutureTask zmqTermination = new FutureTask(new Runnable() { @Override public void run() { diff --git a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/RemoteServerTestClient.java b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/RemoteServerTestClient.java index a71ab865aa..7a4f4a5974 100644 --- a/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/RemoteServerTestClient.java +++ b/opendaylight/md-sal/sal-remoterpc-connector/implementation/src/test/java/org/opendaylight/controller/sal/connector/remoterpc/utils/RemoteServerTestClient.java @@ -1,14 +1,14 @@ package org.opendaylight.controller.sal.connector.remoterpc.utils; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + import org.opendaylight.controller.sal.connector.api.RpcRouter; import org.opendaylight.controller.sal.connector.remoterpc.dto.Message; import org.opendaylight.controller.sal.connector.remoterpc.util.XmlUtils; import org.opendaylight.yangtools.yang.data.api.CompositeNode; import org.zeromq.ZMQ; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - public class RemoteServerTestClient { @@ -39,7 +39,7 @@ public class RemoteServerTestClient { } public Message createAddFlowMessage(String serverAddress ){ - RpcRouter.RouteIdentifier routeIdentifier = getAddFlowRpcIdentifier(); + RpcRouter.RouteIdentifier routeIdentifier = getAddFlowRpcIdentifier(); Message addFlow = new Message.MessageBuilder() .type(Message.MessageType.REQUEST) @@ -52,7 +52,7 @@ public class RemoteServerTestClient { return addFlow; } - private RpcRouter.RouteIdentifier getAddFlowRpcIdentifier(){ + private RpcRouter.RouteIdentifier getAddFlowRpcIdentifier(){ throw new UnsupportedOperationException(); }