<containermanager.version>0.5.2-SNAPSHOT</containermanager.version>
<controllermanager.northbound.version>0.0.2-SNAPSHOT</controllermanager.northbound.version>
<corsfilter.version>7.0.42</corsfilter.version>
+ <ctrie.version>0.2.0</ctrie.version>
<devices.web.version>0.4.2-SNAPSHOT</devices.web.version>
<eclipse.persistence.version>2.5.0</eclipse.persistence.version>
<!-- enforcer version -->
<artifactId>jackson-module-jaxb-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.github.romix</groupId>
+ <artifactId>java-concurrent-hash-trie-map</artifactId>
+ <version>${ctrie.version}</version>
+ </dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
+
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<artifactId>restconf-client-impl</artifactId>
<version>${yangtools.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>util</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
<!-- yangtools dependencies -->
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>restconf-client-impl</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>util</artifactId>
+ </dependency>
<!-- yangtools dependencies I'm pretty sure we can trim -->
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+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<String,Object> properties() {
+ final Hashtable<String,Object> props = new Hashtable<String, Object>();
+ props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), NodeMapping.MD_SAL_TYPE);
+ props.put("protocolName", NodeMapping.MD_SAL_TYPE);
+ return props;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility
-
-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<String, Object> properties() {
- val props = new Hashtable<String, Object>();
- 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)
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility
-
-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;
- }
-
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+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<Flow, UUID> flowToFlowId = new ConcurrentHashMap<Flow, UUID>();
+ 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<? extends Object> 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<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow> 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<RpcResult<TransactionStatus>> 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<RpcResult<TransactionStatus>> internalAddFlowAsync(final Node node, final Flow flow, final long rid) {
+ final Map<Flow,UUID> 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<RpcResult<TransactionStatus>> internalModifyFlowAsync(final Node node, final Flow oldFlow, final Flow newFlow, final long rid) {
+ final Map<Flow,UUID> 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<RpcResult<TransactionStatus>> internalRemoveFlowAsync(final Node node, final Flow adflow, final long rid) {
+ final Map<Flow,UUID> 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<RpcResult<TransactionStatus>> future) {
+ if (future == null) {
+ // FIXME: really?
+ return FlowProgrammerAdapter.toStatus(true);
+ }
+
+ try {
+ final RpcResult<TransactionStatus> 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<Flow,UUID> getCache() {
+ final IClusterGlobalServices cgs = getClusterGlobalServices();
+ if (cgs == null) {
+ return new ConcurrentHashMap<Flow, UUID>();
+ }
+
+ Map<Flow, UUID> cache = (Map<Flow, UUID>) cgs.getCache(FlowProgrammerAdapter.CACHE_NAME);
+ if (cache != null) {
+ return cache;
+ }
+
+ try {
+ return (Map<Flow, UUID>) cgs.createCache(CACHE_NAME, EnumSet.of(cacheMode.TRANSACTIONAL));
+ } catch (CacheExistException e) {
+ return (Map<Flow, UUID>) cgs.getCache(CACHE_NAME);
+ } catch (CacheConfigException e) {
+ throw new IllegalStateException("Unexpected cache configuration problem", e);
+ }
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility
-
-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<Flow, UUID> flowToFlowId = new ConcurrentHashMap<Flow, UUID>();
-
-
- 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<RpcResult<TransactionStatus>> 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<RpcResult<TransactionStatus>> 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<RpcResult<TransactionStatus>> 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<RpcResult<TransactionStatus>> 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<RpcResult<TransactionStatus>> 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<Flow, UUID> getCache(){
- if(clusterGlobalServices == null){
- return new ConcurrentHashMap<Flow, UUID>();
- }
-
- 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<Flow, UUID>;
-
- }
-
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+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<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> toMDActions(final List<Action> actions) {
+ final ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> ret =
+ new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action>(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<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> 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()));
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility;
-
-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<Action>();
- 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<Action>();
- 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<Action> 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.<Instruction>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<Action>();
- 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();
- }
-
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility;
+
+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<? extends ProviderFunctionality> getFunctionality() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Collection<? extends RpcService> 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());
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility.topology;
+
+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> 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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility.topology
-
-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))
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility.topology;
+
+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<TopoEdgeUpdate> toADEdgeUpdates(final Topology topology,final TypeSafeDataReader reader) {
+ final List<TopoEdgeUpdate> result = new CopyOnWriteArrayList<>();
+ return FluentIterable.from(topology.getLink()).transform(
+ new Function<Link, TopoEdgeUpdate>() {
+ @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<Property> 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<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector> ncInstanceId =
+ (InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>) 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));
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility.topology
-
-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<TopoEdgeUpdate> result = new CopyOnWriteArrayList<TopoEdgeUpdate>()
- 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<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector>)
- if(ncInstanceId == null) {
- LOG.debug("Edge {} ncref {}",e,ncref)
- return null;
- }
- val nc = reader.readOperationalData(ncInstanceId)
- if(nc == null) {
- return null;
- }
- return nc.toADNodeConnectorProperties
- }
-
- 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);
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility.topology;
+
+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<Link> PATH = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class ,new TopologyKey(new TopologyId("flow:1")))
+ .child(Link.class)
+ .toInstance();
+ private TopologyCommitHandler commitHandler;
+
+ private ListenerRegistration<DataChangeListener> 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);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.compatibility.topology
-
-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<DataChangeListener> listenerRegistration
-
-
- def void start() {
-
- }
- def void startAdapter() {
- if(dataService == null){
- LOG.error("dataService not set");
- return;
- }
- commitHandler = new TopologyCommitHandler(dataService,topologyPublisher);
- val InstanceIdentifier<? extends DataObject> 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);
- }
- }
-
-}
--- /dev/null
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.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<? extends Object> cls, final String suffix) {
+ return cls.getName() + "$$Broker$" + suffix;
+ }
+
+ public static String getInvokerName(final Class<? extends NotificationListener> listener) {
+ return getGeneratedName(listener, RuntimeCodeSpecification.INVOKER_SUFFIX);
+ }
+
+ /**
+ * Returns a name for DirectProxy implementation
+ */
+ public static String getDirectProxyName(final Class<? extends RpcService> base) {
+ return getGeneratedName(base, RuntimeCodeSpecification.DIRECT_PROXY_SUFFIX);
+ }
+
+ /**
+ * Returns a name for Router implementation
+ */
+ public static String getRouterName(final Class<? extends RpcService> base) {
+ return getGeneratedName(base, RuntimeCodeSpecification.ROUTER_SUFFIX);
+ }
+
+ /**
+ * Returns a field name for specified routing context
+ */
+ public static String getRoutingTableField(final Class<? extends BaseIdentity> routingContext) {
+ return "_routes_" + routingContext.getSimpleName();
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.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<? extends NotificationListener> listener) {
- getGeneratedName(listener, INVOKER_SUFFIX);
- }
-
- /**
- * Returns a name for DirectProxy implementation
- *
- *
- */
- public static def getDirectProxyName(Class<? extends RpcService> base) {
- getGeneratedName(base, DIRECT_PROXY_SUFFIX);
- }
-
- /**
- * Returns a name for Router implementation
- *
- */
- public static def getRouterName(Class<? extends RpcService> 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<? extends BaseIdentity> routingContext) {
- return '''_routes_«routingContext.simpleName»'''.toString;
- }
-}
* 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
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(), // //
<packaging>bundle</packaging>
<dependencies>
+ <dependency>
+ <groupId>com.github.romix</groupId>
+ <artifactId>java-concurrent-hash-trie-map</artifactId>
+ </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
- <dependency>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>org.eclipse.xtend.lib</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>config-api</artifactId>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-spi</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>util</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-impl</artifactId>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-impl</artifactId>
</dependency>
+
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
org.opendaylight.yangtools.yang.util,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*</Private-Package>
<Import-Package>*</Import-Package>
+ <Embed-Dependency>java-concurrent-hash-trie-map;inline=true</Embed-Dependency>
</instructions>
</configuration>
</plugin>
- <plugin>
- <groupId>org.eclipse.xtend</groupId>
- <artifactId>xtend-maven-plugin</artifactId>
- </plugin>
<!-- TODO - unite yang-maven-plugin configuration in md-sal-->
<plugin>
<groupId>org.opendaylight.yangtools</groupId>
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;
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);
ready = true;
LOG.debug("Store transaction: {} : Ready", getIdentifier());
- mutableTree.seal();
+ mutableTree.ready();
return store.submit(this);
}
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;
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:
- * <ul>
- * <li>{@link #setRootPath(InstanceIdentifier)} - Root path of datastore
- * <li>{@link #setListenerRoot(ListenerTree)} - Root of listener registration
- * tree, which contains listeners to be notified
- * <li>{@link #setModificationRoot(NodeModification)} - Modification root, for
- * which events should be computed
- * <li>{@link #setBeforeRoot(Optional)} - State of before modification occurred
- * <li>{@link #setAfterRoot(Optional)} - State of after modification occurred
- * </ul>
- *
*/
final class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeListenerNotifyTask>> {
private static final Logger LOG = LoggerFactory.getLogger(ResolveDataChangeEventsTask.class);
private final DataTreeCandidate candidate;
private final ListenerTree listenerRoot;
- public ResolveDataChangeEventsTask(DataTreeCandidate candidate, ListenerTree listenerTree) {
+ public ResolveDataChangeEventsTask(final DataTreeCandidate candidate, final ListenerTree listenerTree) {
this.candidate = Preconditions.checkNotNull(candidate);
this.listenerRoot = Preconditions.checkNotNull(listenerTree);
}
* Implementation of done as Map-Reduce with two steps: 1. resolving events
* and their mapping to listeners 2. merging events affecting same listener
*
- * @return Iterable of Notification Tasks which needs to be executed in
+ * @return An {@link Iterable} of Notification Tasks which needs to be executed in
* order to delivery data change events.
*/
@Override
for (NormalizedNode<PathArgument, ?> beforeChild : beforeCont.getValue()) {
PathArgument childId = beforeChild.getIdentifier();
alreadyProcessed.add(childId);
- InstanceIdentifier childPath = append(path, childId);
+ InstanceIdentifier childPath = path.node(childId);
Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
Optional<NormalizedNode<PathArgument, ?>> afterChild = afterCont.getChild(childId);
DOMImmutableDataChangeEvent childChange = resolveNodeContainerChildUpdated(childPath, childListeners,
// and it was not present in previous loop, that means it is
// created.
Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
- InstanceIdentifier childPath = append(path,childId);
+ InstanceIdentifier childPath = path.node(childId);
childChanges.add(resolveSameEventRecursivelly(childPath , childListeners, afterChild,
DOMImmutableDataChangeEvent.getCreateEventFactory()));
}
PathArgument childId = child.getIdentifier();
LOG.trace("Resolving event for child {}", childId);
Collection<Node> 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 {
for (DataTreeCandidateNode childMod : modification.getChildNodes()) {
PathArgument childId = childMod.getIdentifier();
- InstanceIdentifier childPath = append(path, childId);
+ InstanceIdentifier childPath = path.node(childId);
Collection<ListenerTree.Node> childListeners = getListenerChildrenWildcarded(listeners, childId);
switch (childMod.getModificationType()) {
}
}
- public static ResolveDataChangeEventsTask create(DataTreeCandidate candidate, ListenerTree listenerTree) {
+ public static ResolveDataChangeEventsTask create(final DataTreeCandidate candidate, final ListenerTree listenerTree) {
return new ResolveDataChangeEventsTask(candidate, listenerTree);
}
}
import com.google.common.base.Preconditions;
+/**
+ * Exception thrown when a proposed change fails validation before being
+ * applied into the datastore. This can have multiple reasons, for example
+ * the datastore has been concurrently modified such that a conflicting
+ * node is present, or the modification is structurally incorrect.
+ */
public class DataPreconditionFailedException extends Exception {
private static final long serialVersionUID = 1L;
private final InstanceIdentifier path;
+ /**
+ * Create a new instance.
+ *
+ * @param path Object path which caused this exception
+ * @param message Specific message describing the failure
+ */
public DataPreconditionFailedException(final InstanceIdentifier path, final String message) {
- super(message);
- this.path = Preconditions.checkNotNull(path);
+ this(path, message, null);
}
-
+ /**
+ * Create a new instance, initializing
+ *
+ * @param path Object path which caused this exception
+ * @param message Specific message describing the failure
+ * @param cause Exception which triggered this failure, may be null
+ */
public DataPreconditionFailedException(final InstanceIdentifier path, final String message, final Throwable cause) {
super(message, cause);
this.path = Preconditions.checkNotNull(path);
}
+ /**
+ * Returns the offending object path.
+ *
+ * @return Path of the offending object
+ */
public InstanceIdentifier getPath() {
return path;
}
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+/**
+ * An encapsulation of a validated data tree modification. This candidate
+ * is ready for atomic commit to the datastore. It allows access to before-
+ * and after-state as it will be seen in to subsequent commit. This capture
+ * can be accessed for reference, but cannot be modified and the content
+ * is limited to nodes which were affected by the modification from which
+ * this instance originated.
+ */
public interface DataTreeCandidate {
+ /**
+ * Get the candidate tree root node.
+ *
+ * @return Candidate tree root node
+ */
DataTreeCandidateNode getRootNode();
+
+ /**
+ * Get the candidate tree root path. This is the path of the root node
+ * relative to the root of InstanceIdentifier namespace.
+ *
+ * @return Relative path of the root node
+ */
InstanceIdentifier getRootPath();
}
import com.google.common.base.Optional;
+/**
+ * A single node within a {@link DataTreeCandidate}. The nodes are organized
+ * in tree hierarchy, reflecting the modification from which this candidate
+ * was created. The node itself exposes the before- and after-image of the
+ * tree restricted to the modified nodes.
+ */
public interface DataTreeCandidateNode {
+ /**
+ * Get the node identifier.
+ *
+ * @return The node identifier.
+ */
PathArgument getIdentifier();
+
+ /**
+ * Get an unmodifiable iterable of modified child nodes.
+ *
+ * @return Unmodifiable iterable of modified child nodes.
+ */
Iterable<DataTreeCandidateNode> getChildNodes();
+ /**
+ * Return the type of modification this node is undergoing.
+ *
+ * @return Node modification type.
+ */
ModificationType getModificationType();
+
+ /**
+ * Return the before-image of data corresponding to the node.
+ *
+ * @return Node data as they were present in the tree before
+ * the modification was applied.
+ */
Optional<NormalizedNode<?, ?>> getDataAfter();
+
+ /**
+ * Return the after-image of data corresponding to the node.
+ *
+ * @return Node data as they will be present in the tree after
+ * the modification is applied.
+ */
Optional<NormalizedNode<?, ?>> getDataBefore();
}
* 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();
}
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();
}
}
}
+ /**
+ * 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.
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;
*/
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,
}
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 <C> Final node type
*/
public interface StoreTreeNode<C extends StoreTreeNode<C>> {
/**
- *
- * 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.
*/
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<Identifiable<Object>, Object> EXTRACT_IDENTIFIER = new Function<Identifiable<Object>, Object>() {
- @Override
- public Object apply(final Identifiable<Object> 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 <V> Function<Identifiable<V>, 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.<PathArgument> builder().addAll(parent.getPath()).add(arg).build());
- }
-
- public static <V> Set<V> toIdentifierSet(final Iterable<? extends Identifiable<V>> children) {
- return FluentIterable.from(children).transform(StoreUtils.<V> 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();
}
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;
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");
* @param tree Data Tree
* @param path Path to the node
* @return Optional with node if the node is present in tree, {@link Optional#absent()} otherwise.
- *
*/
public static <T extends StoreTreeNode<T>> Optional<T> findNode(final T tree, final InstanceIdentifier path) {
Optional<T> current = Optional.<T> of(tree);
final class AlwaysFailOperation implements ModificationApplyOperation {
@Override
public Optional<TreeNode> apply(final ModifiedNode modification,
- final Optional<TreeNode> storeMeta, final Version subtreeVersion) {
+ final Optional<TreeNode> storeMeta, final Version version) {
throw new IllegalStateException("Schema Context is not available.");
}
}
@Override
- public synchronized void seal() {
+ public synchronized void ready() {
Preconditions.checkState(!sealed, "Attempted to seal an already-sealed Data Tree.");
sealed = true;
rootNode.seal();
* @param storeMeta
* Store Metadata Node on which NodeModification should be
* applied
- * @param subtreeVersion New subtree version of parent node
+ * @param version New subtree version of parent node
* @throws IllegalArgumentException
* If it is not possible to apply Operation on provided Metadata
* node
* node, {@link Optional#absent()} if {@link ModifiedNode}
* resulted in deletion of this node.
*/
- Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version subtreeVersion);
+ Optional<TreeNode> apply(ModifiedNode modification, Optional<TreeNode> storeMeta, Version version);
/**
*
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<PathArgument> {
+ /**
+ * 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<TreeNode> getOriginal();
+
+ /**
+ * Get a read-only view of children nodes.
+ *
+ * @return Iterable of all children nodes.
+ */
Iterable<? extends NodeModification> getChildren();
}
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
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;
@Override
protected TreeNode applyWrite(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
- final Version nodeVersion;
- if (currentMeta.isPresent()) {
- nodeVersion = currentMeta.get().getVersion().next();
- } else {
- nodeVersion = subtreeVersion;
- }
-
+ final Optional<TreeNode> 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;
* 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" })
@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
final PathArgument childId = childMod.getIdentifier();
final Optional<TreeNode> childMeta = currentMeta.getChild(childId);
- InstanceIdentifier childPath = StoreUtils.append(path, childId);
+ InstanceIdentifier childPath = path.node(childId);
resolveChildOperation(childId).checkApplicable(childPath, childMod, childMeta);
}
}
return applyOperation;
}
- public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version subtreeVersion) {
- return applyOperation.apply(modification, data, subtreeVersion);
+ public Optional<TreeNode> apply(final Optional<TreeNode> data, final Version version) {
+ return applyOperation.apply(modification, data, version);
}
public static OperationWithModification from(final ModificationApplyOperation operation,
@Override
public final Optional<TreeNode> apply(final ModifiedNode modification,
- final Optional<TreeNode> currentMeta, final Version subtreeVersion) {
+ final Optional<TreeNode> currentMeta, final Version version) {
switch (modification.getType()) {
case DELETE:
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:
}
protected abstract TreeNode applyMerge(ModifiedNode modification,
- TreeNode currentMeta, Version subtreeVersion);
+ TreeNode currentMeta, Version version);
protected abstract TreeNode applyWrite(ModifiedNode modification,
- Optional<TreeNode> currentMeta, Version subtreeVersion);
+ Optional<TreeNode> 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<TreeNode> current) throws DataPreconditionFailedException;
@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<TreeNode> currentMeta, final Version subtreeVersion) {
- return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+ final Optional<TreeNode> currentMeta, final Version version) {
+ return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
}
@Override
@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<TreeNode> currentMeta, final Version subtreeVersion) {
- return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), subtreeVersion);
+ final Optional<TreeNode> currentMeta, final Version version) {
+ return TreeNodeFactory.createTreeNode(modification.getWrittenValue(), version);
}
@Override
import com.google.common.base.Preconditions;
-/*
+/**
* A very basic data tree node.
*/
abstract class AbstractTreeNode implements TreeNode {
*/
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;
}
private static final class Mutable implements MutableTreeNode {
- private final Map<PathArgument, TreeNode> children;
private final Version version;
+ private Map<PathArgument, TreeNode> 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();
}
@Override
public TreeNode seal() {
- final Map<PathArgument, TreeNode> 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
private static ContainerNode create(final Version version, final NormalizedNode<?, ?> data,
final Iterable<NormalizedNode<?, ?>> children) {
- final Map<PathArgument, TreeNode> map = new HashMap<>();
+ final Map<PathArgument, TreeNode> map = new HashMap<>();
for (NormalizedNode<?, ?> child : children) {
map.put(child.getIdentifier(), TreeNodeFactory.createTreeNode(child, version));
}
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<TreeNode> {
+ /**
+ * 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();
}
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.
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");
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);
--- /dev/null
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker;
+
+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<DataBrokerService> dataReg = null;
+ private ServiceRegistration<DataProviderService> dataProviderReg = null;
+ private ServiceRegistration<MountService> mountReg = null;
+ private ServiceRegistration<MountProvisionService> mountProviderReg = null;
+ private SchemaService schemaService = null;
+ private ServiceRegistration<RpcProvisionRegistry> 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<String, String> emptyProperties = new Hashtable<String, String>();
+ broker.setBundleContext(context);
+
+ final ServiceReference<SchemaService> serviceRef = context
+ .getServiceReference(SchemaService.class);
+ schemaService = context.<SchemaService> 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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.dom.broker
-
-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<DataBrokerService> dataReg;
- private var ServiceRegistration<DataProviderService> dataProviderReg;
- private var ServiceRegistration<MountService> mountReg;
- private var ServiceRegistration<MountProvisionService> mountProviderReg;
- private var SchemaService schemaService;
- private var ServiceRegistration<RpcProvisionRegistry> rpcProvisionRegistryReg;
- private var MountPointManagerImpl mountService;
-
- SchemaAwareDataStoreAdapter wrappedStore
-
- public def void start(BrokerImpl broker, DataStore store, DOMDataBroker asyncBroker,BundleContext context) {
- val emptyProperties = new Hashtable<String, String>();
- 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();
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.dom.broker;
+
+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<ConsumerContextImpl> sessions = Collections
+ .synchronizedSet(new HashSet<ConsumerContextImpl>());
+ private final Set<ProviderContextImpl> providerSessions = Collections
+ .synchronizedSet(new HashSet<ProviderContextImpl>());
+
+ 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<RpcResult<CompositeNode>> 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<RpcRegistrationListener> addRpcRegistrationListener(
+ final RpcRegistrationListener listener) {
+ return router.addRpcRegistrationListener(listener);
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> ListenerRegistration<L> registerRouteChangeListener(
+ final L listener) {
+ return router.registerRouteChangeListener(listener);
+ }
+
+ @Override
+ public Set<QName> getSupportedRpcs() {
+ return router.getSupportedRpcs();
+ }
+
+ @Override
+ public ListenableFuture<RpcResult<CompositeNode>> 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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.dom.broker;
-
-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<ConsumerContextImpl> sessions = Collections.synchronizedSet(new HashSet<ConsumerContextImpl>());
- private val Set<ProviderContextImpl> providerSessions = Collections.synchronizedSet(
- new HashSet<ProviderContextImpl>());
-
- @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<RpcResult<CompositeNode>> 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 <L extends RouteChangeListener<RpcRoutingContext, InstanceIdentifier>> registerRouteChangeListener(L listener) {
- return router.registerRouteChangeListener(listener);
- }
-
- override getSupportedRpcs() {
- return router.getSupportedRpcs();
- }
-
- override invokeRpc(QName rpc, CompositeNode input) {
- return router.invokeRpc(rpc,input)
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<BrokerService> 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<RpcResult<CompositeNode>> rpc(final QName rpc,
+ final CompositeNode input) {
+ return broker.invokeRpcAsync(rpc, input);
+ }
+
+ @Override
+ public <T extends BrokerService> T getService(final Class<T> service) {
+ final T localProxy = instantiatedServices.getInstance(service);
+ if (localProxy != null) {
+ return localProxy;
+ }
+ final ServiceReference<T> 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<BrokerService> 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;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<BrokerService> 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 extends BrokerService> T getService(Class<T> 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;
- }
-}
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<MountProvisionListener> listeners =
+ ListenerRegistry.create();
+ private final ConcurrentMap<InstanceIdentifier, MountPointImpl> 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<MountProvisionListener> 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<MountProvisionListener> registerProvisionListener(
+ final MountProvisionListener listener) {
+ return listeners.register(listener);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<MountProvisionListener> listeners = ListenerRegistry.create()
-
- ConcurrentMap<InstanceIdentifier,MountPointImpl> 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);
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<RpcRegistrationWrapper> 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<QName> getSupportedRpcs() {
+ return getBroker().getRouter().getSupportedRpcs();
+ }
+
+ @Override
+ public ListenerRegistration<RpcRegistrationListener> addRpcRegistrationListener(
+ final RpcRegistrationListener listener) {
+ return getBroker().getRouter().addRpcRegistrationListener(listener);
+ }
+
+ /**
+ * @return the provider
+ */
+ public Provider getProvider() {
+ return provider;
+ }
+
+ /**
+ * @param provider
+ * the provider to set
+ */
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<Registration<?>> 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
- }
-}
-
--- /dev/null
+/**
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<InstanceIdentifier, CompositeNode> {
+ 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<CompositeNode> data) {
+ PathArgument pathArgument = Iterables.getLast(path.getPath(), null);
+ boolean empty = true;
+ QName name = (pathArgument == null ? null : pathArgument.getNodeType());
+ final ArrayList<Node<?>> nodes = new ArrayList<Node<?>>();
+ final HashMap<QName, SimpleNode<?>> keyNodes = new HashMap<QName, SimpleNode<?>>();
+ for (final CompositeNode dataBit : data) {
+ try {
+ if (pathArgument != null && dataBit != null) {
+ empty = false;
+ final Map<QName, SimpleNode<?>> 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<Node<?>> finalNodes = new ArrayList<Node<?>>(
+ nodes.size() + keyNodes.size());
+ finalNodes.addAll(keyNodes.values());
+ finalNodes.addAll(nodes);
+ return new CompositeNodeTOImpl(name, null, finalNodes);
+ }
+
+ protected Map<QName, SimpleNode<?>> _getKeyNodes(
+ final PathArgument argument, final CompositeNode node) {
+ return Collections.emptyMap();
+ }
+
+ protected Map<QName, SimpleNode<?>> _getKeyNodes(
+ final NodeIdentifierWithPredicates argument,
+ final CompositeNode node) {
+ final HashMap<QName, SimpleNode<?>> ret = new HashMap<QName, SimpleNode<?>>();
+ for (final Entry<QName, Object> keyValue : argument.getKeyValues()
+ .entrySet()) {
+ final List<SimpleNode<?>> 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> compositeNode = node
+ .getCompositesByName(keyValue.getKey());
+ checkState(compositeNode == null || compositeNode.isEmpty(),
+ "Key node must be Simple Node, not composite node.");
+ }
+ return ret;
+ }
+
+ public Map<QName, SimpleNode<?>> 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.<Object> asList(argument, node).toString());
+ }
+ }
+
+ private Collection<? extends Node<?>> childrenWithout(
+ final CompositeNode node,
+ final Set<Entry<QName, SimpleNode<?>>> entries) {
+ if (entries.isEmpty()) {
+ return node.getValue();
+ }
+ final List<Node<?>> filteredNodes = new ArrayList<Node<?>>();
+ for (final Node<?> scannedNode : node.getValue()) {
+ if (!entries.contains(scannedNode.getNodeType())) {
+ filteredNodes.add(scannedNode);
+ }
+ }
+ return filteredNodes;
+ }
+
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<InstanceIdentifier, CompositeNode> {
- 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<CompositeNode> data) {
- val pathArgument = path.path.last;
- var empty = true;
- var name = pathArgument?.nodeType;
- val nodes = new ArrayList<Node<?>>();
- val keyNodes = new HashMap<QName, SimpleNode<?>>();
- 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<Node<?>>();
- finalNodes.addAll(keyNodes.values);
- finalNodes.addAll(nodes);
- return new CompositeNodeTOImpl(name,null,finalNodes);
- }
-
-
-
- dispatch def Map<QName, SimpleNode<?>> getKeyNodes(PathArgument argument, CompositeNode node) {
- return Collections.emptyMap();
- }
-
- dispatch def getKeyNodes(NodeIdentifierWithPredicates argument, CompositeNode node) {
- val ret = new HashMap<QName, SimpleNode<?>>();
- 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<? extends Node<?>> childrenWithout(CompositeNode node, Set<Entry<QName, SimpleNode<?>>> entries) {
- if(entries.empty) {
- return node.children;
- }
- val filteredNodes = new ArrayList<Node<?>>();
- for(scannedNode : node.children) {
- if(!entries.contains(scannedNode.nodeType)) {
- filteredNodes.add(scannedNode);
- }
- }
- return filteredNodes;
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap<InstanceIdentifier, CompositeNode>();
+ private final Map<InstanceIdentifier, CompositeNode> operational = new ConcurrentHashMap<InstanceIdentifier, CompositeNode>();
+
+ @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<InstanceIdentifier> getStoredConfigurationPaths() {
+ return configuration.keySet();
+ }
+
+ @Override
+ public Iterable<InstanceIdentifier> 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<InstanceIdentifier, CompositeNode> requestCommit(
+ final DataModification<InstanceIdentifier, CompositeNode> modification) {
+ return new HashMapDataStoreTransaction(modification, this);
+ }
+
+ public RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
+ return Rpcs.<Void> getRpcResult(true, null,
+ Collections.<RpcError> emptySet());
+ }
+
+ public RpcResult<Void> finish(HashMapDataStoreTransaction transaction) {
+ final DataModification<InstanceIdentifier, CompositeNode> 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.<Void> getRpcResult(true, null,
+ Collections.<RpcError> emptySet());
+ }
+
+ public void remove(final Map<InstanceIdentifier, CompositeNode> map,
+ final InstanceIdentifier identifier) {
+ Set<InstanceIdentifier> affected = new HashSet<InstanceIdentifier>();
+ 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
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<InstanceIdentifier, CompositeNode> configuration = new ConcurrentHashMap();
- val Map<InstanceIdentifier, CompositeNode> 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<InstanceIdentifier, CompositeNode> modification) {
- return new HashMapDataStoreTransaction(modification, this);
- }
-
- def RpcResult<Void> rollback(HashMapDataStoreTransaction transaction) {
- return Rpcs.getRpcResult(true, null, Collections.emptySet);
- }
-
- def RpcResult<Void> 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<InstanceIdentifier, CompositeNode> map, InstanceIdentifier identifier) {
- val affected = new HashSet<InstanceIdentifier>();
- 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<InstanceIdentifier, CompositeNode> {
- @Property
- val DataModification<InstanceIdentifier, CompositeNode> modification
-
- @Property
- val HashMapDataStore datastore;
-
- new(
- DataModification<InstanceIdentifier, CompositeNode> 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);
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<InstanceIdentifier, CompositeNode> {
+ private final DataModification<InstanceIdentifier, CompositeNode> modification;
+ private final HashMapDataStore datastore;
+
+ HashMapDataStoreTransaction(
+ final DataModification<InstanceIdentifier, CompositeNode> modify,
+ final HashMapDataStore store) {
+ modification = modify;
+ datastore = store;
+ }
+
+ @Override
+ public RpcResult<Void> finish() throws IllegalStateException {
+ return datastore.finish(this);
+ }
+
+ @Override
+ public DataModification<InstanceIdentifier, CompositeNode> getModification() {
+ return this.modification;
+ }
+
+ @Override
+ public RpcResult<Void> rollback() throws IllegalStateException {
+ return datastore.rollback(this);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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 extends BrokerService> T createProxy(
+ final ServiceReference<T> 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<DataBrokerService>) ref), service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final DataProviderService service) {
+
+ return new DataProviderServiceProxy(
+ ((ServiceReference<DataProviderService>) ref), service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final NotificationPublishService service) {
+
+ return new NotificationPublishServiceProxy(
+ ((ServiceReference<NotificationPublishService>) ref), service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final NotificationService service) {
+
+ return new NotificationServiceProxy(
+ ((ServiceReference<NotificationService>) ref), service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final MountProvisionService service) {
+
+ return new MountProviderServiceProxy(
+ ((ServiceReference<MountProvisionService>) ref), service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final SchemaService service) {
+
+ return new SchemaServiceProxy(((ServiceReference<SchemaService>) ref),
+ service);
+ }
+
+ private static Object _createProxyImpl(final ServiceReference<?> ref,
+ final RpcProvisionRegistry service) {
+
+ return new RpcProvisionRegistryProxy(
+ ((ServiceReference<RpcProvisionRegistry>) ref), service);
+ }
+
+ private static DOMDataBrokerProxy _createProxyImpl(
+ final ServiceReference<?> ref, final DOMDataBroker service) {
+
+ return new DOMDataBrokerProxy(((ServiceReference<DOMDataBroker>) 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.<Object> asList(ref, service).toString());
+ }
+ }
+}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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 extends BrokerService> T createProxy(ServiceReference<T> serviceRef, T service) {
- return createProxyImpl(serviceRef, service) as T;
- }
-
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, DataBrokerService service) {
- new DataBrokerServiceProxy(ref as ServiceReference<DataBrokerService>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, DataProviderService service) {
- new DataProviderServiceProxy(ref as ServiceReference<DataProviderService>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, NotificationPublishService service) {
- new NotificationPublishServiceProxy(ref as ServiceReference<NotificationPublishService>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, NotificationService service) {
- new NotificationServiceProxy(ref as ServiceReference<NotificationService>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, MountProvisionService service) {
- new MountProviderServiceProxy(ref as ServiceReference<MountProvisionService>, service);
- }
-
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, SchemaService service) {
- new SchemaServiceProxy(ref as ServiceReference<SchemaService>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, RpcProvisionRegistry service) {
- new RpcProvisionRegistryProxy(ref as ServiceReference<RpcProvisionRegistry>, service);
- }
-
- private static def dispatch createProxyImpl(ServiceReference<?> ref, DOMDataBroker service) {
- new DOMDataBrokerProxy(ref as ServiceReference<DOMDataBroker>, service)
- }
-
-
- private static def dispatch createProxyImpl(ServiceReference<?> reference, BrokerService service) {
- throw new IllegalArgumentException("Not supported class");
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.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<? extends Node<?>> _mergeMultiple(
+ final LeafSchemaNode node, final List<Node<?>> original,
+ final List<Node<?>> modified, final boolean configurational) {
+ checkArgument(original.size() == 1);
+ checkArgument(modified.size() == 1);
+
+ return modified;
+ }
+
+ private static Iterable<? extends Node<?>> _mergeMultiple(
+ final LeafListSchemaNode node, final List<Node<?>> original,
+ final List<Node<?>> modified, final boolean configurational) {
+ return modified;
+ }
+
+ private static Iterable<? extends Node<?>> _mergeMultiple(
+ final ContainerSchemaNode node, final List<Node<?>> original,
+ final List<Node<?>> 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<? extends Node<?>> _mergeMultiple(
+ final ListSchemaNode node, final List<Node<?>> original,
+ final List<Node<?>> modified, final boolean configurational) {
+
+ if (node.getKeyDefinition() == null
+ || node.getKeyDefinition().isEmpty()) {
+ return modified;
+ }
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final Map<Map<QName, Object>, CompositeNode> originalMap = YangDataUtils
+ .toIndexMap((List) original, node.getKeyDefinition());
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ final Map<Map<QName, Object>, CompositeNode> modifiedMap = YangDataUtils
+ .toIndexMap((List) modified, node.getKeyDefinition());
+
+ final List<Node<?>> mergedNodes = new ArrayList<Node<?>>(
+ original.size() + modified.size());
+ for (final Map.Entry<Map<QName, Object>, 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<? extends Node<?>> mergeMultiple(
+ final DataSchemaNode node, final List<Node<?>> original,
+ final List<Node<?>> 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.<Object> 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<Node<?>> mergedChildNodes = new ArrayList<Node<?>>(stored
+ .getChildren().size() + modified.getChildren().size());
+ final Set<QName> toProcess = new HashSet<QName>(stored.keySet());
+ toProcess.addAll(modified.keySet());
+
+ for (QName qname : toProcess) {
+ final DataSchemaNode schemaChild = schema.getDataChildByName(qname);
+ final List<Node<?>> storedChildren = stored.get(qname);
+ final List<Node<?>> modifiedChildren = modified.get(qname);
+
+ if (modifiedChildren != null && !modifiedChildren.isEmpty()) {
+ if (storedChildren == null || storedChildren.isEmpty()
+ || schemaChild == null) {
+ mergedChildNodes.addAll(modifiedChildren);
+ } else {
+ final Iterable<? extends Node<?>> _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);
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.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<? extends Node<?>> mergeMultiple(LeafSchemaNode node, List<Node<?>> original,
- List<Node<?>> modified, boolean configurational) {
- checkArgument(original.size === 1);
- checkArgument(modified.size === 1);
-
- return modified;
- }
-
- private static dispatch def Iterable<? extends Node<?>> mergeMultiple(LeafListSchemaNode node,
- List<Node<?>> original, List<Node<?>> modified, boolean configurational) {
- return modified;
- }
-
- private static dispatch def Iterable<? extends Node<?>> mergeMultiple(ContainerSchemaNode node,
- List<Node<?>> original, List<Node<?>> 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<? extends Node<?>> mergeMultiple(ListSchemaNode node, List<Node<?>> original,
- List<Node<?>> 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<Node<?>> 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<Node<?>>(stored.children.size + modified.children.size);
-
- val toProcess = new HashSet<QName>(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);
- }
-
-}
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-parent</artifactId>
- <version>1.0-SNAPSHOT</version>
- </parent>
- <artifactId>sal-dom-it</artifactId>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>
- </scm>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-broker-impl</artifactId>
- <version>1.0-SNAPSHOT</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>yang-data-util</artifactId>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-all</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>1.7.2</version>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- <build>
- <plugins>
- <plugin>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>2.4</version>
- <configuration>
- <descriptorRefs>
- <descriptorRef>jar-with-dependencies</descriptorRef>
- </descriptorRefs>
- <archive>
- <manifest>
- <mainClass>org.opendaylight.controller.sal.demo.SALDemo</mainClass>
- </manifest>
- </archive>
- </configuration>
- <executions>
- <execution>
- <id>make-assembly</id>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-</project>
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
+ *
+ * <p>
+ * 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();
+ <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> 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.
*/
- <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
- InstanceIdentifier path, L listener, DataChangeScope scope);
+ DOMStoreTransactionChain createTransactionChain();
}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.core.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();
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.core.spi.data;
+
+/**
+ * Factory for DOM Store Transactions
+ *
+ * <p>
+ * 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}.
+ *
+ * <p>
+ * See {@link DOMStore} or {@link DOMStoreTransactionChain} for concrete
+ * variations of this factory.
+ *
+ * <p>
+ * <b>Note:</b> 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
+ *
+ * <p>
+ * 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
+ *
+ * <p>
+ * 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
+ *
+ * <p>
+ * See {@link DOMStoreReadWriteTransaction} for more information.
+ *
+ * @return new {@link DOMStoreWriteTransaction}
+ * @throws IllegalStateException If state of factory prevents allocating new transaction.
+ */
+ DOMStoreReadWriteTransaction newReadWriteTransaction();
+
+}
+++ /dev/null
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
- <modelVersion>4.0.0</modelVersion>\r
- <parent>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>sal-parent</artifactId>\r
- <version>1.0-SNAPSHOT</version>\r
- </parent>\r
- <artifactId>sal-schema-repository-api</artifactId>\r
- <scm>\r
- <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>\r
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>\r
- <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL</url>\r
- </scm>\r
-\r
- <dependencies>\r
- <dependency>\r
- <groupId>org.opendaylight.controller</groupId>\r
- <artifactId>yang-model-api</artifactId>\r
- </dependency>\r
- </dependencies>\r
-</project>\r
+++ /dev/null
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.controller.sal.schema.api;
\ No newline at end of file