From: Tony Tkacik Date: Fri, 30 May 2014 12:33:04 +0000 (+0000) Subject: Merge "Bug 1003: Restconf - remove whitespace on input" X-Git-Tag: autorelease-tag-v20140601202136_82eb3f9~3 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=da4cff5c3a5bc732fb046b563b886a7aaab67c30;hp=c3acce135d19955f72616c4c956668bb539f80f2 Merge "Bug 1003: Restconf - remove whitespace on input" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index e1e3164f71..c166f668cc 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -49,6 +49,7 @@ 0.5.2-SNAPSHOT 0.0.2-SNAPSHOT 7.0.42 + 0.2.0 0.4.2-SNAPSHOT 2.5.0 @@ -240,6 +241,11 @@ jackson-module-jaxb-annotations ${jackson.version} + + com.github.romix + java-concurrent-hash-trie-map + ${ctrie.version} + com.google.code.findbugs jsr305 @@ -255,6 +261,7 @@ guava ${guava.version} + com.sun.jersey jersey-client @@ -1413,6 +1420,11 @@ restconf-client-impl ${yangtools.version} + + org.opendaylight.yangtools + util + ${yangtools.version} + diff --git a/opendaylight/distribution/opendaylight/pom.xml b/opendaylight/distribution/opendaylight/pom.xml index 52aa6d276b..5b44bb7569 100644 --- a/opendaylight/distribution/opendaylight/pom.xml +++ b/opendaylight/distribution/opendaylight/pom.xml @@ -1145,6 +1145,10 @@ org.opendaylight.yangtools restconf-client-impl + + org.opendaylight.yangtools + util + org.opendaylight.yangtools diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.java new file mode 100644 index 0000000000..ba68d523af --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.java @@ -0,0 +1,239 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility; + +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.ProviderContext; +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.NodeIDType; +import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType; +import org.opendaylight.controller.sal.discovery.IDiscoveryService; +import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService; +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; +import org.opendaylight.controller.sal.topology.IPluginInTopologyService; +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.osgi.framework.BundleContext; + +import com.google.common.base.Preconditions; + +public class ComponentActivator extends ComponentActivatorAbstractBase { + private final INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory(); + private final DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter(); + private final InventoryAndReadAdapter inventory = new InventoryAndReadAdapter(); + private final FlowProgrammerAdapter flow = new FlowProgrammerAdapter(); + private final DataPacketAdapter dataPacket = new DataPacketAdapter(); + private final TopologyProvider tpProvider = new TopologyProvider(); + private final INodeFactory nodeFactory = new MDSalNodeFactory(); + private final TopologyAdapter topology = new TopologyAdapter(); + private BundleContext context; + + public INodeConnectorFactory getNodeConnectorFactory() { + return nodeConnectorFactory; + } + + public DataPacketServiceAdapter getDataPacketService() { + return dataPacketService; + } + + public InventoryAndReadAdapter getInventory() { + return inventory; + } + + public FlowProgrammerAdapter getFlow() { + return flow; + } + + public DataPacketAdapter getDataPacket() { + return dataPacket; + } + + public TopologyProvider getTpProvider() { + return tpProvider; + } + + public INodeFactory getNodeFactory() { + return nodeFactory; + } + + public TopologyAdapter getTopology() { + return topology; + } + + @Override + protected void init() { + NodeIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class); + NodeConnectorIDType.registerIDType(NodeMapping.MD_SAL_TYPE, String.class, NodeMapping.MD_SAL_TYPE); + } + + @Override + public void start(final BundleContext context) { + super.start(context); + this.context = Preconditions.checkNotNull(context); + } + + public ProviderContext setBroker(final BindingAwareBroker broker) { + return broker.registerProvider(new SalCompatibilityProvider(this), context); + } + + @Override + protected Object[] getGlobalImplementations() { + return new Object[] { + flow, + inventory, + dataPacket, + nodeFactory, + nodeConnectorFactory, + topology, + tpProvider, + this // Used for setBroker callback + }; + } + + @Override + protected void configureGlobalInstance(final Component c, final Object imp) { + if (imp instanceof DataPacketAdapter) { + _configure((DataPacketAdapter)imp, c); + } else if (imp instanceof FlowProgrammerAdapter) { + _configure((FlowProgrammerAdapter)imp, c); + } else if (imp instanceof InventoryAndReadAdapter) { + _configure((InventoryAndReadAdapter)imp, c); + } else if (imp instanceof ComponentActivator) { + _configure((ComponentActivator)imp, c); + } else if (imp instanceof MDSalNodeConnectorFactory) { + _configure((MDSalNodeConnectorFactory)imp, c); + } else if (imp instanceof MDSalNodeFactory) { + _configure((MDSalNodeFactory)imp, c); + } else if (imp instanceof TopologyAdapter) { + _configure((TopologyAdapter)imp, c); + } else if (imp instanceof TopologyProvider) { + _configure((TopologyProvider)imp, c); + } else { + throw new IllegalArgumentException(String.format("Unhandled implementation class %s", imp.getClass())); + } + } + + @Override + protected Object[] getImplementations() { + return new Object[] { + dataPacketService, + }; + } + + @Override + protected void configureInstance(final Component c, final Object imp, final String containerName) { + if (imp instanceof ComponentActivator) { + _instanceConfigure((ComponentActivator)imp, c, containerName); + } else if (imp instanceof DataPacketServiceAdapter) { + _instanceConfigure((DataPacketServiceAdapter)imp, c, containerName); + } else { + throw new IllegalArgumentException(String.format("Unhandled implementation class %s", imp.getClass())); + } + } + + private void _configure(final MDSalNodeFactory imp, final Component it) { + it.setInterface(INodeFactory.class.getName(), properties()); + } + + private void _configure(final MDSalNodeConnectorFactory imp, final Component it) { + it.setInterface(INodeConnectorFactory.class.getName(), properties()); + } + + private void _configure(final ComponentActivator imp, final Component it) { + it.add(createServiceDependency() + .setService(BindingAwareBroker.class) + .setCallbacks("setBroker", "setBroker") + .setRequired(true)); + } + + private void _configure(final DataPacketAdapter imp, final Component it) { + it.add(createServiceDependency() + .setService(IPluginOutDataPacketService.class) + .setCallbacks("setDataPacketPublisher", "setDataPacketPublisher") + .setRequired(false)); + } + + private void _configure(final FlowProgrammerAdapter imp, final Component it) { + it.setInterface(IPluginInFlowProgrammerService.class.getName(), properties()); + it.add(createServiceDependency() + .setService(IPluginOutFlowProgrammerService.class) + .setCallbacks("setFlowProgrammerPublisher", "setFlowProgrammerPublisher") + .setRequired(false)); + it.add(createServiceDependency() + .setService(IClusterGlobalServices.class) + .setCallbacks("setClusterGlobalServices", "unsetClusterGlobalServices") + .setRequired(false)); + } + + private void _instanceConfigure(final DataPacketServiceAdapter imp, final Component it, final String containerName) { + it.setInterface(IPluginInDataPacketService.class.getName(), properties()); + } + + private void _instanceConfigure(final ComponentActivator imp, final Component it, final String containerName) { + // No-op + } + + private void _configure(final InventoryAndReadAdapter imp, final Component it) { + it.setInterface(new String[] { + IPluginInInventoryService.class.getName(), + IPluginInReadService.class.getName(), + }, properties()); + + it.add(createServiceDependency() + .setService(IPluginOutReadService.class) + .setCallbacks("setReadPublisher", "unsetReadPublisher") + .setRequired(false)); + it.add(createServiceDependency() + .setService(IPluginOutInventoryService.class) + .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") + .setRequired(false)); + it.add(createServiceDependency() + .setService(IDiscoveryService.class) + .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") + .setRequired(false)); + } + + private void _configure(final TopologyAdapter imp, final Component it) { + it.setInterface(IPluginInTopologyService.class.getName(), properties()); + + it.add(createServiceDependency() + .setService(IPluginOutTopologyService.class) + .setCallbacks("setTopologyPublisher", "setTopologyPublisher") + .setRequired(false)); + } + + private void _configure(final TopologyProvider imp, final Component it) { + it.add(createServiceDependency() + .setService(IPluginOutTopologyService.class) + .setCallbacks("setTopologyPublisher", "setTopologyPublisher") + .setRequired(false)); + } + + private Dictionary properties() { + final Hashtable props = new Hashtable(); + props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), NodeMapping.MD_SAL_TYPE); + props.put("protocolName", NodeMapping.MD_SAL_TYPE); + return props; + } +} 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 deleted file mode 100644 index 57682bc6c9..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ComponentActivator.xtend +++ /dev/null @@ -1,258 +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.sal.compatibility - -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.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 -import org.opendaylight.controller.sal.discovery.IDiscoveryService -import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService -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 -import org.opendaylight.controller.sal.topology.IPluginInTopologyService -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.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -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.* - -class ComponentActivator extends ComponentActivatorAbstractBase { - - private BundleContext context; - - @Property - FlowProgrammerAdapter flow = new FlowProgrammerAdapter; - - @Property - InventoryAndReadAdapter inventory = new InventoryAndReadAdapter; - - @Property - DataPacketAdapter dataPacket = new DataPacketAdapter; - - @Property - INodeFactory nodeFactory = new MDSalNodeFactory - - @Property - INodeConnectorFactory nodeConnectorFactory = new MDSalNodeConnectorFactory - - @Property - TopologyAdapter topology = new TopologyAdapter - - @Property - TopologyProvider tpProvider = new TopologyProvider() - - @Property - DataPacketServiceAdapter dataPacketService = new DataPacketServiceAdapter() - - - - override protected init() { - Node.NodeIDType.registerIDType(MD_SAL_TYPE, String); - NodeConnector.NodeConnectorIDType.registerIDType(MD_SAL_TYPE, String, MD_SAL_TYPE); - } - - override start(BundleContext context) { - super.start(context) - this.context = context; - } - - def setBroker(BindingAwareBroker broker) { - broker.registerProvider(new SalCompatibilityProvider(this), context) - } - - - override protected getGlobalImplementations() { - return Arrays.asList(this, flow, inventory, dataPacket, nodeFactory, nodeConnectorFactory,topology,tpProvider) - } - - override protected configureGlobalInstance(Component c, Object imp) { - configure(imp, c); - } - - override protected getImplementations() { - return Arrays.asList(dataPacketService) - } - - override protected configureInstance(Component c, Object imp, String containerName) { - instanceConfigure(imp, c, containerName); - } - - private def dispatch configure(MDSalNodeFactory imp, Component it) { - setInterface(INodeFactory.name, properties); - } - - private def dispatch configure(MDSalNodeConnectorFactory imp, Component it) { - setInterface(INodeConnectorFactory.name, properties); - } - - private def dispatch configure(ComponentActivator imp, Component it) { - add( - createServiceDependency().setService(BindingAwareBroker) // - .setCallbacks("setBroker", "setBroker") // - .setRequired(true)) - - - } - - private def dispatch configure(DataPacketAdapter imp, Component it) { - add( - createServiceDependency() // - .setService(IPluginOutDataPacketService) // - .setCallbacks("setDataPacketPublisher", "setDataPacketPublisher") // - .setRequired(false)) - } - - private def dispatch configure(FlowProgrammerAdapter imp, Component it) { - setInterface(IPluginInFlowProgrammerService.name, properties) - add( - createServiceDependency() // - .setService(IPluginOutFlowProgrammerService) // - .setCallbacks("setFlowProgrammerPublisher", "setFlowProgrammerPublisher") // - .setRequired(false)) - - add( - createServiceDependency() // - .setService(IClusterGlobalServices) // - .setCallbacks("setClusterGlobalServices", "unsetClusterGlobalServices") // - .setRequired(false)) - - } - - private def dispatch instanceConfigure(DataPacketServiceAdapter imp, Component it, String containerName) { - setInterface(IPluginInDataPacketService.name, properties) - } - - private def dispatch instanceConfigure(ComponentActivator imp, Component it, String containerName) { - } - - - private def dispatch configure(InventoryAndReadAdapter imp, Component it) { - setInterface(Arrays.asList(IPluginInInventoryService.name, IPluginInReadService.name), properties) - add( - createServiceDependency() // - .setService(IPluginOutReadService) // - .setCallbacks("setReadPublisher", "unsetReadPublisher") // - .setRequired(false)) - add( - createServiceDependency() // - .setService(IPluginOutInventoryService) // - .setCallbacks("setInventoryPublisher", "unsetInventoryPublisher") // - .setRequired(false)) - add( - createServiceDependency() // - .setService(IDiscoveryService) // - .setCallbacks("setDiscoveryPublisher", "setDiscoveryPublisher") // - .setRequired(false)) - - - } - - private def dispatch configure (TopologyAdapter imp, Component it) { - setInterface(Arrays.asList(IPluginInTopologyService.name), properties) - add( - createServiceDependency() // - .setService(IPluginOutTopologyService) // - .setCallbacks("setTopologyPublisher", "setTopologyPublisher") // - .setRequired(false)) - } - - private def dispatch configure (TopologyProvider imp, Component it) { - add( - createServiceDependency() // - .setService(IPluginOutTopologyService) // - .setCallbacks("setTopologyPublisher", "setTopologyPublisher") // - .setRequired(false)) - } - - private def Dictionary properties() { - val props = new Hashtable(); - props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString, MD_SAL_TYPE) - props.put("protocolName", MD_SAL_TYPE); - return props; - } -} -package class SalCompatibilityProvider implements BindingAwareProvider { - - private val ComponentActivator activator; - - new(ComponentActivator cmpAct) { - activator = cmpAct; - } - - override getFunctionality() { - // Noop - } - - override getImplementations() { - // Noop - } - - - override onSessionInitialized(ConsumerContext session) { - // Noop - } - - - override onSessionInitiated(ProviderContext session) { - val it = activator - val subscribe = session.getSALService(NotificationService) - - // Registration of Flow Service - flow.delegate = session.getRpcService(SalFlowService) - flow.dataBrokerService = session.getSALService(DataBrokerService); - subscribe.registerNotificationListener(flow); - - // Data Packet Service - subscribe.registerNotificationListener(inventory); - dataPacketService.delegate = session.getRpcService(PacketProcessingService) - - // Inventory Service - inventory.dataService = session.getSALService(DataBrokerService); - inventory.flowStatisticsService = session.getRpcService(OpendaylightFlowStatisticsService); - inventory.flowTableStatisticsService = session.getRpcService(OpendaylightFlowTableStatisticsService); - inventory.nodeConnectorStatisticsService = session.getRpcService(OpendaylightPortStatisticsService); - inventory.topologyDiscovery = session.getRpcService(FlowTopologyDiscoveryService); - inventory.dataProviderService = session.getSALService(DataProviderService) - topology.dataService = session.getSALService(DataProviderService) - tpProvider.dataService = session.getSALService(DataProviderService) - - inventory.startAdapter(); - - tpProvider.startAdapter(); - - subscribe.registerNotificationListener(dataPacket) - } -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.java new file mode 100644 index 0000000000..4d26a3a095 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility; + +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService; +import org.opendaylight.controller.sal.packet.RawPacket; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class DataPacketAdapter implements PacketProcessingListener { + private static final Logger LOG = LoggerFactory.getLogger(DataPacketAdapter.class); + + // These are injected via Apache DM (see ComponentActivator) + private IPluginOutDataPacketService dataPacketPublisher; + + @Override + public void onPacketReceived(final PacketReceived packet) { + try { + RawPacket inPacket = toRawPacket(packet); + if (dataPacketPublisher != null) { + dataPacketPublisher.receiveDataPacket(inPacket); + } else { + LOG.warn("IPluginOutDataPacketService is not available. Not forwarding packet to AD-SAL."); + } + } catch (ConstructionException e) { + LOG.warn("Failed to construct raw packet from {}, dropping it", packet, e); + } + } + + public static RawPacket toRawPacket(final PacketReceived received) throws ConstructionException { + final RawPacket ret = new RawPacket(received.getPayload()); + ret.setIncomingNodeConnector(NodeMapping.toADNodeConnector(received.getIngress())); + return ret; + } + + public IPluginOutDataPacketService getDataPacketPublisher() { + return dataPacketPublisher; + } + + // These are injected via Apache DM (see ComponentActivator) + public void setDataPacketPublisher(final IPluginOutDataPacketService dataPacketPublisher) { + this.dataPacketPublisher = dataPacketPublisher; + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.xtend deleted file mode 100644 index 8581d4a9da..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/DataPacketAdapter.xtend +++ /dev/null @@ -1,31 +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.sal.compatibility - -import org.opendaylight.controller.sal.packet.IPluginOutDataPacketService -import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived -import org.opendaylight.controller.sal.packet.RawPacket - -class DataPacketAdapter implements PacketProcessingListener { - - @Property - IPluginOutDataPacketService dataPacketPublisher; - - override onPacketReceived(PacketReceived packet) { - val RawPacket inPacket = packet.toRawPacket(); - dataPacketPublisher.receiveDataPacket(inPacket); - } - - public static def RawPacket toRawPacket(PacketReceived received) { - val ret = new RawPacket(received.payload); - ret.setIncomingNodeConnector(NodeMapping.toADNodeConnector(received.ingress)) - return ret; - } - -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.java new file mode 100644 index 0000000000..e5a9d3e5db --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.java @@ -0,0 +1,302 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility; + +import java.util.EnumSet; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.IClusterGlobalServices; +import org.opendaylight.controller.clustering.services.IClusterServices.cacheMode; +import org.opendaylight.controller.md.sal.common.api.TransactionStatus; +import org.opendaylight.controller.sal.binding.api.data.DataBrokerService; +import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction; +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.flowprogrammer.Flow; +import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService; +import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService; +import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener { + private final static Logger LOG = LoggerFactory.getLogger(FlowProgrammerAdapter.class); + + // Note: clustering services manipulate this + private final Map flowToFlowId = new ConcurrentHashMap(); + private final static String CACHE_NAME = "flowprogrammeradapter.flowtoid"; + + // These are injected via Apache DM (see ComponentActivator) + private IPluginOutFlowProgrammerService flowProgrammerPublisher; + private IClusterGlobalServices clusterGlobalServices; + private DataBrokerService dataBrokerService; + private SalFlowService delegate; + + public SalFlowService getDelegate() { + return this.delegate; + } + + public void setDelegate(final SalFlowService delegate) { + this.delegate = delegate; + } + + public DataBrokerService getDataBrokerService() { + return this.dataBrokerService; + } + + public void setDataBrokerService(final DataBrokerService dataBrokerService) { + this.dataBrokerService = dataBrokerService; + } + + public IPluginOutFlowProgrammerService getFlowProgrammerPublisher() { + return this.flowProgrammerPublisher; + } + + public void setFlowProgrammerPublisher(final IPluginOutFlowProgrammerService flowProgrammerPublisher) { + this.flowProgrammerPublisher = flowProgrammerPublisher; + } + + public IClusterGlobalServices getClusterGlobalServices() { + return this.clusterGlobalServices; + } + + public void setClusterGlobalServices(final IClusterGlobalServices clusterGlobalServices) { + this.clusterGlobalServices = clusterGlobalServices; + } + + @Override + public Status addFlow(final Node node, final Flow flow) { + return toFutureStatus(internalAddFlowAsync(node, flow, 0)); + } + + @Override + public Status modifyFlow(final Node node, final Flow oldFlow, final Flow newFlow) { + return toFutureStatus(internalModifyFlowAsync(node, oldFlow, newFlow, 0)); + } + + @Override + public Status removeFlow(final Node node, final Flow flow) { + return toFutureStatus(internalRemoveFlowAsync(node, flow, 0)); + } + + @Override + public Status addFlowAsync(final Node node, final Flow flow, final long rid) { + // FIXME is this correct? What if the future fails? + this.internalAddFlowAsync(node, flow, rid); + return FlowProgrammerAdapter.toStatus(true); + } + + @Override + public Status modifyFlowAsync(final Node node, final Flow oldFlow, final Flow newFlow, final long rid) { + // FIXME is this correct? What if the future fails? + this.internalModifyFlowAsync(node, oldFlow, newFlow, rid); + return FlowProgrammerAdapter.toStatus(true); + } + + @Override + public Status removeFlowAsync(final Node node, final Flow flow, final long rid) { + // FIXME is this correct? What if the future fails? + this.internalRemoveFlowAsync(node, flow, rid); + return FlowProgrammerAdapter.toStatus(true); + } + + @Override + public Status removeAllFlows(final Node node) { + // FIXME: unfinished? + return new Status(StatusCode.SUCCESS); + } + + @Override + public Status syncSendBarrierMessage(final Node node) { + // FIXME: unfinished? + return null; + } + + @Override + public Status asyncSendBarrierMessage(final Node node) { + // FIXME: unfinished? + return null; + } + + private static Status toStatus(final boolean successful) { + return new Status(successful ? StatusCode.SUCCESS : StatusCode.INTERNALERROR); + } + + public static Status toStatus(final RpcResult result) { + return toStatus(result.isSuccessful()); + } + + @Override + public void onFlowAdded(final FlowAdded notification) { + // FIXME: unfinished? + } + + @Override + public void onFlowRemoved(final FlowRemoved notification) { + if (notification == null) { + return; + } + + final NodeRef node = notification.getNode(); + if (node == null) { + LOG.debug("Notification {} has not node, ignoring it", notification); + return; + } + + Node adNode; + try { + adNode = NodeMapping.toADNode(notification.getNode()); + } catch (ConstructionException e) { + LOG.warn("Failed to construct AD node for {}, ignoring notification", node, e); + return; + } + flowProgrammerPublisher.flowRemoved(adNode, ToSalConversionsUtils.toFlow(notification, adNode)); + } + + @Override + public void onFlowUpdated(final FlowUpdated notification) { + // FIXME: unfinished? + } + + @Override + public void onSwitchFlowRemoved(final SwitchFlowRemoved notification) { + // FIXME: unfinished? + } + + @Override + public void onNodeErrorNotification(final NodeErrorNotification notification) { + // FIXME: unfinished? + } + + @Override + public void onNodeExperimenterErrorNotification(final NodeExperimenterErrorNotification notification) { + // FIXME: unfinished? + } + + private static final InstanceIdentifier flowPath( + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, final NodeKey nodeKey) { + return InstanceIdentifier.builder(Nodes.class) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, nodeKey) + .augmentation(FlowCapableNode.class) + .child(Table.class, new TableKey(flow.getTableId())) + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow.class, new FlowKey(flow.getId())) + .toInstance(); + } + + private Future> writeFlowAsync(final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, final NodeKey nodeKey) { + final DataModificationTransaction modification = this.dataBrokerService.beginTransaction(); + modification.putConfigurationData(flowPath(flow, nodeKey), flow); + return modification.commit(); + } + + private Future> internalAddFlowAsync(final Node node, final Flow flow, final long rid) { + final Map cache = this.getCache(); + UUID flowId = cache.get(flow); + if (flowId != null) { + this.removeFlow(node, flow); + } + + flowId = UUID.randomUUID(); + cache.put(flow, flowId); + return this.writeFlowAsync(MDFlowMapping.toMDFlow(flow, flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString()))); + } + + private Future> internalModifyFlowAsync(final Node node, final Flow oldFlow, final Flow newFlow, final long rid) { + final Map cache = this.getCache(); + + UUID flowId = cache.remove(oldFlow); + if (flowId == null) { + flowId = UUID.randomUUID(); + cache.put(oldFlow, flowId); + LOG.warn("Could not find flow {} in cache, assigned new ID {}", oldFlow.hashCode(), flowId); + } + + cache.put(newFlow, flowId); + return this.writeFlowAsync(MDFlowMapping.toMDFlow(newFlow, flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString()))); + } + + private Future> internalRemoveFlowAsync(final Node node, final Flow adflow, final long rid) { + final Map cache = this.getCache(); + + final UUID flowId = cache.remove(adflow); + if (flowId == null) { + LOG.warn("Could not find flow {} in cache, nothing to do", adflow.hashCode()); + return null; + } + + final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow = MDFlowMapping.toMDFlow(adflow, flowId.toString()); + final DataModificationTransaction modification = this.dataBrokerService.beginTransaction(); + modification.removeConfigurationData(flowPath(flow, new NodeKey(new NodeId(node.getNodeIDString())))); + return modification.commit(); + } + + private static Status toFutureStatus(final Future> future) { + if (future == null) { + // FIXME: really? + return FlowProgrammerAdapter.toStatus(true); + } + + try { + final RpcResult result = future.get(); + return FlowProgrammerAdapter.toStatus(result); + } catch (final InterruptedException e) { + FlowProgrammerAdapter.LOG.error("Interrupted while processing flow", e); + } catch (ExecutionException e) { + FlowProgrammerAdapter.LOG.error("Failed to process flow", e); + } + + return new Status(StatusCode.INTERNALERROR); + } + + @SuppressWarnings("unchecked") + private Map getCache() { + final IClusterGlobalServices cgs = getClusterGlobalServices(); + if (cgs == null) { + return new ConcurrentHashMap(); + } + + Map cache = (Map) cgs.getCache(FlowProgrammerAdapter.CACHE_NAME); + if (cache != null) { + return cache; + } + + try { + return (Map) cgs.createCache(CACHE_NAME, EnumSet.of(cacheMode.TRANSACTIONAL)); + } catch (CacheExistException e) { + return (Map) cgs.getCache(CACHE_NAME); + } catch (CacheConfigException e) { + throw new IllegalStateException("Unexpected cache configuration problem", e); + } + } + +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend deleted file mode 100644 index 8a0874ee31..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend +++ /dev/null @@ -1,269 +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.sal.compatibility - -import java.util.Map -import java.util.UUID -import java.util.concurrent.ExecutionException -import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.Future -import java.util.EnumSet -import org.opendaylight.controller.sal.core.Node -import org.opendaylight.controller.sal.flowprogrammer.Flow -import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService -import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService -import org.opendaylight.controller.sal.utils.Status -import org.opendaylight.controller.sal.utils.StatusCode -import org.opendaylight.controller.clustering.services.CacheExistException -import org.opendaylight.controller.clustering.services.IClusterGlobalServices -import org.opendaylight.controller.clustering.services.IClusterServices - -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification -import org.opendaylight.yangtools.yang.common.RpcResult -import org.slf4j.LoggerFactory - -import org.opendaylight.controller.sal.binding.api.data.DataBrokerService -import org.opendaylight.controller.md.sal.common.api.TransactionStatus -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId - - -import static extension org.opendaylight.controller.sal.compatibility.MDFlowMapping.* - -import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* -import static extension org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils.* - -class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowListener { - - private static val LOG = LoggerFactory.getLogger(FlowProgrammerAdapter); - private static val CACHE_NAME = "flowprogrammeradapter.flowtoid"; - - @Property - private SalFlowService delegate; - - @Property - private DataBrokerService dataBrokerService; - - @Property - private IPluginOutFlowProgrammerService flowProgrammerPublisher; - - @Property - private IClusterGlobalServices clusterGlobalServices; - - - @Property - private Map flowToFlowId = new ConcurrentHashMap(); - - - override addFlow(Node node, Flow flow) { - return toFutureStatus(internalAddFlowAsync(node,flow,0)); - } - - override modifyFlow(Node node, Flow oldFlow, Flow newFlow) { - return toFutureStatus(internalModifyFlowAsync(node, oldFlow,newFlow,0)); - } - - override removeFlow(Node node, Flow flow) { - return toFutureStatus(internalRemoveFlowAsync(node, flow,0)); - } - - override addFlowAsync(Node node, Flow flow, long rid) { - internalAddFlowAsync(node, flow, rid); - return toStatus(true); - } - - override modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) { - internalModifyFlowAsync(node, oldFlow, newFlow, rid); - return toStatus(true); - } - - override removeFlowAsync(Node node, Flow flow, long rid) { - internalRemoveFlowAsync(node, flow, rid); - return toStatus(true); - } - - override removeAllFlows(Node node) { - // I know this looks like a copout... but its exactly what the legacy OFplugin did - return new Status(StatusCode.SUCCESS); - } - - override syncSendBarrierMessage(Node node) { - - // FIXME: Update YANG model - return null; - } - - override asyncSendBarrierMessage(Node node) { - - // FIXME: Update YANG model - return null; - } - - private static def toStatus(boolean successful) { - if (successful) { - return new Status(StatusCode.SUCCESS); - } else { - return new Status(StatusCode.INTERNALERROR); - } - } - - public static def toStatus(RpcResult result) { - return toStatus(result.isSuccessful()); - } - - private static dispatch def Status processException(InterruptedException e) { - LOG.error("Interruption occured during processing flow",e); - return new Status(StatusCode.INTERNALERROR); - } - - private static dispatch def Status processException(ExecutionException e) { - LOG.error("Execution exception occured during processing flow",e.cause); - return new Status(StatusCode.INTERNALERROR); - } - - private static dispatch def Status processException(Exception e) { - throw new RuntimeException(e); - } - - override onFlowAdded(FlowAdded notification) { - // NOOP : Not supported by AD SAL - } - - override onFlowRemoved(FlowRemoved notification) { - if(notification != null && notification.node != null) { - val adNode = notification.node.toADNode - if(adNode != null) { - flowProgrammerPublisher.flowRemoved(adNode,notification.toFlow(adNode)); - } - } - } - - override onFlowUpdated(FlowUpdated notification) { - // NOOP : Not supported by AD SAL - } - - override onSwitchFlowRemoved(SwitchFlowRemoved notification) { - // NOOP : Not supported by AD SAL - } - - override onNodeErrorNotification(NodeErrorNotification notification) { - // NOOP : Not supported by AD SAL - } - - override onNodeExperimenterErrorNotification( - NodeExperimenterErrorNotification notification) { - // NOOP : Not supported by AD SAL - } - - private def Future> writeFlowAsync(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey){ - val modification = this._dataBrokerService.beginTransaction(); - val flowPath = InstanceIdentifier.builder(Nodes) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey) - .augmentation(FlowCapableNode) - .child(Table, new TableKey(flow.getTableId())) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id)) - .build; - modification.putConfigurationData(flowPath, flow); - return modification.commit(); - } - - private def Future> internalAddFlowAsync(Node node, Flow flow, long rid){ - var flowId = getCache().get(flow); - if(flowId != null) { - removeFlow(node, flow); - return internalAddFlowAsync(node, flow, rid); - } - - flowId = UUID.randomUUID(); - getCache().put(flow, flowId); - - return writeFlowAsync(flow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString()))); - } - - private def Future> internalModifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) { - var flowId = getCache().remove(oldFlow); - if(flowId == null){ - LOG.error("oldFlow not found in cache : " + oldFlow.hashCode); - flowId = UUID.randomUUID(); - getCache().put(oldFlow, flowId); - } - - getCache().put(newFlow, flowId); - return writeFlowAsync(newFlow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString()))); - } - - - private def Future> internalRemoveFlowAsync(Node node, Flow adflow, long rid){ - val flowId = getCache().remove(adflow); - if(flowId == null){ - //throw new IllegalArgumentException("adflow not found in cache : " + adflow.hashCode); - LOG.error("adflow not found in cache : " + adflow.hashCode); - return null; - } - val flow = adflow.toMDFlow(flowId.toString()); - val modification = this._dataBrokerService.beginTransaction(); - val flowPath = InstanceIdentifier.builder(Nodes) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString()))) - .augmentation(FlowCapableNode) - .child(Table, new TableKey(flow.getTableId())) - .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id)) - .build; - modification.removeConfigurationData(flowPath); - return modification.commit(); - } - - private def toFutureStatus(Future> future){ - if(future == null){ - return toStatus(true); - } - - try { - val result = future.get(); - return toStatus(result); - } catch (InterruptedException e) { - return processException(e); - } catch (ExecutionException e) { - return processException(e); - } catch (Exception e){ - processException(e); - } - return toStatus(false); - } - - private def Map getCache(){ - if(clusterGlobalServices == null){ - return new ConcurrentHashMap(); - } - - var cache = clusterGlobalServices.getCache(CACHE_NAME); - - if(cache == null) { - try { - cache = clusterGlobalServices.createCache(CACHE_NAME, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL)); - } catch (CacheExistException e) { - cache = clusterGlobalServices.getCache(CACHE_NAME); - } - } - return cache as Map; - - } - -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.java new file mode 100644 index 0000000000..e989db4d10 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.java @@ -0,0 +1,445 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility; + +import java.math.BigInteger; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.opendaylight.controller.sal.action.Action; +import org.opendaylight.controller.sal.action.Controller; +import org.opendaylight.controller.sal.action.Drop; +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.Output; +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.core.Node; +import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.controller.sal.flowprogrammer.Flow; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder; +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.FloodActionCaseBuilder; +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.FloodAllActionCaseBuilder; +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.HwPathActionCaseBuilder; +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.LoopbackActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder; +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.PopVlanActionCaseBuilder; +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.PushVlanActionCaseBuilder; +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.SetDlDstActionCaseBuilder; +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.SetDlSrcActionCaseBuilder; +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.SetDlTypeActionCaseBuilder; +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.SetNextHopActionCaseBuilder; +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.SetNwDstActionCaseBuilder; +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.SetNwSrcActionCaseBuilder; +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.SetNwTosActionCaseBuilder; +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.SetTpDstActionCaseBuilder; +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.SetTpSrcActionCaseBuilder; +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.SetVlanCfiActionCaseBuilder; +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.SetVlanIdActionCaseBuilder; +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.SetVlanPcpActionCaseBuilder; +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.action.action.SwPathActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.controller.action._case.ControllerActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.action._case.FloodActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.all.action._case.FloodAllActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.hw.path.action._case.HwPathActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.loopback.action._case.LoopbackActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.type.action._case.SetDlTypeActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.next.hop.action._case.SetNextHopActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.dst.action._case.SetTpDstActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.src.action._case.SetTpSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.cfi.action._case.SetVlanCfiActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.pcp.action._case.SetVlanPcpActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.sw.path.action._case.SwPathActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; +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.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp; + +import com.google.common.base.Preconditions; +import com.google.common.net.InetAddresses; + +public final class MDFlowMapping { + private MDFlowMapping() { + throw new UnsupportedOperationException("Utility class"); + } + + private static List toMDActions(final List actions) { + final ArrayList ret = + new ArrayList(actions.size()); + int action = 0; + for (final Action sourceAction : actions) { + ret.add(toAction(sourceAction, action)); + action++; + } + + return ret; + } + + public static FlowAdded flowAdded(final Flow sourceFlow) { + Preconditions.checkArgument(sourceFlow != null); + + return new FlowAddedBuilder() + .setHardTimeout(Integer.valueOf(sourceFlow.getHardTimeout())) + .setIdleTimeout(Integer.valueOf(sourceFlow.getIdleTimeout())) + .setCookie(new FlowCookie(BigInteger.valueOf(sourceFlow.getId()))) + .setPriority(Integer.valueOf(sourceFlow.getPriority())) + .setInstructions(MDFlowMapping.toApplyInstruction(toMDActions(sourceFlow.getActions()))) + .setMatch(FromSalConversionsUtils.toMatch(sourceFlow.getMatch())) + .setTableId((short)0) + .build(); + } + + private static FlowBuilder internalToMDFlow(final Flow sourceFlow) { + Preconditions.checkArgument(sourceFlow != null); + + return new FlowBuilder() + .setHardTimeout(Integer.valueOf(sourceFlow.getHardTimeout())) + .setIdleTimeout(Integer.valueOf(sourceFlow.getIdleTimeout())) + .setCookie(new FlowCookie(BigInteger.valueOf(sourceFlow.getId()))) + .setPriority(Integer.valueOf((sourceFlow.getPriority()))) + .setInstructions(MDFlowMapping.toApplyInstruction(toMDActions(sourceFlow.getActions()))) + .setMatch(FromSalConversionsUtils.toMatch(sourceFlow.getMatch())); + } + + public static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow toMDFlow(final Flow sourceFlow, final String flowId) { + return internalToMDFlow(sourceFlow) + .setTableId((short)0) + .setId(new FlowId(flowId)) + .build(); + } + + public static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow toMDSalflow(final Flow sourceFlow) { + return internalToMDFlow(sourceFlow).build(); + } + + public static Instructions toApplyInstruction(final List actions) { + return new InstructionsBuilder() + .setInstruction( + Collections.singletonList( + new InstructionBuilder() + .setOrder(0) + .setInstruction( + new ApplyActionsCaseBuilder() + .setApplyActions(new ApplyActionsBuilder().setAction(actions).build()) + .build() + ).build()) + ).build(); + } + + public static RemoveFlowInput removeFlowInput(final Node sourceNode, final Flow sourceFlow) { + final FlowAdded source = MDFlowMapping.flowAdded(sourceFlow); + return new RemoveFlowInputBuilder((org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) source) + .setNode(NodeMapping.toNodeRef(sourceNode)) + .build(); + } + + public static AddFlowInput addFlowInput(final Node sourceNode, final Flow sourceFlow) { + final FlowAdded source = MDFlowMapping.flowAdded(sourceFlow); + return new AddFlowInputBuilder(((org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow) source)) + .setNode(NodeMapping.toNodeRef(sourceNode)) + .build(); + } + + public static UpdateFlowInput updateFlowInput(final Node sourceNode, final Flow oldFlow, final Flow newFlow) { + return new UpdateFlowInputBuilder() + .setOriginalFlow(new OriginalFlowBuilder(MDFlowMapping.flowAdded(newFlow)).build()) + .setUpdatedFlow(new UpdatedFlowBuilder(MDFlowMapping.flowAdded(newFlow)).build()) + .setNode(NodeMapping.toNodeRef(sourceNode)) + .build(); + } + + private static ControllerActionCase _toAction(final Controller sourceAction) { + return new ControllerActionCaseBuilder().setControllerAction(new ControllerActionBuilder().build()).build(); + } + + private static DropActionCase _toAction(final Drop sourceAction) { + return new DropActionCaseBuilder().setDropAction(new DropActionBuilder().build()).build(); + } + + private static FloodActionCase _toAction(final Flood sourceAction) { + return new FloodActionCaseBuilder().setFloodAction(new FloodActionBuilder().build()).build(); + } + + private static FloodAllActionCase _toAction(final FloodAll sourceAction) { + return new FloodAllActionCaseBuilder().setFloodAllAction(new FloodAllActionBuilder().build()).build(); + } + + private static HwPathActionCase _toAction(final HwPath sourceAction) { + return new HwPathActionCaseBuilder().setHwPathAction(new HwPathActionBuilder().build()).build(); + } + + private static LoopbackActionCase _toAction(final Loopback sourceAction) { + return new LoopbackActionCaseBuilder().setLoopbackAction( new LoopbackActionBuilder().build()).build(); + } + + private static OutputActionCase _toAction(final Output sourceAction) { + return new OutputActionCaseBuilder() + .setOutputAction( + new OutputActionBuilder().setOutputNodeConnector(MDFlowMapping.toUri(sourceAction.getPort())).build() + ).build(); + } + + private static PopVlanActionCase _toAction(final PopVlan sourceAction) { + return new PopVlanActionCaseBuilder().build(); + } + + private static PushVlanActionCase _toAction(final PushVlan sourceAction) { + return new PushVlanActionCaseBuilder() + .setPushVlanAction( + new PushVlanActionBuilder() + .setCfi(new VlanCfi(sourceAction.getCfi())) + .setPcp(sourceAction.getPcp()) + .setTag(sourceAction.getTag()) + .setVlanId(new VlanId(sourceAction.getVlanId())) + .build() + ).build(); + } + + private static SetDlDstActionCase _toAction(final SetDlDst sourceAction) { + return new SetDlDstActionCaseBuilder() + .setSetDlDstAction(new SetDlDstActionBuilder().setAddress(MDFlowMapping.toMacAddress(sourceAction.getDlAddress())).build()) + .build(); + } + + private static SetDlSrcActionCase _toAction(final SetDlSrc sourceAction) { + return new SetDlSrcActionCaseBuilder() + .setSetDlSrcAction(new SetDlSrcActionBuilder().setAddress(MDFlowMapping.toMacAddress(sourceAction.getDlAddress())).build()) + .build(); + } + + private static SetDlTypeActionCase _toAction(final SetDlType sourceAction) { + return new SetDlTypeActionCaseBuilder() + .setSetDlTypeAction(new SetDlTypeActionBuilder().setDlType(new EtherType(Long.valueOf(sourceAction.getDlType()))).build()) + .build(); + } + + private static SetNextHopActionCase _toAction(final SetNextHop sourceAction) { + return new SetNextHopActionCaseBuilder() + .setSetNextHopAction(new SetNextHopActionBuilder().setAddress(MDFlowMapping.toInetAddress(sourceAction.getAddress())).build()) + .build(); + } + + private static SetNwDstActionCase _toAction(final SetNwDst sourceAction) { + return new SetNwDstActionCaseBuilder() + .setSetNwDstAction(new SetNwDstActionBuilder().setAddress(MDFlowMapping.toInetAddress(sourceAction.getAddress())).build()) + .build(); + } + + private static SetNwSrcActionCase _toAction(final SetNwSrc sourceAction) { + return new SetNwSrcActionCaseBuilder() + .setSetNwSrcAction(new SetNwSrcActionBuilder().setAddress(MDFlowMapping.toInetAddress(sourceAction.getAddress())).build()) + .build(); + } + + private static SetNwTosActionCase _toAction(final SetNwTos sourceAction) { + return new SetNwTosActionCaseBuilder() + .setSetNwTosAction(new SetNwTosActionBuilder().setTos(sourceAction.getNwTos()).build()) + .build(); + } + + private static SetTpDstActionCase _toAction(final SetTpDst sourceAction) { + return new SetTpDstActionCaseBuilder() + .setSetTpDstAction(new SetTpDstActionBuilder().setPort(new PortNumber(sourceAction.getPort())).build()) + .build(); + } + + private static SetTpSrcActionCase _toAction(final SetTpSrc sourceAction) { + return new SetTpSrcActionCaseBuilder() + .setSetTpSrcAction(new SetTpSrcActionBuilder().setPort(new PortNumber(sourceAction.getPort())).build()) + .build(); + } + + private static SetVlanCfiActionCase _toAction(final SetVlanCfi sourceAction) { + return new SetVlanCfiActionCaseBuilder() + .setSetVlanCfiAction(new SetVlanCfiActionBuilder().setVlanCfi(new VlanCfi(sourceAction.getCfi())).build()) + .build(); + } + + private static SetVlanIdActionCase _toAction(final SetVlanId sourceAction) { + return new SetVlanIdActionCaseBuilder() + .setSetVlanIdAction(new SetVlanIdActionBuilder().setVlanId(new VlanId(sourceAction.getVlanId())).build()) + .build(); + } + + private static SetVlanPcpActionCase _toAction(final SetVlanPcp sourceAction) { + return new SetVlanPcpActionCaseBuilder() + .setSetVlanPcpAction(new SetVlanPcpActionBuilder().setVlanPcp(new VlanPcp((short) sourceAction.getPcp())).build()) + .build(); + } + + private static SwPathActionCase _toAction(final SwPath sourceAction) { + return new SwPathActionCaseBuilder().setSwPathAction(new SwPathActionBuilder().build()).build(); + } + + public static Uri toUri(final NodeConnector connector) { + return new NodeConnectorId(((String) connector.getID())); + } + + public static MacAddress toMacAddress(final byte[] bytes) { + final StringBuilder sb = new StringBuilder(18); + boolean first = true; + + for (final byte b : bytes) { + if (first) { + first = false; + } else { + sb.append(':'); + } + sb.append(String.format("%02x", Byte.valueOf(b))); + } + return new MacAddress(sb.toString()); + } + + public static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action toAction(final Action sourceAction, final int order) { + final ActionBuilder ret = new ActionBuilder().setOrder(order); + + if (sourceAction instanceof Controller) { + ret.setAction(_toAction((Controller)sourceAction)); + } else if (sourceAction instanceof Drop) { + ret.setAction(_toAction((Drop)sourceAction)); + } else if (sourceAction instanceof Flood) { + ret.setAction(_toAction((Flood)sourceAction)); + } else if (sourceAction instanceof FloodAll) { + ret.setAction(_toAction((FloodAll)sourceAction)); + } else if (sourceAction instanceof HwPath) { + ret.setAction(_toAction((HwPath)sourceAction)); + } else if (sourceAction instanceof Loopback) { + ret.setAction(_toAction((Loopback)sourceAction)); + } else if (sourceAction instanceof Output) { + ret.setAction(_toAction((Output)sourceAction)); + } else if (sourceAction instanceof PopVlan) { + ret.setAction(_toAction((PopVlan)sourceAction)); + } else if (sourceAction instanceof PushVlan) { + ret.setAction(_toAction((PushVlan)sourceAction)); + } else if (sourceAction instanceof SetDlDst) { + ret.setAction(_toAction((SetDlDst)sourceAction)); + } else if (sourceAction instanceof SetDlSrc) { + ret.setAction(_toAction((SetDlSrc)sourceAction)); + } else if (sourceAction instanceof SetDlType) { + ret.setAction(_toAction((SetDlType)sourceAction)); + } else if (sourceAction instanceof SetNextHop) { + ret.setAction(_toAction((SetNextHop)sourceAction)); + } else if (sourceAction instanceof SetNwDst) { + ret.setAction(_toAction((SetNwDst)sourceAction)); + } else if (sourceAction instanceof SetNwSrc) { + ret.setAction(_toAction((SetNwSrc)sourceAction)); + } else if (sourceAction instanceof SetNwTos) { + ret.setAction(_toAction((SetNwTos)sourceAction)); + } else if (sourceAction instanceof SetTpDst) { + ret.setAction(_toAction((SetTpDst)sourceAction)); + } else if (sourceAction instanceof SetTpSrc) { + ret.setAction(_toAction((SetTpSrc)sourceAction)); + } else if (sourceAction instanceof SetVlanCfi) { + ret.setAction(_toAction((SetVlanCfi)sourceAction)); + } else if (sourceAction instanceof SetVlanId) { + ret.setAction(_toAction((SetVlanId)sourceAction)); + } else if (sourceAction instanceof SetVlanPcp) { + ret.setAction(_toAction((SetVlanPcp)sourceAction)); + } else if (sourceAction instanceof SwPath) { + ret.setAction(_toAction((SwPath)sourceAction)); + } else { + throw new IllegalArgumentException(String.format("Unhandled action class %s", sourceAction.getClass())); + } + + return ret.build(); + } + + public static Address toInetAddress(final InetAddress address) { + if (address instanceof Inet4Address) { + return new Ipv4Builder() + .setIpv4Address(new Ipv4Prefix(InetAddresses.toAddrString(address))) + .build(); + } + if (address instanceof Inet6Address) { + return new Ipv6Builder() + .setIpv6Address(new Ipv6Prefix(InetAddresses.toAddrString(address))) + .build(); + } + + throw new IllegalArgumentException(String.format("Unhandled address class %s", address.getClass())); + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend deleted file mode 100644 index 75cbf49ee5..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend +++ /dev/null @@ -1,423 +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.sal.compatibility; - -import com.google.common.net.InetAddresses -import java.math.BigInteger -import java.net.Inet4Address -import java.net.Inet6Address -import java.util.ArrayList -import org.opendaylight.controller.sal.action.Controller -import org.opendaylight.controller.sal.action.Drop -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.Output -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.core.Node -import org.opendaylight.controller.sal.core.NodeConnector -import org.opendaylight.controller.sal.flowprogrammer.Flow -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi -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.Ipv4Builder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp - -import static extension org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils.* -import static extension org.opendaylight.controller.sal.compatibility.NodeMapping.* -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlowBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder -import java.util.Collections -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.controller.action._case.ControllerActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.drop.action._case.DropActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.action._case.FloodActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.flood.all.action._case.FloodAllActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.hw.path.action._case.HwPathActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.loopback.action._case.LoopbackActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.push.vlan.action._case.PushVlanActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.dst.action._case.SetDlDstActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.src.action._case.SetDlSrcActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.dl.type.action._case.SetDlTypeActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.next.hop.action._case.SetNextHopActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.tos.action._case.SetNwTosActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.dst.action._case.SetTpDstActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.tp.src.action._case.SetTpSrcActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.cfi.action._case.SetVlanCfiActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.id.action._case.SetVlanIdActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.vlan.pcp.action._case.SetVlanPcpActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.sw.path.action._case.SwPathActionBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie - -public class MDFlowMapping { - - private new() { - throw new UnsupportedOperationException() - } - - public static def flowAdded(Flow sourceFlow) { - if (sourceFlow == null) - throw new IllegalArgumentException(); - val it = new FlowAddedBuilder(); - - hardTimeout = sourceFlow.hardTimeout as int - idleTimeout = sourceFlow.idleTimeout as int - cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) - priority = sourceFlow.priority as int - - val sourceActions = sourceFlow.actions; - val targetActions = new ArrayList(); - var int action = 0; - for (sourceAction : sourceActions) { - targetActions.add(sourceAction.toAction(action)); - action = action + 1; - } - instructions = targetActions.toApplyInstruction(); - match = sourceFlow.match.toMatch(); - tableId = new Integer(0).shortValue - return it.build(); - - } - - public static def toMDFlow(Flow sourceFlow, String flowId) { - if (sourceFlow == null) - throw new IllegalArgumentException(); - val it = new FlowBuilder(); - hardTimeout = sourceFlow.hardTimeout as int - idleTimeout = sourceFlow.idleTimeout as int - cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) - priority = sourceFlow.priority as int - id = new FlowId(flowId) - - val sourceActions = sourceFlow.actions; - val targetActions = new ArrayList(); - var int action = 0; - for (sourceAction : sourceActions) { - targetActions.add(sourceAction.toAction(action)); - action = action+ 1; - } - instructions = targetActions.toApplyInstruction(); - match = sourceFlow.match.toMatch(); - tableId = new Integer(0).shortValue - return it.build(); - } - - public static def Instructions toApplyInstruction(ArrayList actions) { - val it = new InstructionsBuilder; - val applyActions = new InstructionBuilder; - applyActions.instruction = new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(actions).build()).build() - applyActions.setOrder(new Integer(0)) - instruction = Collections.singletonList(applyActions.build) - return it.build; - } - - public static def removeFlowInput(Node sourceNode, Flow sourceFlow) { - val source = flowAdded(sourceFlow); - val it = new RemoveFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); - node = sourceNode.toNodeRef() - return it.build(); - } - - public static def addFlowInput(Node sourceNode, Flow sourceFlow) { - val source = flowAdded(sourceFlow); - val it = new AddFlowInputBuilder(source as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); - it.setNode(sourceNode.toNodeRef) - return it.build(); - } - - public static def updateFlowInput(Node sourceNode, Flow oldFlow, Flow newFlow) { - val it = new UpdateFlowInputBuilder(); - val sourceOld = flowAdded(newFlow); - - val original = new OriginalFlowBuilder(sourceOld as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); - val sourceNew = flowAdded(newFlow); - val updated = new UpdatedFlowBuilder(sourceNew as org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow); - originalFlow = original.build() - updatedFlow = updated.build(); - node = sourceNode.toNodeRef() - return it.build(); - } - - public static dispatch def toAction(Controller sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new ControllerActionCaseBuilder().setControllerAction(new ControllerActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(Drop sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new DropActionCaseBuilder().setDropAction(new DropActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(Flood sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new FloodActionCaseBuilder().setFloodAction(new FloodActionBuilder().build).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(FloodAll sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new FloodAllActionCaseBuilder().setFloodAllAction(new FloodAllActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(HwPath sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new HwPathActionCaseBuilder().setHwPathAction(new HwPathActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(Loopback sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new LoopbackActionCaseBuilder().setLoopbackAction(new LoopbackActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(Output sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new OutputActionBuilder(); - outputNodeConnector = sourceAction.port.toUri; - actionBuilder.action = new OutputActionCaseBuilder().setOutputAction(it.build()).build(); - return actionBuilder.build(); - - } - - public static dispatch def toAction(PopVlan sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new PopVlanActionCaseBuilder().build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(PushVlan sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new PushVlanActionBuilder(); - cfi = new VlanCfi(sourceAction.cfi); - vlanId = new VlanId(sourceAction.vlanId); - pcp = sourceAction.pcp; - tag = sourceAction.tag; - actionBuilder.action = new PushVlanActionCaseBuilder().setPushVlanAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetDlDst sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetDlDstActionBuilder(); - address = sourceAction.dlAddress.toMacAddress(); - actionBuilder.action = new SetDlDstActionCaseBuilder().setSetDlDstAction(it.build()).build; - return actionBuilder.build(); - } - - public static dispatch def toAction(SetDlSrc sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetDlSrcActionBuilder(); - address = sourceAction.dlAddress.toMacAddress; - actionBuilder.action = new SetDlSrcActionCaseBuilder().setSetDlSrcAction(it.build()).build; - return actionBuilder.build(); - } - - public static dispatch def toAction(SetDlType sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetDlTypeActionBuilder(); - dlType = new EtherType(sourceAction.dlType as long); - actionBuilder.action = new SetDlTypeActionCaseBuilder().setSetDlTypeAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetNextHop sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetNextHopActionBuilder(); - val inetAddress = sourceAction.address; - address = inetAddress.toInetAddress; - actionBuilder.action = new SetNextHopActionCaseBuilder().setSetNextHopAction(it.build).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetNwDst sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetNwDstActionBuilder(); - val inetAddress = sourceAction.address; - address = inetAddress.toInetAddress; - actionBuilder.action = new SetNwDstActionCaseBuilder().setSetNwDstAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetNwSrc sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetNwSrcActionBuilder(); - val inetAddress = sourceAction.address; - address = inetAddress.toInetAddress; - actionBuilder.action = new SetNwSrcActionCaseBuilder().setSetNwSrcAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetNwTos sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetNwTosActionBuilder(); - tos = sourceAction.nwTos; - actionBuilder.action = new SetNwTosActionCaseBuilder().setSetNwTosAction(it.build).build; - return actionBuilder.build(); - } - - public static dispatch def toAction(SetTpDst sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetTpDstActionBuilder(); - port = new PortNumber(sourceAction.port); - actionBuilder.action = new SetTpDstActionCaseBuilder().setSetTpDstAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetTpSrc sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetTpSrcActionBuilder(); - port = new PortNumber(sourceAction.port); - actionBuilder.action = new SetTpSrcActionCaseBuilder().setSetTpSrcAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetVlanCfi sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetVlanCfiActionBuilder(); - vlanCfi = new VlanCfi(sourceAction.cfi); - actionBuilder.action = new SetVlanCfiActionCaseBuilder().setSetVlanCfiAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetVlanId sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - - val it = new SetVlanIdActionBuilder(); - vlanId = new VlanId(sourceAction.vlanId); - actionBuilder.action = new SetVlanIdActionCaseBuilder().setSetVlanIdAction(it.build()).build(); - return actionBuilder.build(); - } - - public static dispatch def toAction(SetVlanPcp sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - val it = new SetVlanPcpActionBuilder(); - vlanPcp = new VlanPcp(sourceAction.pcp as short); - actionBuilder.action = new SetVlanPcpActionCaseBuilder().setSetVlanPcpAction(it.build).build; - return actionBuilder.build(); - } - - public static dispatch def toAction(SwPath sourceAction, int order) { - val actionBuilder = new ActionBuilder().setOrder(order); - actionBuilder.action = new SwPathActionCaseBuilder().setSwPathAction(new SwPathActionBuilder().build()).build(); - return actionBuilder.build(); - } - - public static def dispatch Address toInetAddress(Inet4Address address) { - val it = new Ipv4Builder - ipv4Address = new Ipv4Prefix(InetAddresses.toAddrString(address)) - return it.build() - } - - public static def dispatch Address toInetAddress(Inet6Address address) { - val it = new Ipv6Builder - ipv6Address = new Ipv6Prefix(InetAddresses.toAddrString(address)) - return it.build() - } - - public static def Uri toUri(NodeConnector connector) { - return new NodeConnectorId(connector.ID as String); - } - - public static def MacAddress toMacAddress(byte[] bytes) { - val sb = new StringBuilder(18); - for (byte b : bytes) { - if (sb.length() > 0) - sb.append(':'); - sb.append(String.format("%02x", b)); - } - return new MacAddress(sb.toString()); - } - - public static def toMDSalflow(Flow sourceFlow) { - if (sourceFlow == null) - throw new IllegalArgumentException(); - val it = new FlowBuilder(); - - hardTimeout = sourceFlow.hardTimeout as int - idleTimeout = sourceFlow.idleTimeout as int - cookie = new FlowCookie(BigInteger.valueOf(sourceFlow.id)) - priority = sourceFlow.priority as int - - val sourceActions = sourceFlow.actions; - val targetActions = new ArrayList(); - var int action = 0; - for (sourceAction : sourceActions) { - targetActions.add(sourceAction.toAction(action)); - action = action + 1; - } - instructions = targetActions.toApplyInstruction(); - match = sourceFlow.match.toMatch(); - return it.build(); - } - -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/SalCompatibilityProvider.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/SalCompatibilityProvider.java new file mode 100644 index 0000000000..0ddbcaa2e0 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/SalCompatibilityProvider.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility; + +import java.util.Collection; +import java.util.Collections; + +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ConsumerContext; +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.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +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.opendaylight.yangtools.yang.binding.RpcService; + +import com.google.common.base.Preconditions; + +class SalCompatibilityProvider implements BindingAwareProvider { + private final ComponentActivator activator; + + public SalCompatibilityProvider(final ComponentActivator cmpAct) { + this.activator = Preconditions.checkNotNull(cmpAct); + } + + @Override + public Collection getFunctionality() { + return Collections.emptyList(); + } + + @Override + public Collection getImplementations() { + return Collections.emptyList(); + } + + @Override + public void onSessionInitialized(final ConsumerContext session) { + // No-op + } + + @Override + public void onSessionInitiated(final ProviderContext session) { + final NotificationService subscribe = session.getSALService(NotificationService.class); + + final FlowProgrammerAdapter flow = activator.getFlow(); + flow.setDelegate(session.getRpcService(SalFlowService.class)); + flow.setDataBrokerService(session.getSALService(DataBrokerService.class)); + // FIXME: remember registration for clean shutdown + subscribe.registerNotificationListener(flow); + + final InventoryAndReadAdapter inv = activator.getInventory(); + inv.setDataService(session.getSALService(DataBrokerService.class)); + inv.setFlowStatisticsService(session.getRpcService(OpendaylightFlowStatisticsService.class)); + inv.setFlowTableStatisticsService(session.getRpcService(OpendaylightFlowTableStatisticsService.class)); + inv.setNodeConnectorStatisticsService(session.getRpcService(OpendaylightPortStatisticsService.class)); + inv.setTopologyDiscovery(session.getRpcService(FlowTopologyDiscoveryService.class)); + inv.setDataProviderService(session.getSALService(DataProviderService.class)); + // FIXME: remember registration for clean shutdown + subscribe.registerNotificationListener(inv); + + final DataPacketServiceAdapter dps = activator.getDataPacketService(); + dps.setDelegate(session.getRpcService(PacketProcessingService.class)); + + final TopologyAdapter topo = activator.getTopology(); + topo.setDataService(session.getSALService(DataProviderService.class)); + + final TopologyProvider tpp = activator.getTpProvider(); + tpp.setDataService(session.getSALService(DataProviderService.class)); + + inv.startAdapter(); + tpp.startAdapter(); + + subscribe.registerNotificationListener(activator.getDataPacket()); + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.java new file mode 100644 index 0000000000..4e3cf69817 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility.topology; + +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.topology.IPluginInTopologyService; +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +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.TopologyKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import com.google.common.base.Preconditions; + +public class TopologyAdapter implements IPluginInTopologyService { + private final InstanceIdentifier topology = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(new TopologyId("flow:1"))).toInstance(); + + // Injected via Apache DM + private IPluginOutTopologyService topologyPublisher; + + + private DataProviderService dataService; + + public void setDataService(final DataProviderService dataService) { + this.dataService = Preconditions.checkNotNull(dataService); + } + + @Override + public void sollicitRefresh() { + final TypeSafeDataReader reader = TypeSafeDataReader.forReader(dataService); + final Topology t = reader.readOperationalData(topology); + topologyPublisher.edgeUpdate(TopologyMapping.toADEdgeUpdates(t, reader)); + } + + public IPluginOutTopologyService getTopologyPublisher() { + return topologyPublisher; + } + + public void setTopologyPublisher(final IPluginOutTopologyService topologyPublisher) { + this.topologyPublisher = topologyPublisher; + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend deleted file mode 100644 index 4ce57afe9e..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyAdapter.xtend +++ /dev/null @@ -1,37 +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.sal.compatibility.topology - -import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.controller.sal.topology.IPluginInTopologyService -import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId -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.TopologyKey -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier - -import static extension org.opendaylight.controller.sal.compatibility.topology.TopologyMapping.* - -class TopologyAdapter implements IPluginInTopologyService { - - @Property - DataProviderService dataService; - - @Property - IPluginOutTopologyService topologyPublisher; - - override sollicitRefresh() { - val path = InstanceIdentifier.builder(NetworkTopology).child(Topology,new TopologyKey(new TopologyId("flow:1"))).toInstance; - val reader = TypeSafeDataReader.forReader(dataService) - val topology = reader.readOperationalData(path) - topologyPublisher.edgeUpdate(topology.toADEdgeUpdates(reader)) - } - -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.java new file mode 100644 index 0000000000..476a71a4ac --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility.topology; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.opendaylight.controller.md.sal.binding.util.TypeSafeDataReader; +import org.opendaylight.controller.sal.compatibility.NodeMapping; +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Edge; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.controller.sal.core.Property; +import org.opendaylight.controller.sal.core.UpdateType; +import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId; +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.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Function; +import com.google.common.collect.FluentIterable; + +public final class TopologyMapping { + private static final Logger LOG = LoggerFactory.getLogger(TopologyMapping.class); + + private TopologyMapping() { + throw new UnsupportedOperationException("Utility class. Instantiation is not allowed."); + } + + public static List toADEdgeUpdates(final Topology topology,final TypeSafeDataReader reader) { + final List result = new CopyOnWriteArrayList<>(); + return FluentIterable.from(topology.getLink()).transform( + new Function() { + @Override + public TopoEdgeUpdate apply(final Link input) { + try { + return toTopoEdgeUpdate(toAdEdge(input, topology), reader); + } catch (ConstructionException e) { + throw new IllegalArgumentException(String.format("Failed to construct edge update for {}", input), e); + } + }} + ).copyInto(result); + } + + public static Edge toAdEdge(final Link link, final Topology topology) throws ConstructionException { + final NodeConnector adSrc = toADNodeConnector(link.getSource().getSourceTp(), link.getSource().getSourceNode()); + final NodeConnector adDst = toADNodeConnector(link.getDestination().getDestTp(), link.getDestination().getDestNode()); + return new Edge(adSrc, adDst); + } + + public static TopoEdgeUpdate toTopoEdgeUpdate(final Edge e, final TypeSafeDataReader reader) { + return toTopoEdgeUpdate(e, UpdateType.ADDED, reader); + } + + public static TopoEdgeUpdate toTopoEdgeUpdate(final Edge e,final UpdateType type,final TypeSafeDataReader reader) { + return new TopoEdgeUpdate(e, toAdEdgeProperties(e, reader), type); + } + + public static Set toAdEdgeProperties(final Edge e,final TypeSafeDataReader reader) { + final NodeConnectorRef ncref = NodeMapping.toNodeConnectorRef(e.getTailNodeConnector()); + if(ncref == null) { + LOG.debug("Edge {} ncref {}",e,ncref); + return null; + } + + @SuppressWarnings("unchecked") + final InstanceIdentifier ncInstanceId = + (InstanceIdentifier) ncref.getValue(); + if(ncInstanceId == null) { + LOG.debug("Edge {} ncref {}",e,ncref); + return null; + } + + final org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector nc = reader.readOperationalData(ncInstanceId); + if(nc == null) { + return null; + } + return NodeMapping.toADNodeConnectorProperties(nc); + } + + public static String toADNodeId(final NodeId nodeId) { + return nodeId.getValue(); + } + + public static NodeConnector toADNodeConnector(final TpId source, final NodeId nodeId) throws ConstructionException { + checkNotNull(source); + return new NodeConnector(NodeMapping.MD_SAL_TYPE, toADNodeConnectorId(source), toADNode(nodeId)); + } + + public static String toADNodeConnectorId(final TpId nodeConnectorId) { + return nodeConnectorId.getValue(); + } + + public static Node toADNode(final NodeId nodeId) throws ConstructionException { + checkNotNull(nodeId); + return new Node(NodeMapping.MD_SAL_TYPE, toADNodeId(nodeId)); + } +} 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 deleted file mode 100644 index 2d490564e1..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyMapping.xtend +++ /dev/null @@ -1,91 +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.sal.compatibility.topology - -import com.google.common.collect.FluentIterable -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 -import org.opendaylight.controller.sal.core.NodeConnector -import org.opendaylight.controller.sal.core.UpdateType -import org.opendaylight.controller.sal.topology.TopoEdgeUpdate -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId -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.* - -class TopologyMapping { - private static val LOG = LoggerFactory.getLogger(TopologyMapping); - private new() { - throw new UnsupportedOperationException("Utility class. Instantiation is not allowed."); - } - - public static def toADEdgeUpdates(Topology topology,TypeSafeDataReader reader) { - val List result = new CopyOnWriteArrayList() - return FluentIterable.from(topology.link).transform[toAdEdge(topology).toTopoEdgeUpdate(reader)].copyInto(result) - } - - public static def toAdEdge(Link link,Topology topology) { - val adSrc = link.source.sourceTp.toADNodeConnector(link.source.sourceNode) - val adDst = link.destination.destTp.toADNodeConnector(link.destination.destNode) - return new Edge(adSrc,adDst); - } - - public static def toTopoEdgeUpdate(Edge e,TypeSafeDataReader reader) { - return toTopoEdgeUpdate(e,UpdateType.ADDED,reader) - } - - public static def toTopoEdgeUpdate(Edge e,UpdateType type,TypeSafeDataReader reader) { - return new TopoEdgeUpdate(e,e.toAdEdgeProperties(reader),type) - } - - public static def toAdEdgeProperties(Edge e,TypeSafeDataReader reader) { - val ncref = e.tailNodeConnector.toNodeConnectorRef - if(ncref == null) { - LOG.debug("Edge {} ncref {}",e,ncref) - return null; - } - val ncInstanceId = (ncref.value as InstanceIdentifier) - if(ncInstanceId == null) { - LOG.debug("Edge {} ncref {}",e,ncref) - return null; - } - val nc = reader.readOperationalData(ncInstanceId) - if(nc == null) { - return null; - } - return nc.toADNodeConnectorProperties - } - - public static def toADNodeId(NodeId nodeId) { - checkNotNull(nodeId); - return nodeId.value - } - public static def toADNodeConnector(TpId source,NodeId nodeId) throws ConstructionException { - checkNotNull(source); - return new NodeConnector(MD_SAL_TYPE,source.toADNodeConnectorId,nodeId.toADNode) - } - - public static def toADNodeConnectorId(TpId nodeConnectorId) { - return nodeConnectorId.value - } - - public static def toADNode(NodeId nodeId) { - checkNotNull(nodeId); - return new Node(MD_SAL_TYPE,nodeId.toADNodeId); - } -} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.java b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.java new file mode 100644 index 0000000000..d78bce4787 --- /dev/null +++ b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.compatibility.topology; + +import org.opendaylight.controller.sal.binding.api.data.DataChangeListener; +import org.opendaylight.controller.sal.binding.api.data.DataProviderService; +import org.opendaylight.controller.sal.topology.IPluginOutTopologyService; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +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.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; + +public class TopologyProvider implements AutoCloseable{ + private static final Logger LOG = LoggerFactory.getLogger(TopologyProvider.class); + private static final InstanceIdentifier PATH = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class ,new TopologyKey(new TopologyId("flow:1"))) + .child(Link.class) + .toInstance(); + private TopologyCommitHandler commitHandler; + + private ListenerRegistration listenerRegistration; + private IPluginOutTopologyService topologyPublisher; + private DataProviderService dataService; + + public void startAdapter() { + if(dataService == null){ + LOG.error("dataService not set"); + return; + } + commitHandler = new TopologyCommitHandler(dataService,topologyPublisher); + listenerRegistration = dataService.registerDataChangeListener(PATH, commitHandler); + LOG.info("TopologyProvider started"); + } + + @Override + public void close() { + if (listenerRegistration != null) { + listenerRegistration.close(); + } + } + + void setTopologyPublisher(final IPluginOutTopologyService topologyPublisher) { + this.topologyPublisher = topologyPublisher; + if (commitHandler != null) { + commitHandler.setTopologyPublisher(topologyPublisher); + } + } + + public void setDataService(final DataProviderService dataService) { + this.dataService = Preconditions.checkNotNull(dataService); + } +} diff --git a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend b/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend deleted file mode 100644 index 21f2b35f40..0000000000 --- a/opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/topology/TopologyProvider.xtend +++ /dev/null @@ -1,64 +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.sal.compatibility.topology - -import org.opendaylight.controller.sal.binding.api.data.DataProviderService -import org.opendaylight.controller.sal.topology.IPluginOutTopologyService -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId -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.TopologyKey -import org.opendaylight.yangtools.yang.binding.DataObject -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link -import org.slf4j.LoggerFactory -import org.opendaylight.yangtools.concepts.ListenerRegistration -import org.opendaylight.controller.sal.binding.api.data.DataChangeListener - -class TopologyProvider implements AutoCloseable{ - static val LOG = LoggerFactory.getLogger(TopologyProvider); - TopologyCommitHandler commitHandler - - @Property - IPluginOutTopologyService topologyPublisher; - - @Property - DataProviderService dataService; - - ListenerRegistration listenerRegistration - - - def void start() { - - } - def void startAdapter() { - if(dataService == null){ - LOG.error("dataService not set"); - return; - } - commitHandler = new TopologyCommitHandler(dataService,topologyPublisher); - val InstanceIdentifier path = InstanceIdentifier.builder(NetworkTopology) - .child(Topology,new TopologyKey(new TopologyId("flow:1"))) - .child(Link) - .toInstance(); - listenerRegistration = dataService.registerDataChangeListener(path,commitHandler); - LOG.info("TopologyProvider started") - } - - override close() throws Exception { - listenerRegistration.close - } - - def setTopologyPublisher(IPluginOutTopologyService topologyPublisher) { - _topologyPublisher = topologyPublisher; - if(commitHandler != null){ - commitHandler.setTopologyPublisher(topologyPublisher); - } - } - -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.java new file mode 100644 index 0000000000..22b6f6f1c7 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.binding.codegen; + +import org.opendaylight.yangtools.yang.binding.BaseIdentity; +import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.opendaylight.yangtools.yang.binding.RpcService; + +public final class RuntimeCodeSpecification { + public final static String DIRECT_PROXY_SUFFIX = "DirectProxy"; + public final static String INVOKER_SUFFIX = "ListenerInvoker"; + public final static String ROUTER_SUFFIX = "Router"; + + public final static String DELEGATE_FIELD = "_delegate"; + public final static String ROUTING_TABLE_FIELD_PREFIX = "_routes_"; + + private RuntimeCodeSpecification() { + throw new UnsupportedOperationException("Utility class"); + } + + /** + * Returns a name for generated interface + */ + private static String getGeneratedName(final Class cls, final String suffix) { + return cls.getName() + "$$Broker$" + suffix; + } + + public static String getInvokerName(final Class listener) { + return getGeneratedName(listener, RuntimeCodeSpecification.INVOKER_SUFFIX); + } + + /** + * Returns a name for DirectProxy implementation + */ + public static String getDirectProxyName(final Class base) { + return getGeneratedName(base, RuntimeCodeSpecification.DIRECT_PROXY_SUFFIX); + } + + /** + * Returns a name for Router implementation + */ + public static String getRouterName(final Class base) { + return getGeneratedName(base, RuntimeCodeSpecification.ROUTER_SUFFIX); + } + + /** + * Returns a field name for specified routing context + */ + public static String getRoutingTableField(final Class routingContext) { + return "_routes_" + routingContext.getSimpleName(); + } +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend deleted file mode 100644 index c5648adaa5..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeSpecification.xtend +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.codegen - -import org.opendaylight.yangtools.yang.binding.RpcService -import org.opendaylight.yangtools.yang.binding.BaseIdentity -import org.opendaylight.yangtools.yang.binding.NotificationListener - -/** - * - * - */ -class RuntimeCodeSpecification { - - //public static val PACKAGE_PREFIX = "_gen."; - - public static val DIRECT_PROXY_SUFFIX = "DirectProxy"; - public static val ROUTER_SUFFIX = "Router"; - public static val INVOKER_SUFFIX = "ListenerInvoker"; - - public static val DELEGATE_FIELD = "_delegate" - public static val ROUTING_TABLE_FIELD_PREFIX = "_routes_" - - public static def getInvokerName(Class listener) { - getGeneratedName(listener, INVOKER_SUFFIX); - } - - /** - * Returns a name for DirectProxy implementation - * - * - */ - public static def getDirectProxyName(Class base) { - getGeneratedName(base, DIRECT_PROXY_SUFFIX); - } - - /** - * Returns a name for Router implementation - * - */ - public static def getRouterName(Class base) { - getGeneratedName(base, ROUTER_SUFFIX); - } - - /** - * Returns a name for generated interface - * - */ - public static def getGeneratedName(Class cls, String suffix) { - '''«cls.name»$$Broker$«suffix»'''.toString() - } - - /** - * Returns a field name for specified routing context - * - */ - public static def getRoutingTableField(Class routingContext) { - return '''_routes_«routingContext.simpleName»'''.toString; - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java index 0bc11d9b35..4ad0bb0558 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/YangtoolsMappingHelper.java @@ -5,18 +5,19 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - - package org.opendaylight.controller.sal.binding.codegen; import java.lang.reflect.Method; + import org.opendaylight.yangtools.yang.binding.Notification; -@SuppressWarnings("all") -public class YangtoolsMappingHelper { - public static boolean isNotificationCallback(final Method it) { - return it.getName().startsWith("on") && (it.getParameterTypes().length == 1) && - Notification.class.isAssignableFrom(it.getParameterTypes()[0]); - } +public final class YangtoolsMappingHelper { + private YangtoolsMappingHelper() { + throw new UnsupportedOperationException("Utility class"); + } + public static boolean isNotificationCallback(final Method it) { + return it.getName().startsWith("on") && (it.getParameterTypes().length == 1) && + Notification.class.isAssignableFrom(it.getParameterTypes()[0]); + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java index 57b4960145..a15c711e2d 100644 --- a/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java +++ b/opendaylight/md-sal/sal-binding-it/src/main/java/org/opendaylight/controller/test/sal/binding/it/TestHelper.java @@ -27,6 +27,7 @@ public class TestHelper { public static Option mdSalCoreBundles() { return new DefaultCompositeOption( // mavenBundle(YANGTOOLS, "concepts").versionAsInProject(), // // + mavenBundle(YANGTOOLS, "util").versionAsInProject(), // // mavenBundle(YANGTOOLS, "yang-binding").versionAsInProject(), // // mavenBundle(YANGTOOLS, "yang-common").versionAsInProject(), // // mavenBundle(CONTROLLER, "sal-common").versionAsInProject(), // // diff --git a/opendaylight/md-sal/sal-dom-broker/pom.xml b/opendaylight/md-sal/sal-dom-broker/pom.xml index 162b66bda1..bac9146bf5 100644 --- a/opendaylight/md-sal/sal-dom-broker/pom.xml +++ b/opendaylight/md-sal/sal-dom-broker/pom.xml @@ -10,6 +10,10 @@ bundle + + com.github.romix + java-concurrent-hash-trie-map + com.google.guava guava @@ -18,10 +22,6 @@ junit junit - - org.eclipse.xtend - org.eclipse.xtend.lib - org.opendaylight.controller config-api @@ -42,6 +42,10 @@ org.opendaylight.controller sal-core-spi + + org.opendaylight.yangtools + util + org.opendaylight.yangtools yang-data-impl @@ -50,6 +54,7 @@ org.opendaylight.yangtools yang-parser-impl + org.slf4j slf4j-api @@ -88,13 +93,10 @@ org.opendaylight.yangtools.yang.util, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.* * + java-concurrent-hash-trie-map;inline=true - - org.eclipse.xtend - xtend-maven-plugin - org.opendaylight.yangtools 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 00df6580ef..87c68596ef 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 @@ -28,6 +28,7 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction; import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction; import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort; import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransaction; +import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain; import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.Identifiable; @@ -80,6 +81,11 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch return new SnapshotBackedWriteTransaction(nextIdentifier(), dataTree.takeSnapshot(), this); } + @Override + public DOMStoreTransactionChain createTransactionChain() { + throw new UnsupportedOperationException("Not implemented yet."); + } + @Override public synchronized void onGlobalContextUpdated(final SchemaContext ctx) { dataTree.setSchemaContext(ctx); @@ -257,7 +263,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable, Sch ready = true; LOG.debug("Store transaction: {} : Ready", getIdentifier()); - mutableTree.seal(); + mutableTree.ready(); return store.submit(this); } 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 b36ef3dd7c..2a163d8dbc 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,6 @@ 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.tree.StoreUtils.append; import java.util.Collection; import java.util.Collections; @@ -46,23 +45,10 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; /** - * * Resolve Data Change Events based on modifications and listeners * * Computes data change events for all affected registered listeners in data * tree. - * - * Prerequisites for computation is to set all parameters properly: - *
    - *
  • {@link #setRootPath(InstanceIdentifier)} - Root path of datastore - *
  • {@link #setListenerRoot(ListenerTree)} - Root of listener registration - * tree, which contains listeners to be notified - *
  • {@link #setModificationRoot(NodeModification)} - Modification root, for - * which events should be computed - *
  • {@link #setBeforeRoot(Optional)} - State of before modification occurred - *
  • {@link #setAfterRoot(Optional)} - State of after modification occurred - *
- * */ final class ResolveDataChangeEventsTask implements Callable> { private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class); @@ -72,7 +58,7 @@ final class ResolveDataChangeEventsTask implements Callable beforeChild : beforeCont.getValue()) { PathArgument childId = beforeChild.getIdentifier(); alreadyProcessed.add(childId); - InstanceIdentifier childPath = append(path, childId); + InstanceIdentifier childPath = path.node(childId); Collection childListeners = getListenerChildrenWildcarded(listeners, childId); Optional> afterChild = afterCont.getChild(childId); DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners, @@ -348,7 +334,7 @@ final class ResolveDataChangeEventsTask implements Callable childListeners = getListenerChildrenWildcarded(listeners, childId); - InstanceIdentifier childPath = append(path,childId); + InstanceIdentifier childPath = path.node(childId); childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild, DOMImmutableDataChangeEvent.getCreateEventFactory())); } @@ -432,7 +418,7 @@ final class ResolveDataChangeEventsTask implements Callable childListeners = getListenerChildrenWildcarded(listeners, childId); - eventBuilder.merge(resolveSameEventRecursivelly(append(path, childId), childListeners, child, eventFactory)); + eventBuilder.merge(resolveSameEventRecursivelly(path.node(childId), childListeners, child, eventFactory)); } propagateEvent = eventBuilder.build(); } else { @@ -460,7 +446,7 @@ final class ResolveDataChangeEventsTask implements Callable childListeners = getListenerChildrenWildcarded(listeners, childId); switch (childMod.getModificationType()) { @@ -522,7 +508,7 @@ final class ResolveDataChangeEventsTask implements Callable getChildNodes(); + /** + * Return the type of modification this node is undergoing. + * + * @return Node modification type. + */ ModificationType getModificationType(); + + /** + * Return the before-image of data corresponding to the node. + * + * @return Node data as they were present in the tree before + * the modification was applied. + */ Optional> getDataAfter(); + + /** + * Return the after-image of data corresponding to the node. + * + * @return Node data as they will be present in the tree after + * the modification is applied. + */ Optional> getDataBefore(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java index cff90a4aef..e4370c46a0 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/DataTreeModification.java @@ -16,8 +16,35 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; * has the ability to rebase itself to a new snapshot. */ public interface DataTreeModification extends DataTreeSnapshot { - void delete(InstanceIdentifier path); - void merge(InstanceIdentifier path, NormalizedNode data); - void write(InstanceIdentifier path, NormalizedNode data); - void seal(); + /** + * Delete the node at specified path. + * + * @param path Node path + */ + void delete(InstanceIdentifier path); + + /** + * Merge the specified data with the currently-present data + * at specified path. + * + * @param path Node path + * @param data Data to be merged + */ + void merge(InstanceIdentifier path, NormalizedNode data); + + /** + * Replace the data at specified path with supplied data. + * + * @param path Node path + * @param data New node data + */ + void write(InstanceIdentifier path, NormalizedNode data); + + /** + * Finish creation of a modification, making it ready for application + * to the data tree. Any calls to this object's methods will result + * in undefined behavior, possibly with an + * {@link IllegalStateException} being thrown. + */ + void ready(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java index f93f40a9cc..0d73143de2 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ListenerTree.java @@ -33,15 +33,24 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +/** + * A set of listeners organized as a tree by node to which they listen. This class + * allows for efficient lookup of listeners when we walk the DataTreeCandidate. + */ public final class ListenerTree { private static final Logger LOG = LoggerFactory.getLogger(ListenerTree.class); private final ReadWriteLock rwLock = new ReentrantReadWriteLock(true); private final Node rootNode = new Node(null, null); private ListenerTree() { - + // Private to disallow direct instantiation } + /** + * Create a new empty instance of the listener tree. + * + * @return An empty instance. + */ public static ListenerTree create() { return new ListenerTree(); } @@ -110,6 +119,14 @@ public final class ListenerTree { } } + /** + * Obtain a tree walking context. This context ensures a consistent view of + * the listener registrations. The context should be closed as soon as it + * is not required, because each unclosed instance blocks modification of + * the listener tree. + * + * @return A walker instance. + */ public Walker getWalker() { /* * TODO: The only current user of this method is local to the datastore. @@ -124,6 +141,10 @@ public final class ListenerTree { return ret; } + /** + * A walking context, pretty much equivalent to an iterator, but it + * exposes the undelying tree structure. + */ public static final class Walker implements AutoCloseable { private final Lock lock; private final Node node; 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/ModificationType.java index b16e907120..b9a26f5c00 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/ModificationType.java @@ -7,37 +7,39 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree; +/** + * Enumeration of all possible node modification states. These are used in + * data tree modification context to quickly assess what sort of modification + * the node is undergoing. + */ public enum ModificationType { - /** - * - * Node is unmodified - * - * + * Node is currently unmodified. */ UNMODIFIED, + /** - * - * Child of tree node was modified - * + * A child node, either direct or indirect, has been modified. This means + * that the data representation of this node has potentially changed. */ SUBTREE_MODIFIED, + /** - * Tree node was replaced with new value / subtree - * + * This node has been placed into the tree, potentially completely replacing + * pre-existing contents. */ WRITE, + /** - * - * Tree node is to be deleted. - * + * This node has been deleted along with any of its child nodes. */ DELETE, /** - * - * Tree node is to be merged with existing one. - * + * Node has been written into the tree, but instead of replacing pre-existing + * contents, it has been merged. This means that any incoming nodes which + * were present in the tree have been replaced, but their child nodes have + * been retained. */ - MERGE + MERGE, } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java index 52beaa7c61..d714f1cc85 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreTreeNode.java @@ -10,17 +10,17 @@ package org.opendaylight.controller.md.sal.dom.store.impl.tree; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; + /** - * - * Tree node which contains references to it's leafs + * A tree node which has references to its child leaves. This are typically + * internal non-data leaves, such as containers, lists, etc. * * @param Final node type */ public interface StoreTreeNode> { /** - * - * Returns direct child of the node + * Returns a direct child of the node * * @param child Identifier of child * @return Optional with node if the child is existing, {@link Optional#absent()} otherwise. diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java index 7e783f927d..b634866856 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/StoreUtils.java @@ -7,60 +7,32 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree; -import java.util.Set; - -import org.opendaylight.yangtools.concepts.Identifiable; -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; -import com.google.common.base.Function; import com.google.common.base.Strings; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; -import com.google.common.primitives.UnsignedLong; +/** + * Data store tree manipulation utilities. + */ public final class StoreUtils { private static final int STRINGTREE_INDENT = 4; - private final static Function, Object> EXTRACT_IDENTIFIER = new Function, Object>() { - @Override - public Object apply(final Identifiable input) { - return input.getIdentifier(); - } - }; - private StoreUtils() { throw new UnsupportedOperationException("Utility class should not be instantiated"); } - /* - * Suppressing warnings here allows us to fool the compiler enough - * such that we can reuse a single function for all applicable types - * and present it in a type-safe manner to our users. + /** + * Convert a data subtree under a node into a human-readable string format. + * + * @param node Data subtree root + * @return String containing a human-readable form of the subtree. */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Function, V> identifierExtractor() { - return (Function) EXTRACT_IDENTIFIER; - } - - public static final UnsignedLong increase(final UnsignedLong original) { - return original.plus(UnsignedLong.ONE); - } - - public static final InstanceIdentifier append(final InstanceIdentifier parent, final PathArgument arg) { - return new InstanceIdentifier(ImmutableList. builder().addAll(parent.getPath()).add(arg).build()); - } - - public static Set toIdentifierSet(final Iterable> children) { - return FluentIterable.from(children).transform(StoreUtils. identifierExtractor()).toSet(); - } - public static String toStringTree(final NormalizedNode node) { - StringBuilder builder = new StringBuilder(); + final StringBuilder builder = new StringBuilder(); toStringTree(builder, node, 0); return builder.toString(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java index 732352dd34..99982d318c 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/TreeNodeUtils.java @@ -13,6 +13,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.TreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; @@ -21,6 +22,9 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +/** + * A set of utility methods for interacting with {@link TreeNode} objects. + */ public final class TreeNodeUtils { private TreeNodeUtils() { throw new UnsupportedOperationException("Utility class should not be instantiated"); @@ -32,7 +36,6 @@ public final class TreeNodeUtils { * @param tree Data Tree * @param path Path to the node * @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise. - * */ public static > Optional findNode(final T tree, final InstanceIdentifier path) { Optional current = Optional. of(tree); 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 index 15479be462..c09a1a38b5 100644 --- 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 @@ -16,7 +16,7 @@ import com.google.common.base.Optional; final class AlwaysFailOperation implements ModificationApplyOperation { @Override public Optional apply(final ModifiedNode modification, - final Optional storeMeta, final Version subtreeVersion) { + final Optional storeMeta, final Version version) { 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/tree/data/InMemoryDataTreeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java index c05ed4b442..f7e95b84bd 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/InMemoryDataTreeModification.java @@ -131,7 +131,7 @@ final class InMemoryDataTreeModification implements DataTreeModification { } @Override - public synchronized void seal() { + public synchronized void ready() { Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree."); sealed = true; rootNode.seal(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java index 10f39a8cef..df03db35be 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ModificationApplyOperation.java @@ -50,7 +50,7 @@ interface ModificationApplyOperation extends StoreTreeNode apply(ModifiedNode modification, Optional storeMeta, Version subtreeVersion); + Optional apply(ModifiedNode modification, Optional storeMeta, Version version); /** * diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java index 2639d050ef..e7e79f8916 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NodeModification.java @@ -14,8 +14,31 @@ import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import com.google.common.base.Optional; +/** + * Internal interface representing a modification action of a particular node. + * It is used by the validation code to allow for a read-only view of the + * modification tree as we should never modify that during validation. + */ interface NodeModification extends Identifiable { + /** + * Get the type of modification. + * + * @return Modification type. + */ ModificationType getType(); + + /** + * Get the original tree node to which the modification is to be applied. + * + * @return The original node, or {@link Optional#absent()} if the node is + * a new node. + */ Optional getOriginal(); + + /** + * Get a read-only view of children nodes. + * + * @return Iterable of all children nodes. + */ Iterable getChildren(); } 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 index 2ef85cbcb7..227684ae35 100644 --- 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 @@ -18,6 +18,11 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Optional; import com.google.common.base.Preconditions; +/** + * Internal utility class for an empty candidate. We instantiate this class + * for empty modifications, saving memory and processing speed. Instances + * of this class are explicitly recognized and processing of them is skipped. + */ final class NoopDataTreeCandidate extends AbstractDataTreeCandidate { private static final DataTreeCandidateNode ROOT = new DataTreeCandidateNode() { @Override diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java index 3a3af5ecab..5c6aeace56 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/NormalizedNodeContainerModificationStrategy.java @@ -13,7 +13,6 @@ import java.util.Map; import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException; import org.opendaylight.controller.md.sal.dom.store.impl.tree.ModificationType; -import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreUtils; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.DataNodeContainerModificationStrategy.ListEntryModificationStrategy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.data.ValueNodeModificationStrategy.LeafSetEntryModificationStrategy; import org.opendaylight.controller.md.sal.dom.store.impl.tree.spi.MutableTreeNode; @@ -95,16 +94,9 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp @Override protected TreeNode applyWrite(final ModifiedNode modification, - final Optional currentMeta, final Version subtreeVersion) { - final Version nodeVersion; - if (currentMeta.isPresent()) { - nodeVersion = currentMeta.get().getVersion().next(); - } else { - nodeVersion = subtreeVersion; - } - + final Optional currentMeta, final Version version) { final NormalizedNode newValue = modification.getWrittenValue(); - final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, nodeVersion); + final TreeNode newValueMeta = TreeNodeFactory.createTreeNode(newValue, version); if (Iterables.isEmpty(modification.getChildren())) { return newValueMeta; @@ -122,12 +114,12 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp * and run the common parts on it -- which end with the node being sealed. */ final MutableTreeNode mutable = newValueMeta.mutable(); - mutable.setSubtreeVersion(subtreeVersion); + mutable.setSubtreeVersion(version); @SuppressWarnings("rawtypes") final NormalizedNodeContainerBuilder dataBuilder = createBuilder(newValue); - return mutateChildren(mutable, dataBuilder, nodeVersion, modification.getChildren()); + return mutateChildren(mutable, dataBuilder, version, modification.getChildren()); } @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -155,24 +147,21 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp @Override protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, - final Version subtreeVersion) { + final Version version) { // For Node Containers - merge is same as subtree change - we only replace children. - return applySubtreeChange(modification, currentMeta, subtreeVersion); + return applySubtreeChange(modification, currentMeta, version); } @Override public TreeNode applySubtreeChange(final ModifiedNode modification, - final TreeNode currentMeta, final Version subtreeVersion) { - // Bump subtree version to its new target - final Version updatedSubtreeVersion = currentMeta.getSubtreeVersion().next(); - + final TreeNode currentMeta, final Version version) { final MutableTreeNode newMeta = currentMeta.mutable(); - newMeta.setSubtreeVersion(updatedSubtreeVersion); + newMeta.setSubtreeVersion(version); @SuppressWarnings("rawtypes") NormalizedNodeContainerBuilder dataBuilder = createBuilder(currentMeta.getData()); - return mutateChildren(newMeta, dataBuilder, updatedSubtreeVersion, modification.getChildren()); + return mutateChildren(newMeta, dataBuilder, version, modification.getChildren()); } @Override @@ -188,7 +177,7 @@ abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareAp final PathArgument childId = childMod.getIdentifier(); final Optional childMeta = currentMeta.getChild(childId); - InstanceIdentifier childPath = StoreUtils.append(path, childId); + InstanceIdentifier childPath = path.node(childId); resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta); } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java index ff90d57f49..e1cc1a17e5 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/OperationWithModification.java @@ -44,8 +44,8 @@ final class OperationWithModification { return applyOperation; } - public Optional apply(final Optional data, final Version subtreeVersion) { - return applyOperation.apply(modification, data, subtreeVersion); + public Optional apply(final Optional data, final Version version) { + return applyOperation.apply(modification, data, version); } public static OperationWithModification from(final ModificationApplyOperation operation, diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java index bdf5667b67..6ef76adacf 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/SchemaAwareApplyOperation.java @@ -184,7 +184,7 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { @Override public final Optional apply(final ModifiedNode modification, - final Optional currentMeta, final Version subtreeVersion) { + final Optional currentMeta, final Version version) { switch (modification.getType()) { case DELETE: @@ -193,13 +193,13 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { Preconditions.checkArgument(currentMeta.isPresent(), "Metadata not available for modification", modification); return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(), - subtreeVersion))); + version))); case MERGE: if(currentMeta.isPresent()) { - return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion))); + return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(), version))); } // Fallback to write is intentional - if node is not preexisting merge is same as write case WRITE: - return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion))); + return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, version))); case UNMODIFIED: return currentMeta; default: @@ -208,13 +208,13 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { } protected abstract TreeNode applyMerge(ModifiedNode modification, - TreeNode currentMeta, Version subtreeVersion); + TreeNode currentMeta, Version version); protected abstract TreeNode applyWrite(ModifiedNode modification, - Optional currentMeta, Version subtreeVersion); + Optional currentMeta, Version version); protected abstract TreeNode applySubtreeChange(ModifiedNode modification, - TreeNode currentMeta, Version subtreeVersion); + TreeNode currentMeta, Version version); protected abstract void checkSubtreeModificationApplicable(InstanceIdentifier path, final NodeModification modification, final Optional current) throws DataPreconditionFailedException; @@ -231,20 +231,20 @@ abstract class SchemaAwareApplyOperation implements ModificationApplyOperation { @Override protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, - final Version subtreeVersion) { - return applyWrite(modification, Optional.of(currentMeta), subtreeVersion); + final Version version) { + return applyWrite(modification, Optional.of(currentMeta), version); } @Override protected TreeNode applySubtreeChange(final ModifiedNode modification, - final TreeNode currentMeta, final Version subtreeVersion) { + final TreeNode currentMeta, final Version version) { throw new UnsupportedOperationException("UnkeyedList does not support subtree change."); } @Override protected TreeNode applyWrite(final ModifiedNode modification, - final Optional currentMeta, final Version subtreeVersion) { - return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); + final Optional currentMeta, final Version version) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version); } @Override diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java index 5f68782a2e..a9f69ac953 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/data/ValueNodeModificationStrategy.java @@ -48,22 +48,22 @@ abstract class ValueNodeModificationStrategy extends S @Override protected TreeNode applySubtreeChange(final ModifiedNode modification, - final TreeNode currentMeta, final Version subtreeVersion) { + final TreeNode currentMeta, final Version version) { throw new UnsupportedOperationException("Node " + schema.getPath() + "is leaf type node. Subtree change is not allowed."); } @Override protected TreeNode applyMerge(final ModifiedNode modification, final TreeNode currentMeta, - final Version subtreeVersion) { + final Version version) { // Just overwrite whatever was there - return applyWrite(modification, null, subtreeVersion); + return applyWrite(modification, null, version); } @Override protected TreeNode applyWrite(final ModifiedNode modification, - final Optional currentMeta, final Version subtreeVersion) { - return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion); + final Optional currentMeta, final Version version) { + return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version); } @Override diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java index 1444f0c6a8..522bf3c84d 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/AbstractTreeNode.java @@ -12,7 +12,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import com.google.common.base.Preconditions; -/* +/** * A very basic data tree node. */ abstract class AbstractTreeNode implements TreeNode { diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java index 8f74f60498..3ca8db2405 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ContainerNode.java @@ -7,10 +7,10 @@ */ package org.opendaylight.controller.md.sal.dom.store.impl.tree.spi; -import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.opendaylight.yangtools.util.MapAdaptor; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; @@ -50,14 +50,14 @@ final class ContainerNode extends AbstractTreeNode { } private static final class Mutable implements MutableTreeNode { - private final Map children; private final Version version; + private Map children; private NormalizedNode data; private Version subtreeVersion; private Mutable(final ContainerNode parent) { this.data = parent.getData(); - this.children = new HashMap<>(parent.children); + this.children = MapAdaptor.getDefaultInstance().takeSnapshot(parent.children); this.subtreeVersion = parent.getSubtreeVersion(); this.version = parent.getVersion(); } @@ -84,15 +84,11 @@ final class ContainerNode extends AbstractTreeNode { @Override public TreeNode seal() { - final Map realChildren; + final TreeNode ret = new ContainerNode(data, version, MapAdaptor.getDefaultInstance().optimize(children), subtreeVersion); - if (children.isEmpty()) { - realChildren = Collections.emptyMap(); - } else { - realChildren = children; - } - - return new ContainerNode(data, version, realChildren, subtreeVersion); + // This forces a NPE if this class is accessed again. Better than corruption. + children = null; + return ret; } @Override @@ -103,8 +99,8 @@ final class ContainerNode extends AbstractTreeNode { private static ContainerNode create(final Version version, final NormalizedNode data, final Iterable> children) { - final Map map = new HashMap<>(); + final Map map = new HashMap<>(); for (NormalizedNode child : children) { map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version)); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java index dd3672cf11..087f4de666 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/MutableTreeNode.java @@ -11,10 +11,49 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreTreeNode; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +/** + * A mutable tree node. This is a transient view materialized from a pre-existing + * node. Modifications are isolated. Once this object is {@link #seal()}-ed, + * any interactions with it will result in undefined behavior. + */ public interface MutableTreeNode extends StoreTreeNode { + /** + * Set the data component of the node. + * + * @param data New data component, may not be null. + */ void setData(NormalizedNode data); + + /** + * Set the new subtree version. This is typically invoked when the user + * has modified some of this node's children. + * + * @param subtreeVersion New subtree version. + */ void setSubtreeVersion(Version subtreeVersion); + + /** + * Add a new child node. This acts as add-or-replace operation, e.g. it + * succeeds even if a conflicting child is already present. + * + * @param child New child node. + */ void addChild(TreeNode child); + + /** + * Remove a child node. This acts as delete-or-nothing operation, e.g. it + * succeeds even if the corresponding child is not present. + * + * @param id Child identificator. + */ void removeChild(PathArgument id); + + /** + * Finish node modification and return a read-only view of this node. After + * this method is invoked, any further calls to this object's method result + * in undefined behavior. + * + * @return Read-only view of this node. + */ TreeNode seal(); } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java index b0beb8168b..def1958123 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNode.java @@ -12,7 +12,7 @@ import org.opendaylight.yangtools.concepts.Identifiable; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -/* +/** * A very basic data tree node. It has a version (when it was last modified), * a subtree version (when any of its children were modified) and some read-only * data. diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java index c5d174caad..9547628ae9 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/TreeNodeFactory.java @@ -11,6 +11,10 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer; import org.opendaylight.yangtools.yang.data.api.schema.OrderedNodeContainer; +/** + * Public entrypoint for other packages. Allows instantiating a tree node + * with specified version. + */ public final class TreeNodeFactory { private TreeNodeFactory() { throw new UnsupportedOperationException("Utility class should not be instantiated"); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java index 7194faadf6..d89928b51e 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/spi/ValueNode.java @@ -14,6 +14,11 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; +/** + * Concretization of AbstractTreeNode for leaf nodes which only contain data. + * Instances of this class report all children as absent, subtree version + * equal to this node's version and do not support mutable view. + */ final class ValueNode extends AbstractTreeNode { private static final Logger LOG = LoggerFactory.getLogger(ValueNode.class); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java new file mode 100644 index 0000000000..7f834351d3 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.java @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import java.util.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.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.ServiceReference; +import org.osgi.framework.ServiceRegistration; + +public class BrokerConfigActivator implements AutoCloseable { + + private static InstanceIdentifier ROOT = InstanceIdentifier.builder() + .toInstance(); + + private DataProviderService dataService; + + private ServiceRegistration dataReg = null; + private ServiceRegistration dataProviderReg = null; + private ServiceRegistration mountReg = null; + private ServiceRegistration mountProviderReg = null; + private SchemaService schemaService = null; + private ServiceRegistration rpcProvisionRegistryReg = null; + private MountPointManagerImpl mountService = null; + + private SchemaAwareDataStoreAdapter wrappedStore = null; + + public void start(final BrokerImpl broker, final DataStore store, + final DOMDataBroker asyncBroker, final BundleContext context) { + + final Hashtable emptyProperties = new Hashtable(); + broker.setBundleContext(context); + + final ServiceReference serviceRef = context + .getServiceReference(SchemaService.class); + schemaService = context. getService(serviceRef); + + broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders + .fromSchemaService(schemaService))); + + if (asyncBroker == null) { + dataService = new DataBrokerImpl(); + dataProviderReg = context.registerService( + DataProviderService.class, dataService, emptyProperties); + + wrappedStore = new SchemaAwareDataStoreAdapter(); + wrappedStore.changeDelegate(store); + wrappedStore.setValidationEnabled(false); + context.registerService(SchemaServiceListener.class, wrappedStore, + emptyProperties); + + dataService.registerConfigurationReader(ROOT, wrappedStore); + dataService.registerCommitHandler(ROOT, wrappedStore); + dataService.registerOperationalReader(ROOT, wrappedStore); + } else { + BackwardsCompatibleDataBroker compatibleDataBroker = new BackwardsCompatibleDataBroker( + asyncBroker); + context.registerService(SchemaServiceListener.class, + compatibleDataBroker, emptyProperties); + dataService = compatibleDataBroker; + } + + mountService = new MountPointManagerImpl(); + dataReg = context.registerService(DataBrokerService.class, dataService, + emptyProperties); + mountReg = context.registerService(MountService.class, mountService, + emptyProperties); + mountProviderReg = context.registerService(MountProvisionService.class, + mountService, emptyProperties); + + rpcProvisionRegistryReg = context + .registerService(RpcProvisionRegistry.class, + broker.getRouter(), emptyProperties); + } + + @Override + public void close() { + + if (dataReg != null) { + dataReg.unregister(); + dataReg = null; + } + if (dataProviderReg != null) { + dataProviderReg.unregister(); + dataProviderReg = null; + } + if (mountReg != null) { + mountReg.unregister(); + mountReg = null; + } + if (mountProviderReg != null) { + mountProviderReg.unregister(); + mountProviderReg = null; + } + if (rpcProvisionRegistryReg != null) { + rpcProvisionRegistryReg.unregister(); + rpcProvisionRegistryReg = null; + } + } + + /** + * @return the dataService + */ + public DataProviderService getDataService() { + return dataService; + } + + /** + * @param dataService + * the dataService to set + */ + public void setDataService(final DataProviderService dataService) { + this.dataService = dataService; + } +} 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 deleted file mode 100644 index 357a516b57..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerConfigActivator.xtend +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.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.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 - -class BrokerConfigActivator implements AutoCloseable { - - private static val ROOT = InstanceIdentifier.builder().toInstance(); - - @Property - private var DataProviderService dataService; - - private var ServiceRegistration dataReg; - private var ServiceRegistration dataProviderReg; - private var ServiceRegistration mountReg; - private var ServiceRegistration mountProviderReg; - private var SchemaService schemaService; - private var ServiceRegistration rpcProvisionRegistryReg; - private var MountPointManagerImpl mountService; - - SchemaAwareDataStoreAdapter wrappedStore - - public def void start(BrokerImpl broker, DataStore store, DOMDataBroker asyncBroker,BundleContext context) { - val emptyProperties = new Hashtable(); - broker.setBundleContext(context); - - val serviceRef = context.getServiceReference(SchemaService); - schemaService = context.getService(serviceRef); - - broker.setRouter(new SchemaAwareRpcBroker("/", SchemaContextProviders.fromSchemaService(schemaService))); - - - if(asyncBroker == null) { - dataService = new DataBrokerImpl(); - dataProviderReg = context.registerService(DataProviderService, dataService, emptyProperties); - - wrappedStore = new SchemaAwareDataStoreAdapter(); - wrappedStore.changeDelegate(store); - wrappedStore.setValidationEnabled(false); - context.registerService(SchemaServiceListener, wrappedStore, emptyProperties) - - dataService.registerConfigurationReader(ROOT, wrappedStore); - dataService.registerCommitHandler(ROOT, wrappedStore); - dataService.registerOperationalReader(ROOT, wrappedStore); - } else { - val compatibleDataBroker = new BackwardsCompatibleDataBroker(asyncBroker); - context.registerService(SchemaServiceListener,compatibleDataBroker,emptyProperties); - dataService = compatibleDataBroker; - } - - -// - - mountService = new MountPointManagerImpl(); - dataReg = context.registerService(DataBrokerService, dataService, emptyProperties); - mountReg = context.registerService(MountService, mountService, emptyProperties); - mountProviderReg = context.registerService(MountProvisionService, mountService, emptyProperties); - - rpcProvisionRegistryReg = context.registerService(RpcProvisionRegistry, broker.getRouter(), emptyProperties); - } - - override def close() { - dataReg?.unregister(); - dataProviderReg?.unregister(); - mountReg?.unregister(); - mountProviderReg?.unregister(); - rpcProvisionRegistryReg?.unregister(); - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.java new file mode 100644 index 0000000000..e4bd0343cf --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener; +import org.opendaylight.controller.sal.core.api.Broker; +import org.opendaylight.controller.sal.core.api.Consumer; +import org.opendaylight.controller.sal.core.api.Provider; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter; +import org.opendaylight.controller.sal.core.api.RpcRegistrationListener; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.controller.sal.core.api.RpcImplementation; +import org.opendaylight.controller.sal.core.api.RpcRoutingContext; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation; + +public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { + private final static Logger log = LoggerFactory.getLogger(BrokerImpl.class); + + // Broker Generic Context + private final Set sessions = Collections + .synchronizedSet(new HashSet()); + private final Set providerSessions = Collections + .synchronizedSet(new HashSet()); + + private BundleContext bundleContext = null; + + private AutoCloseable deactivator = null; + + private RpcRouter router = null; + + @Override + public ConsumerSession registerConsumer(final Consumer consumer, + final BundleContext ctx) { + checkPredicates(consumer); + log.trace("Registering consumer {}", consumer); + final ConsumerContextImpl session = newSessionFor(consumer, ctx); + consumer.onSessionInitiated(session); + sessions.add(session); + return session; + } + + @Override + public ProviderSession registerProvider(final Provider provider, + final BundleContext ctx) { + checkPredicates(provider); + final ProviderContextImpl session = newSessionFor(provider, ctx); + provider.onSessionInitiated(session); + providerSessions.add(session); + return session; + } + + protected Future> invokeRpcAsync(final QName rpc, + final CompositeNode input) { + return router.invokeRpc(rpc, input); + } + + // Validation + private void checkPredicates(final Provider prov) { + Preconditions.checkNotNull(prov, "Provider should not be null."); + for (ProviderContextImpl session : providerSessions) { + if (prov.equals(session.getProvider())) + throw new IllegalStateException("Provider already registered"); + } + + } + + private void checkPredicates(final Consumer cons) { + Preconditions.checkNotNull(cons, "Consumer should not be null."); + for (ConsumerContextImpl session : sessions) { + if (cons.equals(session.getConsumer())) + throw new IllegalStateException("Consumer already registered"); + } + } + + // Private Factory methods + private ConsumerContextImpl newSessionFor(final Consumer provider, + final BundleContext ctx) { + ConsumerContextImpl ret = new ConsumerContextImpl(provider, ctx); + ret.setBroker(this); + return ret; + } + + private ProviderContextImpl newSessionFor(final Provider provider, + final BundleContext ctx) { + ProviderContextImpl ret = new ProviderContextImpl(provider, ctx); + ret.setBroker(this); + return ret; + } + + protected void consumerSessionClosed( + final ConsumerContextImpl consumerContextImpl) { + sessions.remove(consumerContextImpl); + providerSessions.remove(consumerContextImpl); + } + + @Override + public void close() throws Exception { + if (deactivator != null) { + deactivator.close(); + deactivator = null; + } + } + + @Override + public RpcRegistration addRpcImplementation(final QName rpcType, + final RpcImplementation implementation) + throws IllegalArgumentException { + return router.addRpcImplementation(rpcType, implementation); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation( + final QName rpcType, final RpcImplementation implementation) { + return router.addRoutedRpcImplementation(rpcType, implementation); + } + + @Override + public void setRoutedRpcDefaultDelegate( + final RoutedRpcDefaultImplementation defaultImplementation) { + router.setRoutedRpcDefaultDelegate(defaultImplementation); + } + + @Override + public ListenerRegistration addRpcRegistrationListener( + final RpcRegistrationListener listener) { + return router.addRpcRegistrationListener(listener); + } + + @Override + public > ListenerRegistration registerRouteChangeListener( + final L listener) { + return router.registerRouteChangeListener(listener); + } + + @Override + public Set getSupportedRpcs() { + return router.getSupportedRpcs(); + } + + @Override + public ListenableFuture> invokeRpc( + final QName rpc, final CompositeNode input) { + return router.invokeRpc(rpc, input); + } + + /** + * @return the bundleContext + */ + public BundleContext getBundleContext() { + return bundleContext; + } + + /** + * @param bundleContext + * the bundleContext to set + */ + public void setBundleContext(final BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + /** + * @return the deactivator + */ + public AutoCloseable getDeactivator() { + return deactivator; + } + + /** + * @param deactivator + * the deactivator to set + */ + public void setDeactivator(final AutoCloseable deactivator) { + this.deactivator = deactivator; + } + + /** + * @return the router + */ + public RpcRouter getRouter() { + return router; + } + + /** + * @param router + * the router to set + */ + public void setRouter(final RpcRouter router) { + this.router = router; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend deleted file mode 100644 index 0ed14c1027..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.xtend +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.dom.broker; - -import com.google.common.util.concurrent.ListenableFuture -import java.util.Collections -import java.util.HashSet -import java.util.Set -import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener -import org.opendaylight.controller.sal.core.api.Broker -import org.opendaylight.controller.sal.core.api.Consumer -import org.opendaylight.controller.sal.core.api.Provider -import org.opendaylight.yangtools.yang.common.QName -import org.opendaylight.yangtools.yang.common.RpcResult -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.osgi.framework.BundleContext -import org.slf4j.LoggerFactory -import org.opendaylight.controller.sal.dom.broker.spi.RpcRouter -import org.opendaylight.controller.sal.core.api.RpcRegistrationListener -import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry -import org.opendaylight.controller.sal.core.api.RpcImplementation -import org.opendaylight.controller.sal.core.api.RpcRoutingContext -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.controller.sal.core.api.RoutedRpcDefaultImplementation - -public class BrokerImpl implements Broker, RpcProvisionRegistry, AutoCloseable { - private static val log = LoggerFactory.getLogger(BrokerImpl); - - // Broker Generic Context - private val Set sessions = Collections.synchronizedSet(new HashSet()); - private val Set providerSessions = Collections.synchronizedSet( - new HashSet()); - - @Property - private var BundleContext bundleContext; - - @Property - private var AutoCloseable deactivator; - - @Property - private var RpcRouter router; - - override registerConsumer(Consumer consumer, BundleContext ctx) { - checkPredicates(consumer); - log.trace("Registering consumer " + consumer); - val session = newSessionFor(consumer, ctx); - consumer.onSessionInitiated(session); - sessions.add(session); - return session; - } - - override registerProvider(Provider provider, BundleContext ctx) { - checkPredicates(provider); - - val session = newSessionFor(provider, ctx); - provider.onSessionInitiated(session); - providerSessions.add(session); - return session; - } - - protected def ListenableFuture> invokeRpcAsync(QName rpc, CompositeNode input) { - return router.invokeRpc(rpc, input); - } - - // Validation - private def void checkPredicates(Provider prov) { - if (prov == null) - throw new IllegalArgumentException("Provider should not be null."); - for (ProviderContextImpl session : providerSessions) { - if (prov.equals(session.getProvider())) - throw new IllegalStateException("Provider already registered"); - } - - } - - private def void checkPredicates(Consumer cons) { - if (cons == null) - throw new IllegalArgumentException("Consumer should not be null."); - for (ConsumerContextImpl session : sessions) { - if (cons.equals(session.getConsumer())) - throw new IllegalStateException("Consumer already registered"); - } - } - - // Private Factory methods - private def ConsumerContextImpl newSessionFor(Consumer provider, BundleContext ctx) { - val ret = new ConsumerContextImpl(provider, ctx); - ret.broker = this; - return ret; - } - - private def ProviderContextImpl newSessionFor(Provider provider, BundleContext ctx) { - val ret = new ProviderContextImpl(provider, ctx); - ret.broker = this; - return ret; - } - - protected def void consumerSessionClosed(ConsumerContextImpl consumerContextImpl) { - sessions.remove(consumerContextImpl); - providerSessions.remove(consumerContextImpl); - } - - override close() throws Exception { - deactivator?.close(); - } - - override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException { - router.addRpcImplementation(rpcType,implementation); - } - - override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) { - router.addRoutedRpcImplementation(rpcType,implementation); - } - - override setRoutedRpcDefaultDelegate(RoutedRpcDefaultImplementation defaultImplementation) { - router.setRoutedRpcDefaultDelegate(defaultImplementation); - } - - override addRpcRegistrationListener(RpcRegistrationListener listener) { - return router.addRpcRegistrationListener(listener); - } - - override > registerRouteChangeListener(L listener) { - return router.registerRouteChangeListener(listener); - } - - override getSupportedRpcs() { - return router.getSupportedRpcs(); - } - - override invokeRpc(QName rpc, CompositeNode input) { - return router.invokeRpc(rpc,input) - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.java new file mode 100644 index 0000000000..fa81bc9040 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import java.util.Collection; +import java.util.concurrent.Future; + +import javax.annotation.concurrent.GuardedBy; + +import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession; +import org.opendaylight.controller.sal.core.api.BrokerService; +import org.opendaylight.controller.sal.core.api.Consumer; +import org.opendaylight.controller.sal.dom.broker.osgi.AbstractBrokerServiceProxy; +import org.opendaylight.controller.sal.dom.broker.osgi.ProxyFactory; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +import com.google.common.collect.ClassToInstanceMap; +import com.google.common.collect.MutableClassToInstanceMap; + +class ConsumerContextImpl implements ConsumerSession { + + private final ClassToInstanceMap instantiatedServices = MutableClassToInstanceMap + .create(); + private final BundleContext context; + private final Consumer consumer; + + private BrokerImpl broker = null; + @GuardedBy("this") + private boolean closed = false; + + public ConsumerContextImpl(final Consumer consumer, final BundleContext ctx) { + this.consumer = consumer; + this.context = ctx; + } + + @Override + public Future> rpc(final QName rpc, + final CompositeNode input) { + return broker.invokeRpcAsync(rpc, input); + } + + @Override + public T getService(final Class service) { + final T localProxy = instantiatedServices.getInstance(service); + if (localProxy != null) { + return localProxy; + } + final ServiceReference serviceRef = context + .getServiceReference(service); + if (serviceRef == null) { + return null; + } + final T serviceImpl = context.getService(serviceRef); + final T ret = ProxyFactory.createProxy(serviceRef, serviceImpl); + if (ret != null) { + instantiatedServices.putInstance(service, ret); + } + return ret; + } + + @Override + public void close() { + synchronized (this) { + if (closed) { + return; + } + this.closed = true; + } + + Collection toStop = instantiatedServices.values(); + for (BrokerService brokerService : toStop) { + if (brokerService instanceof AbstractBrokerServiceProxy) { + ((AbstractBrokerServiceProxy) brokerService).close(); + } + } + broker.consumerSessionClosed(this); + } + + @Override + public synchronized boolean isClosed() { + return closed; + } + + /** + * @return the broker + */ + public BrokerImpl getBroker() { + return broker; + } + + /** + * @param broker + * the broker to set + */ + public void setBroker(final BrokerImpl broker) { + this.broker = broker; + } + + /** + * @return the _consumer + */ + public Consumer getConsumer() { + return consumer; + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.xtend deleted file mode 100644 index 813f52b67d..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ConsumerContextImpl.xtend +++ /dev/null @@ -1,76 +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.sal.dom.broker - -import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession -import org.opendaylight.controller.sal.core.api.BrokerService -import org.opendaylight.controller.sal.core.api.Consumer -import org.osgi.framework.BundleContext -import org.opendaylight.yangtools.yang.common.QName -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.controller.sal.dom.broker.osgi.AbstractBrokerServiceProxy -import com.google.common.collect.ClassToInstanceMap -import com.google.common.collect.MutableClassToInstanceMap -import org.opendaylight.controller.sal.dom.broker.osgi.ProxyFactory - -class ConsumerContextImpl implements ConsumerSession { - - @Property - private val Consumer consumer; - - @Property - private var BrokerImpl broker; - - private val ClassToInstanceMap instantiatedServices = MutableClassToInstanceMap.create(); - private boolean closed = false; - - private BundleContext context; - - public new(Consumer consumer, BundleContext ctx) { - this._consumer = consumer; - this.context = ctx; - } - - override rpc(QName rpc, CompositeNode input) { - return broker.invokeRpcAsync(rpc, input); - } - - override T getService(Class service) { - val localProxy = instantiatedServices.getInstance(service); - if(localProxy != null) { - return localProxy; - } - val serviceRef = context.getServiceReference(service); - if(serviceRef == null) { - return null; - } - val serviceImpl = context.getService(serviceRef); - - - val ret = ProxyFactory.createProxy(serviceRef,serviceImpl); - if(ret != null) { - instantiatedServices.putInstance(service, ret); - } - return ret; - } - - override close() { - val toStop = instantiatedServices.values(); - this.closed = true; - for (BrokerService brokerService : toStop) { - if(brokerService instanceof AbstractBrokerServiceProxy) { - (brokerService as AutoCloseable).close(); - } - } - broker.consumerSessionClosed(this); - } - - override isClosed() { - return closed; - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java new file mode 100644 index 0000000000..55a6ee77b4 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.java @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.opendaylight.controller.sal.core.api.data.DataProviderService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; + +public class MountPointManagerImpl implements MountProvisionService { + + private final ListenerRegistry listeners = + ListenerRegistry.create(); + private final ConcurrentMap mounts = + new ConcurrentHashMap<>(); + private DataProviderService dataBroker = null; + + @Override + public MountProvisionInstance createMountPoint(final InstanceIdentifier path) { + checkState(!mounts.containsKey(path), "Mount already created"); + final MountPointImpl mount = new MountPointImpl(path); + registerMountPoint(mount); + mounts.put(path, mount); + notifyMountCreated(path); + return mount; + } + + public void notifyMountCreated(final InstanceIdentifier identifier) { + for (final ListenerRegistration listener : listeners + .getListeners()) { + listener.getInstance().onMountPointCreated(identifier); + } + } + + public Object registerMountPoint(final MountPointImpl impl) { + // FIXME: Why is thie commented out? Either we need it or we don't + // dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper); + // dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper); + return null; + } + + @Override + public MountProvisionInstance createOrGetMountPoint( + final InstanceIdentifier path) { + final MountPointImpl mount = mounts.get(path); + if (mount == null) { + return createMountPoint(path); + } + return mount; + } + + @Override + public MountProvisionInstance getMountPoint(final InstanceIdentifier path) { + return mounts.get(path); + } + + /** + * @return the dataBroker + */ + public DataProviderService getDataBroker() { + return dataBroker; + } + + /** + * @param dataBroker + * the dataBroker to set + */ + public void setDataBroker(final DataProviderService dataBroker) { + this.dataBroker = dataBroker; + } + + @Override + public ListenerRegistration registerProvisionListener( + final MountProvisionListener listener) { + return listeners.register(listener); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend deleted file mode 100644 index 023f906a67..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/MountPointManagerImpl.xtend +++ /dev/null @@ -1,66 +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.sal.dom.broker - - -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import java.util.concurrent.ConcurrentMap -import java.util.concurrent.ConcurrentHashMap -import static com.google.common.base.Preconditions.*; -import org.opendaylight.controller.sal.core.api.data.DataProviderService -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService.MountProvisionListener -import org.opendaylight.yangtools.concepts.util.ListenerRegistry - -class MountPointManagerImpl implements MountProvisionService { - - @Property - DataProviderService dataBroker; - - val ListenerRegistry listeners = ListenerRegistry.create() - - ConcurrentMap mounts = new ConcurrentHashMap(); - - override createMountPoint(InstanceIdentifier path) { - checkState(!mounts.containsKey(path),"Mount already created"); - val mount = new MountPointImpl(path); - registerMountPoint(mount); - mounts.put(path,mount); - notifyMountCreated(path); - return mount; - } - - def notifyMountCreated(InstanceIdentifier identifier) { - for(listener : listeners) { - listener.instance.onMountPointCreated(identifier); - } - } - - def registerMountPoint(MountPointImpl impl) { - //dataBroker?.registerConfigurationReader(impl.mountPath,impl.readWrapper); - //dataBroker?.registerOperationalReader(impl.mountPath,impl.readWrapper); - } - - override registerProvisionListener(MountProvisionListener listener) { - listeners.register(listener) - } - - - override createOrGetMountPoint(InstanceIdentifier path) { - val mount = mounts.get(path); - if(mount === null) { - return createMountPoint(path) - } - return mount; - } - - - override getMountPoint(InstanceIdentifier path) { - mounts.get(path); - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.java new file mode 100644 index 0000000000..5e8c0e8253 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import java.util.HashSet; +import java.util.Set; + +import org.opendaylight.controller.sal.core.api.Broker.ProviderSession; +import org.opendaylight.controller.sal.core.api.Broker.RoutedRpcRegistration; +import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration; +import org.opendaylight.controller.sal.core.api.Provider; +import org.opendaylight.controller.sal.core.api.RpcImplementation; +import org.opendaylight.controller.sal.core.api.RpcRegistrationListener; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.common.QName; +import org.osgi.framework.BundleContext; + +class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession { + private final Set registrations = new HashSet<>(); + private final Provider provider; + + public ProviderContextImpl(final Provider provider, final BundleContext ctx) { + super(null, ctx); + this.provider = provider; + } + + @Override + public RpcRegistrationWrapper addRpcImplementation(final QName rpcType, + final RpcImplementation implementation) throws IllegalArgumentException { + final RpcRegistration origReg = getBroker().getRouter() + .addRpcImplementation(rpcType, implementation); + final RpcRegistrationWrapper newReg = new RpcRegistrationWrapper( + origReg); + registrations.add(newReg); + return newReg; + } + + protected boolean removeRpcImplementation(final RpcRegistrationWrapper implToRemove) { + return registrations.remove(implToRemove); + } + + @Override + public void close() { + for (final RpcRegistrationWrapper reg : registrations) { + reg.close(); + } + } + + @Override + public RoutedRpcRegistration addMountedRpcImplementation( + final QName rpcType, final RpcImplementation implementation) { + throw new UnsupportedOperationException( + "TODO: auto-generated method stub"); + } + + @Override + public RoutedRpcRegistration addRoutedRpcImplementation( + final QName rpcType, final RpcImplementation implementation) { + throw new UnsupportedOperationException( + "TODO: auto-generated method stub"); + } + + @Override + public Set getSupportedRpcs() { + return getBroker().getRouter().getSupportedRpcs(); + } + + @Override + public ListenerRegistration addRpcRegistrationListener( + final RpcRegistrationListener listener) { + return getBroker().getRouter().addRpcRegistrationListener(listener); + } + + /** + * @return the provider + */ + public Provider getProvider() { + return provider; + } + + /** + * @param provider + * the provider to set + */ +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.xtend deleted file mode 100644 index e641ed1039..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/ProviderContextImpl.xtend +++ /dev/null @@ -1,92 +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.sal.dom.broker - -import org.opendaylight.controller.sal.core.api.Broker.ProviderSession -import org.opendaylight.controller.sal.core.api.Provider -import org.opendaylight.controller.sal.core.api.RpcImplementation -import org.opendaylight.yangtools.yang.common.QName -import org.osgi.framework.BundleContext -import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration -import org.opendaylight.controller.sal.core.api.RpcRegistrationListener -import org.opendaylight.yangtools.concepts.Registration - -import java.util.Set -import java.util.HashSet - -class ProviderContextImpl extends ConsumerContextImpl implements ProviderSession { - - @Property - private val Provider provider; - - private val Set> registrations = new HashSet(); - - new(Provider provider, BundleContext ctx) { - super(null, ctx); - this._provider = provider; - } - - override addRpcImplementation(QName rpcType, RpcImplementation implementation) throws IllegalArgumentException { - val origReg = broker.router.addRpcImplementation(rpcType, implementation); - val newReg = new RpcRegistrationWrapper(origReg); - registrations.add(newReg); - return newReg; - } - - protected def removeRpcImplementation(RpcRegistrationWrapper implToRemove) throws IllegalArgumentException { - registrations.remove(implToRemove); - } - - override close() { - - for (reg : registrations) { - reg.close() - } - super.close - } - - override addMountedRpcImplementation(QName rpcType, RpcImplementation implementation) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - } - - override addRoutedRpcImplementation(QName rpcType, RpcImplementation implementation) { - throw new UnsupportedOperationException("TODO: auto-generated method stub") - } - - override getSupportedRpcs() { - broker.router.supportedRpcs; - } - - override addRpcRegistrationListener(RpcRegistrationListener listener) { - broker.router.addRpcRegistrationListener(listener); - } -} - -class RpcRegistrationWrapper implements RpcRegistration { - - - @Property - val RpcRegistration delegate - - new(RpcRegistration delegate) { - _delegate = delegate - } - - override getInstance() { - delegate.instance - } - - override close() { - delegate.close - } - - override getType() { - delegate.type - } -} - diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/RpcRegistrationWrapper.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/RpcRegistrationWrapper.java new file mode 100644 index 0000000000..db6c72e2ff --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/RpcRegistrationWrapper.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker; + +import org.opendaylight.controller.sal.core.api.Broker.RpcRegistration; +import org.opendaylight.controller.sal.core.api.RpcImplementation; +import org.opendaylight.yangtools.yang.common.QName; + +import com.google.common.base.Preconditions; + +public class RpcRegistrationWrapper implements RpcRegistration { + + private final RpcRegistration delegate; + + public RpcRegistrationWrapper(final RpcRegistration delegate) { + this.delegate = Preconditions.checkNotNull(delegate); + } + + @Override + public RpcImplementation getInstance() { + return delegate.getInstance(); + } + + @Override + public void close() { + delegate.close(); + } + + @Override + public QName getType() { + return delegate.getType(); + } + + /** + * @return the delegate + */ + public RpcRegistration getDelegate() { + return delegate; + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.java new file mode 100644 index 0000000000..53423f6b09 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker.impl; + +import static com.google.common.base.Preconditions.checkState; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.api.SimpleNode; +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Iterables; + +public class DataReaderRouter extends +AbstractDataReadRouter { + private final static Logger LOG = LoggerFactory + .getLogger(DataReaderRouter.class); + private final static URI NETCONF_NAMESPACE = URI + .create("urn:ietf:params:xml:ns:netconf:base:1.0"); + private final static QName NETCONF_DATA = new QName(NETCONF_NAMESPACE, + "data"); + + @Override + protected CompositeNodeTOImpl merge(final InstanceIdentifier path, + final Iterable data) { + PathArgument pathArgument = Iterables.getLast(path.getPath(), null); + boolean empty = true; + QName name = (pathArgument == null ? null : pathArgument.getNodeType()); + final ArrayList> nodes = new ArrayList>(); + final HashMap> keyNodes = new HashMap>(); + for (final CompositeNode dataBit : data) { + try { + if (pathArgument != null && dataBit != null) { + empty = false; + final Map> keyNodesLocal = getKeyNodes( + pathArgument, dataBit); + nodes.addAll(this.childrenWithout(dataBit, + keyNodesLocal.entrySet())); + } else if (dataBit != null) { + empty = false; + nodes.addAll(dataBit.getValue()); + } + } catch (IllegalStateException e) { + LOG.error("BUG: Readed data for path {} was invalid", path, e); + } + } + if (empty) { + return null; + } + /** + * Reading from Root + * + */ + if (pathArgument == null) { + return new CompositeNodeTOImpl(NETCONF_DATA, null, nodes); + } + final ArrayList> finalNodes = new ArrayList>( + nodes.size() + keyNodes.size()); + finalNodes.addAll(keyNodes.values()); + finalNodes.addAll(nodes); + return new CompositeNodeTOImpl(name, null, finalNodes); + } + + protected Map> _getKeyNodes( + final PathArgument argument, final CompositeNode node) { + return Collections.emptyMap(); + } + + protected Map> _getKeyNodes( + final NodeIdentifierWithPredicates argument, + final CompositeNode node) { + final HashMap> ret = new HashMap>(); + for (final Entry keyValue : argument.getKeyValues() + .entrySet()) { + final List> simpleNode = node + .getSimpleNodesByName(keyValue.getKey()); + if (simpleNode != null && !simpleNode.isEmpty()) { + checkState( + simpleNode.size() <= 1, + "Only one simple node for key $s is allowed in node $s", + keyValue.getKey(), node); + checkState( + simpleNode.get(0).getValue() == keyValue.getValue(), + "Key node must equal to instance identifier value in node $s", + node); + ret.put(keyValue.getKey(), simpleNode.get(0)); + } + final List compositeNode = node + .getCompositesByName(keyValue.getKey()); + checkState(compositeNode == null || compositeNode.isEmpty(), + "Key node must be Simple Node, not composite node."); + } + return ret; + } + + public Map> getKeyNodes( + final InstanceIdentifier.PathArgument argument, + final CompositeNode node) { + if (argument instanceof InstanceIdentifier.NodeIdentifierWithPredicates) { + return _getKeyNodes( + (InstanceIdentifier.NodeIdentifierWithPredicates) argument, + node); + } else if (argument != null) { + return _getKeyNodes(argument, node); + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays. asList(argument, node).toString()); + } + } + + private Collection> childrenWithout( + final CompositeNode node, + final Set>> entries) { + if (entries.isEmpty()) { + return node.getValue(); + } + final List> filteredNodes = new ArrayList>(); + for (final Node scannedNode : node.getValue()) { + if (!entries.contains(scannedNode.getNodeType())) { + filteredNodes.add(scannedNode); + } + } + return filteredNodes; + } + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend deleted file mode 100644 index 95d0018b21..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/DataReaderRouter.xtend +++ /dev/null @@ -1,106 +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.sal.dom.broker.impl - -import java.net.URI -import java.util.ArrayList -import java.util.Collection -import java.util.Collections -import java.util.HashMap -import java.util.Map -import java.util.Map.Entry -import java.util.Set -import org.opendaylight.controller.md.sal.common.impl.routing.AbstractDataReadRouter -import org.opendaylight.yangtools.yang.common.QName -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument -import org.opendaylight.yangtools.yang.data.api.Node -import org.opendaylight.yangtools.yang.data.api.SimpleNode -import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl -import org.slf4j.LoggerFactory - -import static com.google.common.base.Preconditions.* - -class DataReaderRouter extends AbstractDataReadRouter { - private static val LOG = LoggerFactory.getLogger(DataReaderRouter); - private static val NETCONF_NAMESPACE = URI.create("urn:ietf:params:xml:ns:netconf:base:1.0") - private static val NETCONF_DATA = new QName(NETCONF_NAMESPACE,"data"); - - override protected merge(InstanceIdentifier path, Iterable data) { - val pathArgument = path.path.last; - var empty = true; - var name = pathArgument?.nodeType; - val nodes = new ArrayList>(); - val keyNodes = new HashMap>(); - for(dataBit : data) { - try { - if(pathArgument != null && dataBit != null) { - empty = false; - val keyNodesLocal = getKeyNodes(pathArgument,dataBit); - nodes.addAll(dataBit.childrenWithout(keyNodesLocal.entrySet)); - } else if (dataBit != null) { - empty = false; - nodes.addAll(dataBit.children) - } - } catch (IllegalStateException e) { - LOG.error("BUG: Readed data for path {} was invalid",path,e); - } - } - if(empty) { - return null; - } - /** - * Reading from Root - * - */ - if(pathArgument == null) { - return new CompositeNodeTOImpl(NETCONF_DATA,null,nodes); - } - val finalNodes = new ArrayList>(); - finalNodes.addAll(keyNodes.values); - finalNodes.addAll(nodes); - return new CompositeNodeTOImpl(name,null,finalNodes); - } - - - - dispatch def Map> getKeyNodes(PathArgument argument, CompositeNode node) { - return Collections.emptyMap(); - } - - dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) { - val ret = new HashMap>(); - for (keyValue : argument.keyValues.entrySet) { - val simpleNode = node.getSimpleNodesByName(keyValue.key); - if(simpleNode !== null && !simpleNode.empty) { - checkState(simpleNode.size <= 1,"Only one simple node for key $s is allowed in node $s",keyValue.key,node); - checkState(simpleNode.get(0).value == keyValue.value,"Key node must equal to instance identifier value in node $s",node); - ret.put(keyValue.key,simpleNode.get(0)); - } - val compositeNode = node.getCompositesByName(keyValue.key); - checkState(compositeNode === null || compositeNode.empty,"Key node must be Simple Node, not composite node."); - } - return ret; - } - - def Collection> childrenWithout(CompositeNode node, Set>> entries) { - if(entries.empty) { - return node.children; - } - val filteredNodes = new ArrayList>(); - for(scannedNode : node.children) { - if(!entries.contains(scannedNode.nodeType)) { - filteredNodes.add(scannedNode); - } - } - return filteredNodes; - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.java new file mode 100644 index 0000000000..50dfbe852b --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker.impl; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler; +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.controller.sal.common.util.Rpcs; +import org.opendaylight.controller.sal.core.api.data.DataStore; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public final class HashMapDataStore implements DataStore, AutoCloseable { + private static final Logger LOG = LoggerFactory + .getLogger(HashMapDataStore.class); + + private final Map configuration = new ConcurrentHashMap(); + private final Map operational = new ConcurrentHashMap(); + + @Override + public boolean containsConfigurationPath(final InstanceIdentifier path) { + return configuration.containsKey(path); + } + + @Override + public boolean containsOperationalPath(final InstanceIdentifier path) { + return operational.containsKey(path); + } + + @Override + public Iterable getStoredConfigurationPaths() { + return configuration.keySet(); + } + + @Override + public Iterable getStoredOperationalPaths() { + return operational.keySet(); + } + + @Override + public CompositeNode readConfigurationData(final InstanceIdentifier path) { + LOG.trace("Reading configuration path {}", path); + return configuration.get(path); + } + + @Override + public CompositeNode readOperationalData(InstanceIdentifier path) { + LOG.trace("Reading operational path {}", path); + return operational.get(path); + } + + @Override + public DataCommitHandler.DataCommitTransaction requestCommit( + final DataModification modification) { + return new HashMapDataStoreTransaction(modification, this); + } + + public RpcResult rollback(HashMapDataStoreTransaction transaction) { + return Rpcs. getRpcResult(true, null, + Collections. emptySet()); + } + + public RpcResult finish(HashMapDataStoreTransaction transaction) { + final DataModification modification = transaction + .getModification(); + for (final InstanceIdentifier removal : modification + .getRemovedConfigurationData()) { + LOG.trace("Removing configuration path {}", removal); + remove(configuration, removal); + } + for (final InstanceIdentifier removal : modification + .getRemovedOperationalData()) { + LOG.trace("Removing operational path {}", removal); + remove(operational, removal); + } + if (LOG.isTraceEnabled()) { + for (final InstanceIdentifier a : modification + .getUpdatedConfigurationData().keySet()) { + LOG.trace("Adding configuration path {}", a); + } + for (final InstanceIdentifier a : modification + .getUpdatedOperationalData().keySet()) { + LOG.trace("Adding operational path {}", a); + } + } + configuration.putAll(modification.getUpdatedConfigurationData()); + operational.putAll(modification.getUpdatedOperationalData()); + + return Rpcs. getRpcResult(true, null, + Collections. emptySet()); + } + + public void remove(final Map map, + final InstanceIdentifier identifier) { + Set affected = new HashSet(); + for (final InstanceIdentifier path : map.keySet()) { + if (identifier.contains(path)) { + affected.add(path); + } + } + for (final InstanceIdentifier pathToRemove : affected) { + LOG.trace("Removed path {}", pathToRemove); + map.remove(pathToRemove); + } + } + + @Override + public void close() { + // NOOP + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend deleted file mode 100644 index 12835ccf0a..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStore.xtend +++ /dev/null @@ -1,141 +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.sal.dom.broker.impl - -import org.opendaylight.controller.md.sal.common.api.data.DataModification -import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction -import org.opendaylight.yangtools.yang.common.RpcResult -import java.util.Map -import java.util.concurrent.ConcurrentHashMap -import org.opendaylight.controller.sal.common.util.Rpcs -import java.util.Collections -import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.controller.sal.core.api.data.DataStore -import java.util.HashSet -import org.slf4j.LoggerFactory -import org.slf4j.Logger - -final class HashMapDataStore implements DataStore, AutoCloseable { - private val Logger LOG = LoggerFactory.getLogger(HashMapDataStore) - - val Map configuration = new ConcurrentHashMap(); - val Map operational = new ConcurrentHashMap(); - - - - override containsConfigurationPath(InstanceIdentifier path) { - return configuration.containsKey(path) - } - - override containsOperationalPath(InstanceIdentifier path) { - return operational.containsKey(path) - } - - override getStoredConfigurationPaths() { - configuration.keySet - } - - override getStoredOperationalPaths() { - operational.keySet - } - - override readConfigurationData(InstanceIdentifier path) { - LOG.trace("Reading configuration path {}", path) - configuration.get(path); - } - - override readOperationalData(InstanceIdentifier path) { - LOG.trace("Reading operational path {}", path) - operational.get(path); - } - - - - override requestCommit(DataModification modification) { - return new HashMapDataStoreTransaction(modification, this); - } - - def RpcResult rollback(HashMapDataStoreTransaction transaction) { - return Rpcs.getRpcResult(true, null, Collections.emptySet); - } - - def RpcResult finish(HashMapDataStoreTransaction transaction) { - val modification = transaction.modification; - for (removal : modification.removedConfigurationData) { - LOG.trace("Removing configuration path {}", removal) - remove(configuration,removal); - } - for (removal : modification.removedOperationalData) { - LOG.trace("Removing operational path {}", removal) - remove(operational,removal); - } - if (LOG.isTraceEnabled()) { - for (a : modification.updatedConfigurationData.keySet) { - LOG.trace("Adding configuration path {}", a) - } - for (a : modification.updatedOperationalData.keySet) { - LOG.trace("Adding operational path {}", a) - } - } - configuration.putAll(modification.updatedConfigurationData); - operational.putAll(modification.updatedOperationalData); - - return Rpcs.getRpcResult(true, null, Collections.emptySet); - } - - def remove(Map map, InstanceIdentifier identifier) { - val affected = new HashSet(); - for(path : map.keySet) { - if(identifier.contains(path)) { - affected.add(path); - } - } - for(pathToRemove : affected) { - LOG.trace("Removed path {}", pathToRemove) - map.remove(pathToRemove); - } - - } - - - override close() { - // NOOP - } - -} - -class HashMapDataStoreTransaction implements // -DataCommitTransaction { - @Property - val DataModification modification - - @Property - val HashMapDataStore datastore; - - new( - DataModification modify, - HashMapDataStore store - ) { - _modification = modify; - _datastore = store; - } - - override finish() throws IllegalStateException { - datastore.finish(this); - - } - - override getModification() { - this._modification; - } - - override rollback() throws IllegalStateException { - datastore.rollback(this); - } -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStoreTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStoreTransaction.java new file mode 100644 index 0000000000..bb66594ac9 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/impl/HashMapDataStoreTransaction.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker.impl; + +import org.opendaylight.controller.md.sal.common.api.data.DataModification; +import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; + +public class HashMapDataStoreTransaction implements + DataCommitTransaction { + private final DataModification modification; + private final HashMapDataStore datastore; + + HashMapDataStoreTransaction( + final DataModification modify, + final HashMapDataStore store) { + modification = modify; + datastore = store; + } + + @Override + public RpcResult finish() throws IllegalStateException { + return datastore.finish(this); + } + + @Override + public DataModification getModification() { + return this.modification; + } + + @Override + public RpcResult rollback() throws IllegalStateException { + return datastore.rollback(this); + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.java new file mode 100644 index 0000000000..c2d6add17a --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker.osgi; + +import java.util.Arrays; + +import org.opendaylight.controller.sal.core.api.BrokerService; +import org.osgi.framework.ServiceReference; +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.notify.NotificationPublishService; +import org.opendaylight.controller.sal.core.api.notify.NotificationService; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; +import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; + +@SuppressWarnings("unchecked") +public class ProxyFactory { + + public static T createProxy( + final ServiceReference serviceRef, final T service) { + + Object _createProxyImpl = ProxyFactory.createProxyImpl(serviceRef, + service); + return ((T) _createProxyImpl); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final DataBrokerService service) { + + return new DataBrokerServiceProxy( + ((ServiceReference) ref), service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final DataProviderService service) { + + return new DataProviderServiceProxy( + ((ServiceReference) ref), service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final NotificationPublishService service) { + + return new NotificationPublishServiceProxy( + ((ServiceReference) ref), service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final NotificationService service) { + + return new NotificationServiceProxy( + ((ServiceReference) ref), service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final MountProvisionService service) { + + return new MountProviderServiceProxy( + ((ServiceReference) ref), service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final SchemaService service) { + + return new SchemaServiceProxy(((ServiceReference) ref), + service); + } + + private static Object _createProxyImpl(final ServiceReference ref, + final RpcProvisionRegistry service) { + + return new RpcProvisionRegistryProxy( + ((ServiceReference) ref), service); + } + + private static DOMDataBrokerProxy _createProxyImpl( + final ServiceReference ref, final DOMDataBroker service) { + + return new DOMDataBrokerProxy(((ServiceReference) ref), + service); + } + + private static Object _createProxyImpl(final ServiceReference reference, + final BrokerService service) { + + throw new IllegalArgumentException("Not supported class: " + + service.getClass().getName()); + } + + private static Object createProxyImpl(final ServiceReference ref, + final BrokerService service) { + + if (service instanceof DOMDataBroker) { + return _createProxyImpl(ref, (DOMDataBroker) service); + } else if (service instanceof RpcProvisionRegistry) { + return _createProxyImpl(ref, (RpcProvisionRegistry) service); + } else if (service instanceof DataProviderService) { + return _createProxyImpl(ref, (DataProviderService) service); + } else if (service instanceof MountProvisionService) { + return _createProxyImpl(ref, (MountProvisionService) service); + } else if (service instanceof NotificationPublishService) { + return _createProxyImpl(ref, (NotificationPublishService) service); + } else if (service instanceof DataBrokerService) { + return _createProxyImpl(ref, (DataBrokerService) service); + } else if (service instanceof SchemaService) { + return _createProxyImpl(ref, (SchemaService) service); + } else if (service instanceof NotificationService) { + return _createProxyImpl(ref, (NotificationService) service); + } else if (service != null) { + return _createProxyImpl(ref, service); + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays. asList(ref, service).toString()); + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.xtend deleted file mode 100644 index d0afc3f47d..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/ProxyFactory.xtend +++ /dev/null @@ -1,66 +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.sal.dom.broker.osgi - -import org.opendaylight.controller.sal.core.api.BrokerService -import org.osgi.framework.ServiceReference -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.notify.NotificationPublishService -import org.opendaylight.controller.sal.core.api.notify.NotificationService -import org.opendaylight.controller.sal.core.api.model.SchemaService -import org.opendaylight.controller.sal.core.api.mount.MountProvisionService -import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker - -class ProxyFactory { - - static def T createProxy(ServiceReference serviceRef, T service) { - return createProxyImpl(serviceRef, service) as T; - } - - - private static def dispatch createProxyImpl(ServiceReference ref, DataBrokerService service) { - new DataBrokerServiceProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, DataProviderService service) { - new DataProviderServiceProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, NotificationPublishService service) { - new NotificationPublishServiceProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, NotificationService service) { - new NotificationServiceProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, MountProvisionService service) { - new MountProviderServiceProxy(ref as ServiceReference, service); - } - - - private static def dispatch createProxyImpl(ServiceReference ref, SchemaService service) { - new SchemaServiceProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, RpcProvisionRegistry service) { - new RpcProvisionRegistryProxy(ref as ServiceReference, service); - } - - private static def dispatch createProxyImpl(ServiceReference ref, DOMDataBroker service) { - new DOMDataBrokerProxy(ref as ServiceReference, service) - } - - - private static def dispatch createProxyImpl(ServiceReference reference, BrokerService service) { - throw new IllegalArgumentException("Not supported class"); - } - -} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java new file mode 100644 index 0000000000..0f8ce1d95d --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.dom.broker.util; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.CompositeNode; +import org.opendaylight.yangtools.yang.data.api.Node; +import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Iterables; + +public class YangDataOperations { + + public static CompositeNode merge(final DataSchemaNode schema, + final CompositeNode stored, final CompositeNode modified, + final boolean config) { + if (stored == null) { + return modified; + } + + Preconditions.checkArgument(schema instanceof ListSchemaNode + || schema instanceof ContainerSchemaNode, + "Supplied node is not data node container."); + + return YangDataOperations.mergeContainer((DataNodeContainer) schema, + stored, modified, config); + } + + private static Iterable> _mergeMultiple( + final LeafSchemaNode node, final List> original, + final List> modified, final boolean configurational) { + checkArgument(original.size() == 1); + checkArgument(modified.size() == 1); + + return modified; + } + + private static Iterable> _mergeMultiple( + final LeafListSchemaNode node, final List> original, + final List> modified, final boolean configurational) { + return modified; + } + + private static Iterable> _mergeMultiple( + final ContainerSchemaNode node, final List> original, + final List> modified, final boolean configurational) { + checkArgument(original.size() == 1); + checkArgument(modified.size() == 1); + return Collections.singletonList(merge(node, + (CompositeNode) original.get(0), + (CompositeNode) modified.get(0), configurational)); + } + + private static Iterable> _mergeMultiple( + final ListSchemaNode node, final List> original, + final List> modified, final boolean configurational) { + + if (node.getKeyDefinition() == null + || node.getKeyDefinition().isEmpty()) { + return modified; + } + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Map, CompositeNode> originalMap = YangDataUtils + .toIndexMap((List) original, node.getKeyDefinition()); + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Map, CompositeNode> modifiedMap = YangDataUtils + .toIndexMap((List) modified, node.getKeyDefinition()); + + final List> mergedNodes = new ArrayList>( + original.size() + modified.size()); + for (final Map.Entry, CompositeNode> entry : modifiedMap + .entrySet()) { + final CompositeNode originalEntry = originalMap.get(entry.getKey()); + if (originalEntry != null) { + originalMap.remove(entry.getKey()); + mergedNodes.add(merge(node, originalEntry, entry.getValue(), + configurational)); + } else { + mergedNodes.add(entry.getValue()); + } + } + mergedNodes.addAll(originalMap.values()); + return mergedNodes; + } + + private static Iterable> mergeMultiple( + final DataSchemaNode node, final List> original, + final List> modified, final boolean configurational) { + if (node instanceof ContainerSchemaNode) { + return _mergeMultiple((ContainerSchemaNode) node, original, + modified, configurational); + } else if (node instanceof LeafListSchemaNode) { + return _mergeMultiple((LeafListSchemaNode) node, original, + modified, configurational); + } else if (node instanceof LeafSchemaNode) { + return _mergeMultiple((LeafSchemaNode) node, original, modified, + configurational); + } else if (node instanceof ListSchemaNode) { + return _mergeMultiple((ListSchemaNode) node, original, modified, + configurational); + } else { + throw new IllegalArgumentException("Unhandled parameter types: " + + Arrays. asList(node, original, modified, + configurational).toString()); + } + } + + private static CompositeNode mergeContainer(final DataNodeContainer schema, + final CompositeNode stored, final CompositeNode modified, + final boolean config) { + if (stored == null) { + return modified; + } + Preconditions.checkNotNull(stored); + Preconditions.checkNotNull(modified); + Preconditions.checkArgument(Objects.equals(stored.getNodeType(), + modified.getNodeType())); + + final List> mergedChildNodes = new ArrayList>(stored + .getChildren().size() + modified.getChildren().size()); + final Set toProcess = new HashSet(stored.keySet()); + toProcess.addAll(modified.keySet()); + + for (QName qname : toProcess) { + final DataSchemaNode schemaChild = schema.getDataChildByName(qname); + final List> storedChildren = stored.get(qname); + final List> modifiedChildren = modified.get(qname); + + if (modifiedChildren != null && !modifiedChildren.isEmpty()) { + if (storedChildren == null || storedChildren.isEmpty() + || schemaChild == null) { + mergedChildNodes.addAll(modifiedChildren); + } else { + final Iterable> _mergeMultiple = mergeMultiple( + schemaChild, storedChildren, modifiedChildren, + config); + Iterables.addAll(mergedChildNodes, _mergeMultiple); + } + } else if (storedChildren != null && !storedChildren.isEmpty()) { + mergedChildNodes.addAll(storedChildren); + } + } + return new CompositeNodeTOImpl(stored.getNodeType(), null, + mergedChildNodes); + } +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.xtend b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.xtend deleted file mode 100644 index d80e405b4e..0000000000 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/util/YangDataOperations.xtend +++ /dev/null @@ -1,117 +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.sal.dom.broker.util - -import org.opendaylight.yangtools.yang.data.api.CompositeNode -import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode -import static com.google.common.base.Preconditions.*; -import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl -import java.util.ArrayList - -import org.opendaylight.yangtools.yang.model.api.DataNodeContainer -import org.opendaylight.yangtools.yang.model.api.ListSchemaNode -import org.opendaylight.yangtools.yang.data.api.Node -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode -import java.util.List -import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode -import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode -import java.util.Collections -import java.util.HashSet -import org.opendaylight.yangtools.yang.common.QName -import static extension org.opendaylight.controller.sal.dom.broker.util.YangDataUtils.*; - -class YangDataOperations { - - static def CompositeNode merge(DataSchemaNode schema, CompositeNode stored, CompositeNode modified, boolean config) { - if (stored === null) { - return modified; - } - - if (schema instanceof ListSchemaNode || schema instanceof ContainerSchemaNode) { - return mergeContainer(schema as DataNodeContainer, stored, modified, config); - } - throw new IllegalArgumentException("Supplied node is not data node container."); - } - - private static dispatch def Iterable> mergeMultiple(LeafSchemaNode node, List> original, - List> modified, boolean configurational) { - checkArgument(original.size === 1); - checkArgument(modified.size === 1); - - return modified; - } - - private static dispatch def Iterable> mergeMultiple(LeafListSchemaNode node, - List> original, List> modified, boolean configurational) { - return modified; - } - - private static dispatch def Iterable> mergeMultiple(ContainerSchemaNode node, - List> original, List> modified, boolean configurational) { - checkArgument(original.size === 1); - checkArgument(modified.size === 1); - return Collections.singletonList( - merge(node, original.get(0) as CompositeNode, modified.get(0) as CompositeNode, configurational)); - } - - private static dispatch def Iterable> mergeMultiple(ListSchemaNode node, List> original, - List> modified, boolean configurational) { - - if(node.keyDefinition === null || node.keyDefinition.empty) { - return modified; - } - val originalMap = (original as List).toIndexMap(node.keyDefinition); - val modifiedMap = (modified as List).toIndexMap(node.keyDefinition); - - val List> mergedNodes = new ArrayList(original.size + modified.size); - for(entry : modifiedMap.entrySet) { - val originalEntry = originalMap.get(entry.key); - if(originalEntry != null) { - originalMap.remove(entry.key); - mergedNodes.add(merge(node,originalEntry,entry.value,configurational)); - } else { - mergedNodes.add(entry.value); - } - } - mergedNodes.addAll(originalMap.values); - return mergedNodes; - } - - static private def CompositeNode mergeContainer(DataNodeContainer schema, CompositeNode stored, - CompositeNode modified, boolean config) { - if (stored == null) { - return modified; - } - checkNotNull(stored) - checkNotNull(modified) - checkArgument(stored.nodeType == modified.nodeType); - - val mergedChildNodes = new ArrayList>(stored.children.size + modified.children.size); - - val toProcess = new HashSet(stored.keySet); - toProcess.addAll(modified.keySet); - - for (qname : toProcess) { - val schemaChild = schema.getDataChildByName(qname); - val storedChildren = stored.get(qname); - val modifiedChildren = modified.get(qname); - - if (modifiedChildren !== null && !modifiedChildren.empty) { - if (storedChildren === null || storedChildren.empty || schemaChild === null) { - mergedChildNodes.addAll(modifiedChildren); - } else { - mergedChildNodes.addAll(mergeMultiple(schemaChild, storedChildren, modifiedChildren, config)); - } - } else if (storedChildren !== null && !storedChildren.empty) { - mergedChildNodes.addAll(storedChildren); - } - } - return new CompositeNodeTOImpl(stored.nodeType, null, mergedChildNodes); - } - -} diff --git a/opendaylight/md-sal/sal-dom-it/pom.xml b/opendaylight/md-sal/sal-dom-it/pom.xml deleted file mode 100644 index 5604a87552..0000000000 --- a/opendaylight/md-sal/sal-dom-it/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-dom-it - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - - org.opendaylight.controller - sal-broker-impl - 1.0-SNAPSHOT - - - org.opendaylight.controller - yang-data-util - - - org.mockito - mockito-all - 1.9.5 - test - - - org.slf4j - slf4j-simple - 1.7.2 - runtime - - - - - - maven-assembly-plugin - 2.4 - - - jar-with-dependencies - - - - org.opendaylight.controller.sal.demo.SALDemo - - - - - - make-assembly - package - - single - - - - - - - diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStore.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStore.java index c82a2b855f..138b726edb 100644 --- a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStore.java +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStore.java @@ -10,51 +10,61 @@ package org.opendaylight.controller.sal.core.spi.data; 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.common.api.data.DataChangeListener; +import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -public interface DOMStore { +/** + * DOM Data Store + * + *

+ * DOM Data Store provides transactional tree-like storage for YANG-modeled + * entities described by YANG schema and represented by {@link NormalizedNode}. + * + * Read and write access to stored data is provided only via transactions + * created using {@link #newReadOnlyTransaction()}, + * {@link #newWriteOnlyTransaction()} and {@link #newReadWriteTransaction()}, or + * by creating {@link TransactionChain}. + * + */ +public interface DOMStore extends DOMStoreTransactionFactory { /** + * Registers {@link DataChangeListener} for Data Change callbacks which will + * be triggered on the change of provided subpath. What constitutes a change + * depends on the @scope parameter. * - * Creates a read only transaction + * Listener upon registration receives an initial callback + * {@link AsyncDataChangeListener#onDataChanged(org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent)} + * which contains stable view of data tree at the time of registration. * - * @return - */ - DOMStoreReadTransaction newReadOnlyTransaction(); - - /** - * Creates write only transaction + *  @param path Path (subtree identifier) on which client listener will be + * invoked. * - * @return - */ - DOMStoreWriteTransaction newWriteOnlyTransaction(); - - /** - * Creates Read-Write transaction + * @param listener + * Instance of listener which should be invoked on + * @param scope + * Scope of change which triggers callback. + * @return Listener Registration object, which client may use to close + * registration / interest on receiving data changes. * - * @return */ - DOMStoreReadWriteTransaction newReadWriteTransaction(); + >> ListenerRegistration registerChangeListener( + InstanceIdentifier path, L listener, DataChangeScope scope); /** - * Registers {@link DataChangeListener} for Data Change callbacks - * which will be triggered on the change of provided subpath. What - * constitutes a change depends on the @scope parameter. * - * Listener upon registration receives an initial callback - * {@link AsyncDataChangeListener#onDataChanged(org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent)} - * which contains stable view of data tree at the time of registration. + * Creates new transaction chain. + * + * Transactions in a chain need to be committed in sequence and each + * transaction should see the effects of previous transactions as if they + * happened. * - * @param path Path (subtree identifier) on which client listener will be invoked. - * @param listener Instance of listener which should be invoked on - * @param scope Scope of change which triggers callback. - * @return Listener Registration object, which client may use to close registration - * / interest on receiving data changes. + * See {@link DOMStoreTransactionChain} for more information. * + * @return Newly created transaction chain. */ - >> ListenerRegistration registerChangeListener( - InstanceIdentifier path, L listener, DataChangeScope scope); + DOMStoreTransactionChain createTransactionChain(); } diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionChain.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionChain.java new file mode 100644 index 0000000000..5876c50d51 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionChain.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.core.spi.data; + +/** + * A chain of transactions. Transactions in a chain need to be committed in + * sequence and each transaction must see the effects of previous transactions + * as if they happened. A chain makes no guarantees of atomicity, in fact + * transactions are committed as soon as possible. + * + * + */ +public interface DOMStoreTransactionChain extends DOMStoreTransactionFactory, AutoCloseable { + + /** + * Create a new read only transaction which will continue the chain. The + * previous write transaction has to be either READY or CANCELLED. + * + * If previous write transaction was already commited to data store, new + * read-only transaction is same as obtained via {@link DOMStore#newReadOnlyTransaction()} + * and contains merged result of previous one and current state of data store. + * + * Otherwise read-only transaction presents isolated view as if previous read-write + * transaction was successful. State which was introduced by other transactions + * outside this transaction chain after creation of previous transaction is not visible. + * + * @return New transaction in the chain. + * @throws IllegalStateException + * if the previous transaction was not READY or CANCELLED, or + * if the chain has been closed. + */ + @Override + public DOMStoreReadTransaction newReadOnlyTransaction(); + + /** + * Create a new read write transaction which will continue the chain. The + * previous read-write transaction has to be either COMMITED or CANCELLED. + * + * If previous write transaction was already commited to data store, new + * read-write transaction is same as obtained via {@link DOMStore#newReadWriteTransaction()} + * and contains merged result of previous one and current state of data store. + * + * Otherwise read-write transaction presents isolated view as if previous read-write + * transaction was successful. State which was introduced by other transactions + * outside this transaction chain after creation of previous transaction is not visible. + * + * @return New transaction in the chain. + * @throws IllegalStateException + * if the previous transaction was not READY or CANCELLED, or + * if the chain has been closed. + */ + @Override + public DOMStoreReadWriteTransaction newReadWriteTransaction(); + + /** + * Create a new read write transaction which will continue the chain. The + * previous read-write transaction has to be either READY or CANCELLED. + * + * + * @return New transaction in the chain. + * @throws IllegalStateException + * if the previous transaction was not READY or CANCELLED, or + * if the chain has been closed. + */ + @Override + public DOMStoreWriteTransaction newWriteOnlyTransaction(); + + + /** + * Closes Transaction Chain. + * + * Close method of transaction chain does not guarantee that + * last alocated transaction is ready or was submitted. + * + * @throws IllegalStateException If any of the outstanding created transactions was not canceled or ready. + */ + @Override + public void close(); + +} diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionFactory.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionFactory.java new file mode 100644 index 0000000000..433d575cd1 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreTransactionFactory.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.sal.core.spi.data; + +/** + * Factory for DOM Store Transactions + * + *

+ * Factory provides method to construct read-only, read-write and write-only + * transactions, which may be used to retrieve and modify stored information in + * Underlying {@link DOMStore} or {@link DOMStoreTransactionChain}. + * + *

+ * See {@link DOMStore} or {@link DOMStoreTransactionChain} for concrete + * variations of this factory. + * + *

+ * Note: This interface is used only to define common functionality + * between {@link DOMStore} and {@link DOMStoreTransactionChain}, which + * further specify behaviour of returned transactions. + * + */ +public interface DOMStoreTransactionFactory { + + /** + * + * Creates a read only transaction + * + *

+ * Creates a new read-only transaction, which provides read access to + * snapshot of current state. + * + * See {@link DOMStoreReadTransaction} for more information. + * + * @return new {@link DOMStoreReadTransaction} + * @throws IllegalStateException + * If state of factory prevents allocating new transaction. + * + */ + DOMStoreReadTransaction newReadOnlyTransaction(); + + /** + * Creates write only transaction + * + *

+ * See {@link DOMStoreWriteTransaction} for more information. + * + * @return new {@link DOMStoreWriteTransaction} + * @throws IllegalStateException If state of factory prevents allocating new transaction. + */ + DOMStoreWriteTransaction newWriteOnlyTransaction(); + + /** + * Creates Read-Write transaction + * + *

+ * See {@link DOMStoreReadWriteTransaction} for more information. + * + * @return new {@link DOMStoreWriteTransaction} + * @throws IllegalStateException If state of factory prevents allocating new transaction. + */ + DOMStoreReadWriteTransaction newReadWriteTransaction(); + +} diff --git a/opendaylight/md-sal/sal-schema-repository-api/.gitignore b/opendaylight/md-sal/sal-schema-repository-api/.gitignore deleted file mode 100644 index ea8c4bf7f3..0000000000 --- a/opendaylight/md-sal/sal-schema-repository-api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/opendaylight/md-sal/sal-schema-repository-api/pom.xml b/opendaylight/md-sal/sal-schema-repository-api/pom.xml deleted file mode 100644 index a6e5c78628..0000000000 --- a/opendaylight/md-sal/sal-schema-repository-api/pom.xml +++ /dev/null @@ -1,21 +0,0 @@ - - 4.0.0 - - org.opendaylight.controller - sal-parent - 1.0-SNAPSHOT - - sal-schema-repository-api - - scm:git:ssh://git.opendaylight.org:29418/controller.git - scm:git:ssh://git.opendaylight.org:29418/controller.git - https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL - - - - - org.opendaylight.controller - yang-model-api - - - diff --git a/opendaylight/md-sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java b/opendaylight/md-sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java deleted file mode 100644 index 39387f1414..0000000000 --- a/opendaylight/md-sal/sal-schema-repository-api/src/main/java/org/opendaylight/controller/sal/schema/api/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.schema.api; \ No newline at end of file