<type>xml</type>
<classifier>config</classifier>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-rest-docgen</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.datatype</groupId>
+ <artifactId>jackson-datatype-json-org</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-jaxb-annotations</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-base</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.jaxrs</groupId>
+ <artifactId>jackson-jaxrs-json-provider</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ </dependency>
<!-- test to validate features.xml -->
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<bundle>mvn:org.opendaylight.controller/sal-dom-xsql/${project.version}</bundle>
<configfile finalname="${config.configfile.directory}/${config.xsql.configfile}">mvn:org.opendaylight.controller/sal-dom-xsql-config/${project.version}/xml/config</configfile>
</feature>
+ <feature name ='odl-mdsal-apidocs' version='${project.version}'>
+ <feature version='${project.version}'>odl-restconf</feature>
+ <bundle>mvn:org.opendaylight.controller/sal-rest-docgen/${project.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-annotations/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-core/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.core/jackson-databind/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.datatype/jackson-datatype-json-org/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.module/jackson-module-jaxb-annotations/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-base/${jackson.version}</bundle>
+ <bundle>mvn:com.fasterxml.jackson.jaxrs/jackson-jaxrs-json-provider/${jackson.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-core/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-server/${jersey.version}</bundle>
+ <bundle>mvn:com.sun.jersey/jersey-servlet/${jersey.version}</bundle>
+ <bundle>wrap:mvn:org.json/json/${org.json.version}</bundle>
+ </feature>
</features>
<clustering.test.version>0.4.2-SNAPSHOT</clustering.test.version>
<commmons.northbound.version>0.4.2-SNAPSHOT</commmons.northbound.version>
<!-- Third Party Versions -->
+ <codahale.metrics.version>3.0.1</codahale.metrics.version>
<commons.catalina>7.0.32.v201211201336</commons.catalina>
<commons.catalina.ha>7.0.32.v201211201952</commons.catalina.ha>
<commons.catalina.tribes>7.0.32.v201211201952</commons.catalina.tribes>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
+ <dependency>
+ <groupId>com.codahale.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ <version>${codahale.metrics.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.codahale.metrics</groupId>
+ <artifactId>metrics-graphite</artifactId>
+ <version>${codahale.metrics.version}</version>
+ </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${netconf.version}</version>
<type>test-jar</type>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-auth</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-usermanager</artifactId>
+ <version>${netconf.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-ssh</artifactId>
<artifactId>yang-data-composite-node</artifactId>
<version>${yangtools.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-codec-gson</artifactId>
+ <version>${yangtools.version}</version>
+ </dependency>
<!-- yangtools dependencies -->
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-ssh</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-auth</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>netconf-usermanager</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>netconf-tcp</artifactId>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-parser-impl</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-codec-gson</artifactId>
+ </dependency>
<dependency>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>yang-data-composite-node</artifactId>
+++ /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.frm;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for
- * flow node subDataObject (flows, groups and meters).
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public abstract class AbstractChangeListener implements DataChangeListener {
-
- private final static Logger LOG = LoggerFactory.getLogger(AbstractChangeListener.class);
-
- private final AtomicLong txNum = new AtomicLong();
- private String transactionId;
-
- @Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
- this.transactionId = this.newTransactionIdentifier().toString();
- /* All DataObjects for create */
- final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
- changeEvent.getCreatedData().entrySet();
- /* All DataObjects for updates - init HashSet */
- final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updatedEntries = new HashSet<>();
- /* Filtered DataObject for update processing only */
- Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> updateConfigEntrySet =
- changeEvent.getUpdatedData().entrySet();
- updatedEntries.addAll(updateConfigEntrySet);
- updatedEntries.removeAll(createdEntries);
- /* All DataObjects for remove */
- final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
- changeEvent.getRemovedPaths();
- /* Create DataObject processing (send to device) */
- for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
- InstanceIdentifier<? extends DataObject> entryKey = createdEntry.getKey();
- DataObject entryValue = createdEntry.getValue();
- if (preconditionForChange(entryKey, entryValue, null)) {
- this.add(entryKey, entryValue);
- }
- }
-
- for (final Entry<InstanceIdentifier<?>, DataObject> updatedEntrie : updatedEntries) {
- Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
- changeEvent.getOriginalData();
-
- InstanceIdentifier<? extends Object> entryKey = updatedEntrie.getKey();
- final DataObject original = origConfigData.get(entryKey);
- final DataObject updated = updatedEntrie.getValue();
- if (preconditionForChange(entryKey, original, updated)) {
- this.update(entryKey, original, updated);
- }
- }
-
- for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
- Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
- changeEvent.getOriginalData();
-
- final DataObject removeValue = origConfigData.get(instanceId);
- if (preconditionForChange(instanceId, removeValue, null)) {
- this.remove(instanceId, removeValue);
- }
- }
- }
-
- /**
- * Method returns generated transaction ID, which is unique for
- * every transaction. ID is composite from prefix ("DOM") and unique number.
- *
- * @return String transactionID
- */
- public String getTransactionId() {
- return this.transactionId;
- }
-
- private Object newTransactionIdentifier() {
- return "DOM-" + txNum.getAndIncrement();
- }
-
- /**
- * Method check all local preconditions for apply relevant changes.
- *
- * @param InstanceIdentifier identifier - the whole path to DataObject
- * @param DataObject original - original DataObject (for update)
- * or relevant DataObject (add/delete operations)
- * @param DataObject update - changed DataObject (contain updates)
- * or should be null for (add/delete operations)
- *
- * @return boolean - applicable
- */
- protected abstract boolean preconditionForChange(
- final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update);
-
- /**
- * Method checks the node data path in DataStore/OPERATIONAL because
- * without the Node Identifier in DataStore/OPERATIONAL, device
- * is not connected and device pre-configuration is allowed only.
- *
- * @param InstanceIdentifier identifier - could be whole path to DataObject,
- * but parent Node.class InstanceIdentifier is used for a check only
- *
- * @return boolean - is the Node available in DataStore/OPERATIONAL (is connected)
- */
- protected boolean isNodeAvailable(final InstanceIdentifier<? extends DataObject> identifier,
- final ReadOnlyTransaction readTrans) {
- final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
- try {
- return readTrans.read(LogicalDatastoreType.OPERATIONAL, nodeInstanceId).get().isPresent();
- }
- catch (InterruptedException | ExecutionException e) {
- LOG.error("Unexpected exception by reading Node ".concat(nodeInstanceId.toString()), e);
- return false;
- }
- finally {
- readTrans.close();
- }
- }
-
- /**
- * Method removes DataObject which is identified by InstanceIdentifier
- * from device.
- *
- * @param InstanceIdentifier identifier - the whole path to DataObject
- * @param DataObject remove - DataObject for removing
- */
- protected abstract void remove(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject remove);
-
- /**
- * Method updates the original DataObject to the update DataObject
- * in device. Both are identified by same InstanceIdentifier
- *
- * @param InstanceIdentifier identifier - the whole path to DataObject
- * @param DataObject original - original DataObject (for update)
- * @param DataObject update - changed DataObject (contain updates)
- */
- protected abstract void update(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update);
-
- /**
- * Method adds the DataObject which is identified by InstanceIdentifier
- * to device.
- *
- * @param InstanceIdentifier identifier - the whole path to new DataObject
- * @param DataObject add - new DataObject
- */
- protected abstract void add(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject add);
-}
*/
package org.opendaylight.controller.frm;
-import org.opendaylight.controller.frm.flow.FlowProvider;
-import org.opendaylight.controller.frm.group.GroupProvider;
-import org.opendaylight.controller.frm.meter.MeterProvider;
-import org.opendaylight.controller.frm.reconil.FlowNodeReconcilProvider;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.AbstractBindingAwareProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
/**
* Forwarding Rules Manager Activator
*
- * Activator manages all Providers ({@link FlowProvider}, {@link GroupProvider},
- * {@link MeterProvider} and the {@link FlowNodeReconcilProvider}).
+ * Activator {@link ForwardingRulesManager}.
* It registers all listeners (DataChangeEvent, ReconcilNotification)
* in the Session Initialization phase.
*
private final static Logger LOG = LoggerFactory.getLogger(FRMActivator.class);
- private final FlowProvider flowProvider;
- private final GroupProvider groupProvider;
- private final MeterProvider meterProvider;
- private final FlowNodeReconcilProvider flowNodeReconcilProvider;
-
- public FRMActivator() {
- this.flowProvider = new FlowProvider();
- this.groupProvider = new GroupProvider();
- this.meterProvider = new MeterProvider();
- this.flowNodeReconcilProvider = new FlowNodeReconcilProvider();
- }
+ private ForwardingRulesManager manager;
@Override
- public void onSessionInitiated(final ProviderContext session) {
+ public void onSessionInitiated(ProviderContext session) {
LOG.info("FRMActivator initialization.");
- /* Flow */
try {
- final DataBroker flowSalService = session.getSALService(DataBroker.class);
- this.flowProvider.init(flowSalService);
- this.flowProvider.start(session);
- /* Group */
- final DataBroker groupSalService = session.getSALService(DataBroker.class);
- this.groupProvider.init(groupSalService);
- this.groupProvider.start(session);
- /* Meter */
- final DataBroker meterSalService = session.getSALService(DataBroker.class);
- this.meterProvider.init(meterSalService);
- this.meterProvider.start(session);
- /* FlowNode Reconciliation */
- final DataBroker dbs = session.getSALService(DataBroker.class);
- this.flowNodeReconcilProvider.init(dbs);
- this.flowNodeReconcilProvider.start(session);
-
- LOG.info("FRMActivator started successfully");
- } catch (Exception e) {
- String errMsg = "Unexpected error by starting FRMActivator";
- LOG.error(errMsg, e);
- throw new IllegalStateException(errMsg, e);
+ final DataBroker dataBroker = session.getSALService(DataBroker.class);
+ this.manager = new ForwardingRulesManagerImpl(dataBroker, session);
+ this.manager.start();
+ LOG.info("FRMActivator initialization successfull.");
+ }
+ catch (Exception e) {
+ LOG.error("Unexpected error by FRM initialization!", e);
+ this.stopImpl(null);
}
}
@Override
protected void stopImpl(final BundleContext context) {
- try {
- this.flowProvider.close();
- this.groupProvider.close();
- this.meterProvider.close();
- this.flowNodeReconcilProvider.close();
- } catch (Exception e) {
- LOG.error("Unexpected error by stopping FRMActivator", e);
+ if (manager != null) {
+ try {
+ manager.close();
+ } catch (Exception e) {
+ LOG.error("Unexpected error by stopping FRMActivator", e);
+ }
+ manager = null;
+ LOG.info("FRMActivator stopped.");
}
}
}
\ 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.frm;
-
-import java.math.BigInteger;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AtomicLongMap;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * Singleton FlowCookieProducer contains a FlowCookie generator which is generated unique
- * flowCookie identifier for every flow in same Table. That could help with quick
- * identification of flow statistic because DataStore/CONFIGURATION could contains
- * a lot of flows with same flowCookie. So we are replacing original flowCookie
- * with unique and we are building final FlowCookieMap in DataStore/OPERATIONAL
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public enum FlowCookieProducer {
-
- INSTANCE;
-
- /* Flow_Cookie_Key and Flow_Ids MapHolder */
- private static final AtomicLongMap<InstanceIdentifier<Table>> cookieKeys = AtomicLongMap.create();
-
- /**
- * Method returns the unique cookie for a node table.
- * Flow Cookie Key signs List<FlowId> for a right flow statistic identification
- * in the DataStore/operational.
- * We need a List<FlowId> because system doesn't guarantee unique mapping
- * from flow_cookie to flow_id. REST Operations doesn't used FRM yet, so
- * cookie from user input could have a user input flow ID and an alien system ID
- * which is generated by system.
- *
- * @param InstanceIdentifier<Table> tableIdentifier
- * @return unique BigInteger flowCookie for a node table
- */
- public BigInteger getNewCookie(final InstanceIdentifier<Table> tableIdentifier) {
- FlowCookieProducer.validationTableIdentifier(tableIdentifier);
- if ( cookieKeys.containsKey(tableIdentifier)) {
- /* new identifier always starts from ONE because
- * ZERO is reserved for the NO_COOKIES flows */
- return BigInteger.valueOf(cookieKeys.addAndGet(tableIdentifier, 1L));
- } else {
- return BigInteger.valueOf(cookieKeys.incrementAndGet(tableIdentifier));
- }
- }
-
- /**
- * Method cleans the node table flow_cookie_key for the disconnected Node.
- *
- * @param InstanceIdentifier<Table> tableIdentifier
- */
- public void clean(final InstanceIdentifier<Table> tableIdentifier) {
- FlowCookieProducer.validationTableIdentifier(tableIdentifier);
- cookieKeys.remove(tableIdentifier);
- }
-
- /*
- * Help the TableIdentifer input validation method
- */
- private static void validationTableIdentifier(final InstanceIdentifier<Table> tableIdent) {
- Preconditions.checkArgument(tableIdent != null, "Input validation exception: TableIdentifier can not be null !");
- }
-}
--- /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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * FlowNodeReconciliation
+ * It represent Reconciliation functionality for every new device.
+ * So we have to read all possible pre-configured Flows, Meters and Groups from
+ * Config/DS and add all to new device.
+ * New device is represented by new {@link org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode}
+ * in Operational/DS. So we have to add listener for Wildcarded path in base data change scope.
+ *
+ * WildCarded InstanceIdentifier:
+ * {@code
+ *
+ * InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class)
+ *
+ * }
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 26, 2014
+ */
+public interface FlowNodeReconciliation extends DataChangeListener, AutoCloseable {
+
+ /**
+ * Method contains Node registration to {@link ForwardingRulesManager} functionality
+ * as a prevention to use a validation check to the Operational/DS for identify
+ * pre-configure transaction and serious device commit in every transaction.
+ *
+ * Second part of functionality is own reconciliation pre-configure
+ * Flows, Meters and Groups.
+ *
+ * @param connectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to new Node
+ */
+ void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode);
+
+ /**
+ * Method contains functionality for registered Node {@FlowCapableNode} removing
+ * from {@Link ForwardingRulesManager}
+ *
+ * @param disconnectedNode - {@link org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier} to removed Node
+ */
+ void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode);
+}
+
--- /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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * ForwardingRulesCommiter
+ * It represent a contract between DataStore DataChangeEvent and relevant
+ * SalRpcService for device. Every implementation has to be registered for
+ * Configurational/DS tree path.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public interface ForwardingRulesCommiter <D extends DataObject> extends AutoCloseable, DataChangeListener {
+
+ /**
+ * Method removes DataObject which is identified by InstanceIdentifier
+ * from device.
+ *
+ * @param InstanceIdentifier identifier - the whole path to DataObject
+ * @param DataObject remove - DataObject for removing
+ * @param InstanceIdentifier<FlowCapableNode> parent Node InstanceIdentifier
+ */
+ void remove(InstanceIdentifier<D> identifier, D del,
+ InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+ /**
+ * Method updates the original DataObject to the update DataObject
+ * in device. Both are identified by same InstanceIdentifier
+ *
+ * @param InstanceIdentifier identifier - the whole path to DataObject
+ * @param DataObject original - original DataObject (for update)
+ * @param DataObject update - changed DataObject (contain updates)
+ */
+ void update(InstanceIdentifier<D> identifier, D original, D update,
+ InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+ /**
+ * Method adds the DataObject which is identified by InstanceIdentifier
+ * to device.
+ *
+ * @param InstanceIdentifier identifier - the whole path to new DataObject
+ * @param DataObject add - new DataObject
+ */
+ void add(InstanceIdentifier<D> identifier, D add,
+ InstanceIdentifier<FlowCapableNode> nodeIdent);
+
+}
+
--- /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.frm;
+
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * ForwardingRulesManager
+ * It represent a central point for whole modul. Implementation
+ * Flow Provider registers the link FlowChangeListener} and it holds all needed
+ * services for link FlowChangeListener}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public interface ForwardingRulesManager extends AutoCloseable {
+
+ public void start();
+
+ /**
+ * Method returns information :
+ * "is Node with send InstanceIdentifier connected"?
+ *
+ * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+ * @return boolean - is device connected
+ */
+ public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident);
+
+ /**
+ * Method add new {@link FlowCapableNode} to active Node Holder.
+ * ActiveNodeHolder prevent unnecessary Operational/DS read for identify
+ * pre-configure and serious Configure/DS transactions.
+ *
+ * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+ */
+ public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident);
+
+ /**
+ * Method remove disconnected {@link FlowCapableNode} from active Node
+ * Holder. And all next flows or groups or meters will stay in Config/DS
+ * only.
+ *
+ * @param InstanceIdentifier<FlowCapableNode> ident - the key of the node
+ */
+ public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident);
+
+ /**
+ * Method returns generated transaction ID, which is unique for
+ * every transaction. ID is composite from prefix ("DOM") and unique number.
+ *
+ * @return String transactionID for RPC transaction identification
+ */
+ public String getNewTransactionId();
+
+ /**
+ * Method returns Read Transacion. It is need for Node reconciliation only.
+ *
+ * @return ReadOnlyTransaction
+ */
+ public ReadOnlyTransaction getReadTranaction();
+
+ /**
+ * Flow RPC service
+ *
+ * @return
+ */
+ public SalFlowService getSalFlowService();
+
+ /**
+ * Group RPC service
+ *
+ * @return
+ */
+ public SalGroupService getSalGroupService();
+
+ /**
+ * Meter RPC service
+ *
+ * @return
+ */
+ public SalMeterService getSalMeterService();
+
+ /**
+ * Content definition method and prevent code duplicity in Reconcil
+ * @return ForwardingRulesCommiter<Flow>
+ */
+ public ForwardingRulesCommiter<Flow> getFlowCommiter();
+
+ /**
+ * Content definition method and prevent code duplicity in Reconcil
+ * @return ForwardingRulesCommiter<Group>
+ */
+ public ForwardingRulesCommiter<Group> getGroupCommiter();
+
+ /**
+ * Content definition method and prevent code duplicity
+ * @return ForwardingRulesCommiter<Meter>
+ */
+ public ForwardingRulesCommiter<Meter> getMeterCommiter();
+
+ /**
+ * Content definition method
+ * @return FlowNodeReconciliation
+ */
+ public FlowNodeReconciliation getFlowNodeReconciliation();
+}
+
+++ /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.frm.flow;
-
-import java.math.BigInteger;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.frm.FlowCookieProducer;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-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.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-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.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.FlowRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Flow Change Listener
- * add, update and remove {@link Flow} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class FlowChangeListener extends AbstractChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlowChangeListener.class);
-
- private final FlowProvider provider;
-
- public FlowChangeListener (final FlowProvider provider) {
- this.provider = Preconditions.checkNotNull(provider, "FlowProvider can not be null !");
- }
-
- @Override
- protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject removeDataObj) {
-
- final Flow flow = ((Flow) removeDataObj);
- final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
- final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
- final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(flow);
-
- // use empty cookie mask in order to delete flow even with generated cookie
- builder.setCookieMask(new FlowCookie(BigInteger.ZERO));
-
- builder.setFlowRef(new FlowRef(identifier));
- builder.setNode(new NodeRef(nodeIdent));
- builder.setFlowTable(new FlowTableRef(tableIdent));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalFlowService().removeFlow(builder.build());
- LOG.debug("Transaction {} - Removed Flow has removed flow: {}", new Object[]{uri, removeDataObj});
- }
-
- @Override
- protected void update(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update) {
-
- final Flow originalFlow = ((Flow) original);
- final Flow updatedFlow = ((Flow) update);
- final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
- final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
-
- builder.setNode(new NodeRef(nodeIdent));
- builder.setFlowRef(new FlowRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
-
- builder.setUpdatedFlow((new UpdatedFlowBuilder(updatedFlow)).build());
- builder.setOriginalFlow((new OriginalFlowBuilder(originalFlow)).build());
-
- this.provider.getSalFlowService().updateFlow(builder.build());
- LOG.debug("Transaction {} - Update Flow has updated flow {} with {}", new Object[]{uri, original, update});
- }
-
- @Override
- protected void add(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject addDataObj) {
-
- final Flow flow = ((Flow) addDataObj);
- final InstanceIdentifier<Table> tableIdent = identifier.firstIdentifierOf(Table.class);
- final NodeRef nodeRef = new NodeRef(identifier.firstIdentifierOf(Node.class));
- final FlowCookie flowCookie = new FlowCookie(FlowCookieProducer.INSTANCE.getNewCookie(tableIdent));
- final AddFlowInputBuilder builder = new AddFlowInputBuilder(flow);
-
- builder.setNode(nodeRef);
- builder.setFlowRef(new FlowRef(identifier));
- builder.setFlowTable(new FlowTableRef(tableIdent));
- builder.setCookie( flowCookie );
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalFlowService().addFlow(builder.build());
- LOG.debug("Transaction {} - Add Flow has added flow: {}", new Object[]{uri, addDataObj});
- }
-
- @Override
- protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject dataObj, final DataObject update) {
-
- final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
- return update != null
- ? (dataObj instanceof Flow && update instanceof Flow && isNodeAvailable(identifier, trans))
- : (dataObj instanceof Flow && isNodeAvailable(identifier, trans));
- }
-}
+++ /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.frm.flow;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-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.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Flow Provider registers the {@link FlowChangeListener} and it holds all needed
- * services for {@link FlowChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class FlowProvider implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlowProvider.class);
-
- private SalFlowService salFlowService;
- private DataBroker dataService;
-
- /* DataChangeListener */
- private DataChangeListener flowDataChangeListener;
- private ListenerRegistration<DataChangeListener> flowDataChangeListenerRegistration;
-
- /**
- * Provider Initialization Phase.
- *
- * @param DataProviderService dataService
- */
- public void init (final DataBroker dataService) {
- LOG.info("FRM Flow Config Provider initialization.");
- this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
- }
-
- /**
- * Listener Registration Phase
- *
- * @param RpcConsumerRegistry rpcRegistry
- */
- public void start(final RpcConsumerRegistry rpcRegistry) {
- Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
-
- this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
- "RPC SalFlowService not found.");
-
- /* Build Path */
- InstanceIdentifier<Flow> flowIdentifier = InstanceIdentifier.create(Nodes.class)
- .child(Node.class).augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
-
- /* DataChangeListener registration */
- this.flowDataChangeListener = new FlowChangeListener(FlowProvider.this);
- this.flowDataChangeListenerRegistration =
- this.dataService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- flowIdentifier, flowDataChangeListener, DataChangeScope.SUBTREE);
-
- LOG.info("FRM Flow Config Provider started.");
- }
-
- @Override
- public void close() {
- LOG.info("FRM Flow Config Provider stopped.");
- if (flowDataChangeListenerRegistration != null) {
- try {
- flowDataChangeListenerRegistration.close();
- } catch (Exception e) {
- String errMsg = "Error by stop FRM Flow Config Provider.";
- LOG.error(errMsg, e);
- throw new IllegalStateException(errMsg, e);
- } finally {
- flowDataChangeListenerRegistration = null;
- }
- }
- }
-
- public DataChangeListener getFlowDataChangeListener() {
- return flowDataChangeListener;
- }
-
- public SalFlowService getSalFlowService() {
- return salFlowService;
- }
-
- public DataBroker getDataService() {
- return 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.frm.group;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Group Change Listener
- * add, update and remove {@link Group} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class GroupChangeListener extends AbstractChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(GroupChangeListener.class);
-
- private final GroupProvider provider;
-
- public GroupChangeListener(final GroupProvider provider) {
- this.provider = Preconditions.checkNotNull(provider, "GroupProvider can not be null !");
- }
-
- @Override
- protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject removeDataObj) {
-
- final Group group = ((Group) removeDataObj);
- final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
- final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
-
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setGroupRef(new GroupRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalGroupService().removeGroup(builder.build());
- LOG.debug("Transaction {} - Remove Group has removed group: {}", new Object[]{uri, removeDataObj});
- }
-
- @Override
- protected void update(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update) {
-
- final Group originalGroup = ((Group) original);
- final Group updatedGroup = ((Group) update);
- final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
- final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
-
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setGroupRef(new GroupRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
-
- builder.setUpdatedGroup((new UpdatedGroupBuilder(updatedGroup)).build());
- builder.setOriginalGroup((new OriginalGroupBuilder(originalGroup)).build());
-
- this.provider.getSalGroupService().updateGroup(builder.build());
- LOG.debug("Transaction {} - Update Group has updated group {} with group {}", new Object[]{uri, original, update});
- }
-
- @Override
- protected void add(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject addDataObj) {
-
- final Group group = ((Group) addDataObj);
- final InstanceIdentifier<Node> nodeInstanceId = identifier.<Node> firstIdentifierOf(Node.class);
- final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
-
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setGroupRef(new GroupRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalGroupService().addGroup(builder.build());
- LOG.debug("Transaction {} - Add Group has added group: {}", new Object[]{uri, addDataObj});
- }
-
- @Override
- protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject dataObj, final DataObject update) {
-
- final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
- return update != null
- ? (dataObj instanceof Group && update instanceof Group && isNodeAvailable(identifier, trans))
- : (dataObj instanceof Group && isNodeAvailable(identifier, trans));
- }
-}
+++ /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.frm.group;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Group Provider registers the {@link GroupChangeListener} and it holds all needed
- * services for {@link GroupChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class GroupProvider implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(GroupProvider.class);
-
- private SalGroupService salGroupService;
- private DataBroker dataService;
-
- /* DataChangeListener */
- private DataChangeListener groupDataChangeListener;
- private ListenerRegistration<DataChangeListener> groupDataChangeListenerRegistration;
-
- /**
- * Provider Initialization Phase.
- *
- * @param DataProviderService dataService
- */
- public void init (final DataBroker dataService) {
- LOG.info("FRM Group Config Provider initialization.");
- this.dataService = Preconditions.checkNotNull(dataService, "DataService can not be null !");
- }
-
- /**
- * Listener Registration Phase
- *
- * @param RpcConsumerRegistry rpcRegistry
- */
- public void start(final RpcConsumerRegistry rpcRegistry) {
- Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
-
- this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
- "RPC SalGroupService not found.");
-
- /* Build Path */
- InstanceIdentifier<Group> groupIdentifier = InstanceIdentifier.create(Nodes.class)
- .child(Node.class).augmentation(FlowCapableNode.class).child(Group.class);
-
- /* DataChangeListener registration */
- this.groupDataChangeListener = new GroupChangeListener(GroupProvider.this);
- this.groupDataChangeListenerRegistration = this.dataService.registerDataChangeListener(
- LogicalDatastoreType.CONFIGURATION, groupIdentifier, groupDataChangeListener, DataChangeScope.SUBTREE);
-
- LOG.info("FRM Group Config Provider started.");
- }
-
- @Override
- public void close() {
- LOG.info("FRM Group Config Provider stopped.");
- if (groupDataChangeListenerRegistration != null) {
- try {
- groupDataChangeListenerRegistration.close();
- } catch (Exception e) {
- String errMsg = "Error by stop FRM Group Config Provider.";
- LOG.error(errMsg, e);
- throw new IllegalStateException(errMsg, e);
- } finally {
- groupDataChangeListenerRegistration = null;
- }
- }
- }
-
- public DataChangeListener getGroupDataChangeListener() {
- return groupDataChangeListener;
- }
-
- public SalGroupService getSalGroupService() {
- return salGroupService;
- }
-
- public DataBroker getDataService() {
- return 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.frm.impl;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesCommiter;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * AbstractChangeListner implemented basic {@link AsyncDataChangeEvent} processing for
+ * flow node subDataObject (flows, groups and meters).
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public abstract class AbstractListeningCommiter <T extends DataObject> implements ForwardingRulesCommiter<T> {
+
+ protected ForwardingRulesManager provider;
+
+ protected final Class<T> clazz;
+
+ public AbstractListeningCommiter (ForwardingRulesManager provider, Class<T> clazz) {
+ this.provider = Preconditions.checkNotNull(provider, "ForwardingRulesManager can not be null!");
+ this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
+ }
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+
+ /* All DataObjects for create */
+ final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
+ ? changeEvent.getCreatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+ /* All DataObjects for remove */
+ final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+ ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();
+ /* All DataObjects for updates */
+ final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
+ ? changeEvent.getUpdatedData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+ /* All Original DataObjects */
+ final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
+ ? changeEvent.getOriginalData() : Collections.<InstanceIdentifier<?>, DataObject> emptyMap();
+
+ this.createData(createdData);
+ this.updateData(updateData, originalData);
+ this.removeData(removeData, originalData);
+ }
+
+ /**
+ * Method return wildCardPath for Listener registration
+ * and for identify the correct KeyInstanceIdentifier from data;
+ */
+ protected abstract InstanceIdentifier<T> getWildCardPath();
+
+
+
+ @SuppressWarnings("unchecked")
+ private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
+ final Set<InstanceIdentifier<?>> keys = createdData.keySet() != null
+ ? createdData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<FlowCapableNode> nodeIdent =
+ key.firstIdentifierOf(FlowCapableNode.class);
+ if (preConfigurationCheck(nodeIdent)) {
+ InstanceIdentifier<T> createKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(createdData.get(key));
+ if (value.isPresent()) {
+ this.add(createKeyIdent, (T)value.get(), nodeIdent);
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,
+ final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ final Set<InstanceIdentifier<?>> keys = updateData.keySet() != null
+ ? updateData.keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+ for (InstanceIdentifier<?> key : keys) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<FlowCapableNode> nodeIdent =
+ key.firstIdentifierOf(FlowCapableNode.class);
+ if (preConfigurationCheck(nodeIdent)) {
+ InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
+ final Optional<DataObject> value = Optional.of(updateData.get(key));
+ final Optional<DataObject> original = Optional.of(originalData.get(key));
+ if (value.isPresent() && original.isPresent()) {
+ this.update(updateKeyIdent, (T)original.get(), (T)value.get(), nodeIdent);
+ }
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void removeData(final Set<InstanceIdentifier<?>> removeData,
+ final Map<InstanceIdentifier<?>, DataObject> originalData) {
+
+ for (InstanceIdentifier<?> key : removeData) {
+ if (clazz.equals(key.getTargetType())) {
+ final InstanceIdentifier<FlowCapableNode> nodeIdent =
+ key.firstIdentifierOf(FlowCapableNode.class);
+ if (preConfigurationCheck(nodeIdent)) {
+ final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
+ final DataObject removeValue = originalData.get(key);
+ this.remove(ident, (T)removeValue, nodeIdent);
+ }
+ }
+ }
+ }
+
+ private boolean preConfigurationCheck(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+ Preconditions.checkNotNull(nodeIdent, "FlowCapableNode ident can not be null!");
+ return provider.isNodeActive(nodeIdent);
+ }
+}
+
--- /dev/null
+/**ab
+ * 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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+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.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
+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.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.FlowRef;
+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.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GroupForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Flow} and ForwardingRulesCommiter interface for methods:
+ * add, update and remove {@link Flow} processing for
+ * {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class FlowForwarder extends AbstractListeningCommiter<Flow> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FlowForwarder.class);
+
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ public FlowForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+ super(manager, Flow.class);
+ Preconditions.checkNotNull(db, "DataBroker can not be null!");
+ this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardPath(), FlowForwarder.this, DataChangeScope.BASE);
+ }
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (Exception e) {
+ LOG.error("Error by stop FRM FlowChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ @Override
+ public void remove(final InstanceIdentifier<Flow> identifier,
+ final Flow removeDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+ if (tableIdValidationPrecondition(tableKey, removeDataObj)) {
+ final RemoveFlowInputBuilder builder = new RemoveFlowInputBuilder(removeDataObj);
+ builder.setFlowRef(new FlowRef(identifier));
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalFlowService().removeFlow(builder.build());
+ }
+ }
+
+ @Override
+ public void update(final InstanceIdentifier<Flow> identifier,
+ final Flow original, final Flow update,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+ if (tableIdValidationPrecondition(tableKey, update)) {
+ final UpdateFlowInputBuilder builder = new UpdateFlowInputBuilder();
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setFlowRef(new FlowRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ builder.setUpdatedFlow((new UpdatedFlowBuilder(update)).build());
+ builder.setOriginalFlow((new OriginalFlowBuilder(original)).build());
+
+ this.provider.getSalFlowService().updateFlow(builder.build());
+ }
+ }
+
+ @Override
+ public void add(final InstanceIdentifier<Flow> identifier,
+ final Flow addDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final TableKey tableKey = identifier.firstKeyOf(Table.class, TableKey.class);
+ if (tableIdValidationPrecondition(tableKey, addDataObj)) {
+ final AddFlowInputBuilder builder = new AddFlowInputBuilder(addDataObj);
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setFlowRef(new FlowRef(identifier));
+ builder.setFlowTable(new FlowTableRef(nodeIdent.child(Table.class, tableKey)));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalFlowService().addFlow(builder.build());
+ }
+ }
+
+ @Override
+ protected InstanceIdentifier<Flow> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Table.class).child(Flow.class);
+ }
+
+ private boolean tableIdValidationPrecondition (final TableKey tableKey, final Flow flow) {
+ Preconditions.checkNotNull(tableKey, "TableKey can not be null or empty!");
+ Preconditions.checkNotNull(flow, "Flow can not be null or empty!");
+ if (flow.getTableId() != tableKey.getId()) {
+ LOG.error("TableID in URI tableId={} and in palyload tableId={} is not same.",
+ flow.getTableId(), tableKey.getId());
+ return false;
+ }
+ return true;
+ }
+}
+
--- /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.frm.impl;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.opendaylight.controller.frm.FlowNodeReconciliation;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+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.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm
+ *
+ * FlowNode Reconciliation Listener
+ * Reconciliation for a new FlowNode
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Jun 13, 2014
+ */
+public class FlowNodeReconciliationImpl implements FlowNodeReconciliation {
+
+ private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconciliationImpl.class);
+
+ private final ForwardingRulesManager provider;
+
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ public FlowNodeReconciliationImpl (final ForwardingRulesManager manager, final DataBroker db) {
+ this.provider = Preconditions.checkNotNull(manager, "ForwardingRulesManager can not be null!");
+ Preconditions.checkNotNull(db, "DataBroker can not be null!");
+ /* Build Path */
+ InstanceIdentifier<FlowCapableNode> flowNodeWildCardIdentifier = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class).augmentation(FlowCapableNode.class);
+ this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
+ flowNodeWildCardIdentifier, FlowNodeReconciliationImpl.this, DataChangeScope.BASE);
+ }
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (Exception e) {
+ LOG.error("Error by stop FRM FlowNodeReconilListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ @Override
+ public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
+ Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
+ /* All DataObjects for create */
+ final Set<InstanceIdentifier<?>> createdData = changeEvent.getCreatedData() != null
+ ? changeEvent.getCreatedData().keySet() : Collections.<InstanceIdentifier<?>> emptySet();
+ /* All DataObjects for remove */
+ final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
+ ? changeEvent.getRemovedPaths() : Collections.<InstanceIdentifier<?>> emptySet();
+
+ for (InstanceIdentifier<?> entryKey : removeData) {
+ final InstanceIdentifier<FlowCapableNode> nodeIdent = entryKey
+ .firstIdentifierOf(FlowCapableNode.class);
+ if ( ! nodeIdent.isWildcarded()) {
+ flowNodeDisconnected(nodeIdent);
+ }
+ }
+ for (InstanceIdentifier<?> entryKey : createdData) {
+ final InstanceIdentifier<FlowCapableNode> nodeIdent = entryKey
+ .firstIdentifierOf(FlowCapableNode.class);
+ if ( ! nodeIdent.isWildcarded()) {
+ flowNodeConnected(nodeIdent);
+ }
+ }
+ }
+
+ @Override
+ public void flowNodeDisconnected(InstanceIdentifier<FlowCapableNode> disconnectedNode) {
+ provider.unregistrateNode(disconnectedNode);
+ }
+
+ @Override
+ public void flowNodeConnected(InstanceIdentifier<FlowCapableNode> connectedNode) {
+ if ( ! provider.isNodeActive(connectedNode)) {
+ provider.registrateNewNode(connectedNode);
+ reconciliation(connectedNode);
+ }
+ }
+
+ private void reconciliation(final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ ReadOnlyTransaction trans = provider.getReadTranaction();
+ Optional<FlowCapableNode> flowNode = Optional.absent();
+
+ try {
+ flowNode = trans.read(LogicalDatastoreType.CONFIGURATION, nodeIdent).get();
+ }
+ catch (Exception e) {
+ LOG.error("Fail with read Config/DS for Node {} !", nodeIdent, e);
+ }
+
+ if (flowNode.isPresent()) {
+ /* Groups - have to be first */
+ List<Group> groups = flowNode.get().getGroup() != null
+ ? flowNode.get().getGroup() : Collections.<Group> emptyList();
+ for (Group group : groups) {
+ final KeyedInstanceIdentifier<Group, GroupKey> groupIdent =
+ nodeIdent.child(Group.class, group.getKey());
+ this.provider.getGroupCommiter().add(groupIdent, group, nodeIdent);
+ }
+ /* Meters */
+ List<Meter> meters = flowNode.get().getMeter() != null
+ ? flowNode.get().getMeter() : Collections.<Meter> emptyList();
+ for (Meter meter : meters) {
+ final KeyedInstanceIdentifier<Meter, MeterKey> meterIdent =
+ nodeIdent.child(Meter.class, meter.getKey());
+ this.provider.getMeterCommiter().add(meterIdent, meter, nodeIdent);
+ }
+ /* Flows */
+ List<Table> tables = flowNode.get().getTable() != null
+ ? flowNode.get().getTable() : Collections.<Table> emptyList();
+ for (Table table : tables) {
+ final KeyedInstanceIdentifier<Table, TableKey> tableIdent =
+ nodeIdent.child(Table.class, table.getKey());
+ List<Flow> flows = table.getFlow() != null ? table.getFlow() : Collections.<Flow> emptyList();
+ for (Flow flow : flows) {
+ final KeyedInstanceIdentifier<Flow, FlowKey> flowIdent =
+ tableIdent.child(Flow.class, flow.getKey());
+ this.provider.getFlowCommiter().add(flowIdent, flow, nodeIdent);
+ }
+ }
+ }
+ /* clean transaction */
+ trans.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.frm.impl;
+
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.opendaylight.controller.frm.FlowNodeReconciliation;
+import org.opendaylight.controller.frm.ForwardingRulesCommiter;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+
+/**
+ * forwardingrules-manager
+ * org.opendaylight.controller.frm.impl
+ *
+ * Manager and middle point for whole module.
+ * It contains ActiveNodeHolder and provide all RPC services.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ * Created: Aug 25, 2014
+ */
+public class ForwardingRulesManagerImpl implements ForwardingRulesManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ForwardingRulesManagerImpl.class);
+
+ private final AtomicLong txNum = new AtomicLong();
+ private final Object lockObj = new Object();
+ private Set<InstanceIdentifier<FlowCapableNode>> activeNodes = Collections.emptySet();
+
+ private final DataBroker dataService;
+ private final SalFlowService salFlowService;
+ private final SalGroupService salGroupService;
+ private final SalMeterService salMeterService;
+
+ private ForwardingRulesCommiter<Flow> flowListener;
+ private ForwardingRulesCommiter<Group> groupListener;
+ private ForwardingRulesCommiter<Meter> meterListener;
+ private FlowNodeReconciliation nodeListener;
+
+ public ForwardingRulesManagerImpl(final DataBroker dataBroker,
+ final RpcConsumerRegistry rpcRegistry) {
+ this.dataService = Preconditions.checkNotNull(dataBroker, "DataBroker can not be null!");
+
+ Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
+
+ this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
+ "RPC SalFlowService not found.");
+ this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
+ "RPC SalGroupService not found.");
+ this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
+ "RPC SalMeterService not found.");
+ }
+
+ @Override
+ public void start() {
+ this.flowListener = new FlowForwarder(this, dataService);
+ this.groupListener = new GroupForwarder(this, dataService);
+ this.meterListener = new MeterForwarder(this, dataService);
+ this.nodeListener = new FlowNodeReconciliationImpl(this, dataService);
+ LOG.info("ForwardingRulesManager has started successfull.");
+ }
+
+ @Override
+ public void close() throws Exception {
+ if(this.flowListener != null) {
+ this.flowListener.close();
+ this.flowListener = null;
+ }
+ if (this.groupListener != null) {
+ this.groupListener.close();
+ this.groupListener = null;
+ }
+ if (this.meterListener != null) {
+ this.meterListener.close();
+ this.meterListener = null;
+ }
+ if (this.nodeListener != null) {
+ this.nodeListener.close();
+ this.nodeListener = null;
+ }
+ }
+
+ @Override
+ public ReadOnlyTransaction getReadTranaction() {
+ return dataService.newReadOnlyTransaction();
+ }
+
+ @Override
+ public String getNewTransactionId() {
+ return "DOM-" + txNum.getAndIncrement();
+ }
+
+ @Override
+ public boolean isNodeActive(InstanceIdentifier<FlowCapableNode> ident) {
+ return activeNodes.contains(ident);
+ }
+
+ @Override
+ public void registrateNewNode(InstanceIdentifier<FlowCapableNode> ident) {
+ if ( ! activeNodes.contains(ident)) {
+ synchronized (lockObj) {
+ if ( ! activeNodes.contains(ident)) {
+ Set<InstanceIdentifier<FlowCapableNode>> set =
+ Sets.newHashSet(activeNodes);
+ set.add(ident);
+ activeNodes = Collections.unmodifiableSet(set);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void unregistrateNode(InstanceIdentifier<FlowCapableNode> ident) {
+ if (activeNodes.contains(ident)) {
+ synchronized (lockObj) {
+ if (activeNodes.contains(ident)) {
+ Set<InstanceIdentifier<FlowCapableNode>> set =
+ Sets.newHashSet(activeNodes);
+ set.remove(ident);
+ activeNodes = Collections.unmodifiableSet(set);
+ }
+ }
+ }
+ }
+
+ @Override
+ public SalFlowService getSalFlowService() {
+ return salFlowService;
+ }
+
+ @Override
+ public SalGroupService getSalGroupService() {
+ return salGroupService;
+ }
+
+ @Override
+ public SalMeterService getSalMeterService() {
+ return salMeterService;
+ }
+
+ @Override
+ public ForwardingRulesCommiter<Flow> getFlowCommiter() {
+ return flowListener;
+ }
+
+ @Override
+ public ForwardingRulesCommiter<Group> getGroupCommiter() {
+ return groupListener;
+ }
+
+ @Override
+ public ForwardingRulesCommiter<Meter> getMeterCommiter() {
+ return meterListener;
+ }
+
+ @Override
+ public FlowNodeReconciliation getFlowNodeReconciliation() {
+ return nodeListener;
+ }
+}
+
--- /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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.OriginalGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.group.update.UpdatedGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+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.Node;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GroupForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Group} and ForwardingRulesCommiter interface for methods:
+ * add, update and remove {@link Group} processing for
+ * {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class GroupForwarder extends AbstractListeningCommiter<Group> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(GroupForwarder.class);
+
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ public GroupForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+ super(manager, Group.class);
+ Preconditions.checkNotNull(db, "DataBroker can not be null!");
+ this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardPath(), GroupForwarder.this, DataChangeScope.BASE);
+ }
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (Exception e) {
+ LOG.error("Error by stop FRM GroupChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ @Override
+ protected InstanceIdentifier<Group> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Group.class);
+ }
+
+ @Override
+ public void remove(final InstanceIdentifier<Group> identifier, final Group removeDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final Group group = (removeDataObj);
+ final RemoveGroupInputBuilder builder = new RemoveGroupInputBuilder(group);
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setGroupRef(new GroupRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalGroupService().removeGroup(builder.build());
+ }
+
+ @Override
+ public void update(final InstanceIdentifier<Group> identifier,
+ final Group original, final Group update,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final Group originalGroup = (original);
+ final Group updatedGroup = (update);
+ final UpdateGroupInputBuilder builder = new UpdateGroupInputBuilder();
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setGroupRef(new GroupRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ builder.setUpdatedGroup((new UpdatedGroupBuilder(updatedGroup)).build());
+ builder.setOriginalGroup((new OriginalGroupBuilder(originalGroup)).build());
+
+ this.provider.getSalGroupService().updateGroup(builder.build());
+ }
+
+ @Override
+ public void add(final InstanceIdentifier<Group> identifier, final Group addDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final Group group = (addDataObj);
+ final AddGroupInputBuilder builder = new AddGroupInputBuilder(group);
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setGroupRef(new GroupRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalGroupService().addGroup(builder.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.frm.impl;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.frm.ForwardingRulesManager;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+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.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * MeterForwarder
+ * It implements {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}}
+ * for WildCardedPath to {@link Meter} and ForwardingRulesCommiter interface for methods:
+ * add, update and remove {@link Meter} processing for
+ * {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
+ *
+ * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
+ *
+ */
+public class MeterForwarder extends AbstractListeningCommiter<Meter> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MeterForwarder.class);
+
+ private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+ public MeterForwarder (final ForwardingRulesManager manager, final DataBroker db) {
+ super(manager, Meter.class);
+ Preconditions.checkNotNull(db, "DataBroker can not be null!");
+ this.listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+ getWildCardPath(), MeterForwarder.this, DataChangeScope.BASE);
+ }
+
+ @Override
+ public void close() {
+ if (listenerRegistration != null) {
+ try {
+ listenerRegistration.close();
+ } catch (Exception e) {
+ LOG.error("Error by stop FRM MeterChangeListener.", e);
+ }
+ listenerRegistration = null;
+ }
+ }
+
+ @Override
+ protected InstanceIdentifier<Meter> getWildCardPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class)
+ .augmentation(FlowCapableNode.class).child(Meter.class);
+ }
+
+ @Override
+ public void remove(final InstanceIdentifier<Meter> identifier, final Meter removeDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(removeDataObj);
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setMeterRef(new MeterRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalMeterService().removeMeter(builder.build());
+ }
+
+ @Override
+ public void update(final InstanceIdentifier<Meter> identifier,
+ final Meter original, final Meter update,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setMeterRef(new MeterRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ builder.setUpdatedMeter((new UpdatedMeterBuilder(update)).build());
+ builder.setOriginalMeter((new OriginalMeterBuilder(original)).build());
+
+ this.provider.getSalMeterService().updateMeter(builder.build());
+ }
+
+ @Override
+ public void add(final InstanceIdentifier<Meter> identifier, final Meter addDataObj,
+ final InstanceIdentifier<FlowCapableNode> nodeIdent) {
+
+ final AddMeterInputBuilder builder = new AddMeterInputBuilder(addDataObj);
+
+ builder.setNode(new NodeRef(nodeIdent));
+ builder.setMeterRef(new MeterRef(identifier));
+ builder.setTransactionUri(new Uri(provider.getNewTransactionId()));
+ this.provider.getSalMeterService().addMeter(builder.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.frm.meter;
-
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.OriginalMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.meter.update.UpdatedMeterBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Meter Change Listener
- * add, update and remove {@link Meter} processing from {@link org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class MeterChangeListener extends AbstractChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(MeterChangeListener.class);
-
- private final MeterProvider provider;
-
- public MeterChangeListener (final MeterProvider provider) {
- this.provider = Preconditions.checkNotNull(provider, "MeterProvider can not be null !");
- }
-
- @Override
- protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject removeDataObj) {
-
- final Meter meter = ((Meter) removeDataObj);
- final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
- final RemoveMeterInputBuilder builder = new RemoveMeterInputBuilder(meter);
-
- builder.setNode(new NodeRef(nodeIdent));
- builder.setMeterRef(new MeterRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalMeterService().removeMeter(builder.build());
- LOG.debug("Transaction {} - Remove Meter has removed meter: {}", new Object[]{uri, removeDataObj});
- }
-
- @Override
- protected void update(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update) {
-
- final Meter originalMeter = ((Meter) original);
- final Meter updatedMeter = ((Meter) update);
- final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
- final UpdateMeterInputBuilder builder = new UpdateMeterInputBuilder();
-
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setMeterRef(new MeterRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
-
- builder.setUpdatedMeter((new UpdatedMeterBuilder(updatedMeter)).build());
- builder.setOriginalMeter((new OriginalMeterBuilder(originalMeter)).build());
-
- this.provider.getSalMeterService().updateMeter(builder.build());
- LOG.debug("Transaction {} - Update Meter has updated meter {} with {}", new Object[]{uri, original, update});
-
- }
-
- @Override
- protected void add(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject addDataObj) {
-
- final Meter meter = ((Meter) addDataObj);
- final InstanceIdentifier<Node> nodeInstanceId = identifier.firstIdentifierOf(Node.class);
- final AddMeterInputBuilder builder = new AddMeterInputBuilder(meter);
-
- builder.setNode(new NodeRef(nodeInstanceId));
- builder.setMeterRef(new MeterRef(identifier));
-
- Uri uri = new Uri(this.getTransactionId());
- builder.setTransactionUri(uri);
- this.provider.getSalMeterService().addMeter(builder.build());
- LOG.debug("Transaction {} - Add Meter has added meter: {}", new Object[]{uri, addDataObj});
- }
-
- @Override
- protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject dataObj, final DataObject update) {
-
- final ReadOnlyTransaction trans = this.provider.getDataService().newReadOnlyTransaction();
- return update != null
- ? (dataObj instanceof Meter && update instanceof Meter && isNodeAvailable(identifier, trans))
- : (dataObj instanceof Meter && isNodeAvailable(identifier, trans));
- }
-}
+++ /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.frm.meter;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
-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;
-
-/**
- * Meter Provider registers the {@link MeterChangeListener} and it holds all needed
- * services for {@link MeterChangeListener}.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- */
-public class MeterProvider implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(MeterProvider.class);
-
- private SalMeterService salMeterService;
- private DataBroker dataService;
-
- /* DataChangeListener */
- private DataChangeListener meterDataChangeListener;
- private ListenerRegistration<DataChangeListener> meterDataChangeListenerRegistration;
-
- /**
- * Provider Initialization Phase.
- *
- * @param DataProviderService dataService
- */
- public void init(final DataBroker dataService) {
- LOG.info("FRM Meter Config Provider initialization.");
- this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
- }
-
- /**
- * Listener Registration Phase
- *
- * @param RpcConsumerRegistry rpcRegistry
- */
- public void start(final RpcConsumerRegistry rpcRegistry) {
- Preconditions.checkArgument(rpcRegistry != null, "RpcConsumerRegistry can not be null !");
- this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
- "RPC SalMeterService not found.");
-
- /* Build Path */
- InstanceIdentifier<Meter> meterIdentifier = InstanceIdentifier.create(Nodes.class)
- .child(Node.class).augmentation(FlowCapableNode.class).child(Meter.class);
-
- /* DataChangeListener registration */
- this.meterDataChangeListener = new MeterChangeListener(MeterProvider.this);
- this.meterDataChangeListenerRegistration =
- this.dataService.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
- meterIdentifier, meterDataChangeListener, DataChangeScope.SUBTREE);
-
- LOG.info("FRM Meter Config Provider started.");
- }
-
- @Override
- public void close() {
- LOG.info("FRM Meter Config Provider stopped.");
- if (meterDataChangeListenerRegistration != null) {
- try {
- meterDataChangeListenerRegistration.close();
- } catch (Exception e) {
- String errMsg = "Error by stop FRM Meter Config Provider.";
- LOG.error(errMsg, e);
- throw new IllegalStateException(errMsg, e);
- } finally {
- meterDataChangeListenerRegistration = null;
- }
- }
- }
-
- public DataChangeListener getMeterDataChangeListener() {
- return meterDataChangeListener;
- }
-
- public DataBroker getDataService() {
- return dataService;
- }
-
- public SalMeterService getSalMeterService() {
- return salMeterService;
- }
-}
+++ /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.frm.reconil;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
-import org.opendaylight.controller.frm.AbstractChangeListener;
-import org.opendaylight.controller.frm.FlowCookieProducer;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
-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.table.Flow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowTableRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterRef;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * FlowNode Reconciliation Listener
- * Reconciliation for a new FlowNode
- * Remove CookieMapKey for removed FlowNode
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public class FlowNodeReconcilListener extends AbstractChangeListener {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconcilListener.class);
-
- private final FlowNodeReconcilProvider provider;
-
- public FlowNodeReconcilListener(final FlowNodeReconcilProvider provider) {
- this.provider = Preconditions.checkNotNull(provider, "Flow Node Reconcil Provider can not be null!");
- }
-
- @Override
- public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
- /* FlowCapableNode DataObjects for reconciliation */
- final Set<Entry<InstanceIdentifier<? extends DataObject>, DataObject>> createdEntries =
- changeEvent.getCreatedData().entrySet();
- /* FlowCapableNode DataObjects for clean FlowCookieHolder */
- final Set<InstanceIdentifier<? extends DataObject>> removeEntriesInstanceIdentifiers =
- changeEvent.getRemovedPaths();
- for (final Entry<InstanceIdentifier<? extends DataObject>, DataObject> createdEntry : createdEntries) {
- InstanceIdentifier<? extends DataObject> entryKey = createdEntry.getKey();
- DataObject entryValue = createdEntry.getValue();
- if (preconditionForChange(entryKey, entryValue, null)) {
- this.add(entryKey, entryValue);
- }
- }
- for (final InstanceIdentifier<?> instanceId : removeEntriesInstanceIdentifiers) {
- Map<InstanceIdentifier<? extends DataObject>, DataObject> origConfigData =
- changeEvent.getOriginalData();
- final DataObject removeValue = origConfigData.get(instanceId);
- if (preconditionForChange(instanceId, removeValue, null)) {
- this.remove(instanceId, removeValue);
- }
- }
- }
-
- @Override
- /* Cleaning FlowCookieManager holder for all node tables */
- protected void remove(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject removeDataObj) {
-
- final InstanceIdentifier<FlowCapableNode> flowNodeIdent =
- identifier.firstIdentifierOf(FlowCapableNode.class);
- final FlowCapableNode flowNode = ((FlowCapableNode) removeDataObj);
-
- for (Table flowTable : flowNode.getTable()) {
- final InstanceIdentifier<Table> tableIdent =
- flowNodeIdent.child(Table.class, flowTable.getKey());
- FlowCookieProducer.INSTANCE.clean(tableIdent);
- }
- }
-
- @Override
- /* Reconciliation by connect new FlowCapableNode */
- protected void add(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject addDataObj) {
-
- final InstanceIdentifier<FlowCapableNode> flowNodeIdent =
- identifier.firstIdentifierOf(FlowCapableNode.class);
- final Optional<FlowCapableNode> flowCapNode = this.readFlowCapableNode(flowNodeIdent);
-
- if (flowCapNode.isPresent()) {
- final InstanceIdentifier<Node> nodeIdent = identifier.firstIdentifierOf(Node.class);
- final NodeRef nodeRef = new NodeRef(nodeIdent);
- /* Groups - have to be first */
- List<Group> groups = flowCapNode.get().getGroup();
- if(groups != null) {
- for (Group group : groups) {
- final GroupRef groupRef = new GroupRef(flowNodeIdent.child(Group.class, group.getKey()));
- final AddGroupInputBuilder groupBuilder = new AddGroupInputBuilder(group);
- groupBuilder.setGroupRef(groupRef);
- groupBuilder.setNode(nodeRef);
- this.provider.getSalGroupService().addGroup(groupBuilder.build());
- }
- }
- /* Meters */
- List<Meter> meters = flowCapNode.get().getMeter();
- if(meters != null) {
- for (Meter meter : meters) {
- final MeterRef meterRef = new MeterRef(flowNodeIdent.child(Meter.class, meter.getKey()));
- final AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder(meter);
- meterBuilder.setMeterRef(meterRef);
- meterBuilder.setNode(nodeRef);
- this.provider.getSalMeterService().addMeter(meterBuilder.build());
- }
- }
- /* Flows */
- List<Table> tables = flowCapNode.get().getTable();
- if(tables != null) {
- for (Table flowTable : tables) {
- final InstanceIdentifier<Table> tableIdent = flowNodeIdent.child(Table.class, flowTable.getKey());
- List<Flow> flows = flowTable.getFlow();
- if(flows != null) {
- for (Flow flow : flows) {
- final FlowCookie flowCookie = new FlowCookie(FlowCookieProducer.INSTANCE.getNewCookie(tableIdent));
- final FlowRef flowRef = new FlowRef(tableIdent.child(Flow.class, flow.getKey()));
- final FlowTableRef flowTableRef = new FlowTableRef(tableIdent);
- final AddFlowInputBuilder flowBuilder = new AddFlowInputBuilder(flow);
- flowBuilder.setCookie(flowCookie);
- flowBuilder.setNode(nodeRef);
- flowBuilder.setFlowTable(flowTableRef);
- flowBuilder.setFlowRef(flowRef);
- this.provider.getSalFlowService().addFlow(flowBuilder.build());
- }
- }
- }
- }
- }
- }
-
- @Override
- protected void update(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject original, final DataObject update) {
- // NOOP - Listener is registered for DataChangeScope.BASE only
- }
-
- @Override
- protected boolean preconditionForChange(final InstanceIdentifier<? extends DataObject> identifier,
- final DataObject dataObj, final DataObject update) {
- return (dataObj instanceof FlowCapableNode);
- }
-
- private Optional<FlowCapableNode> readFlowCapableNode(final InstanceIdentifier<FlowCapableNode> flowNodeIdent) {
- ReadOnlyTransaction readTrans = this.provider.getDataService().newReadOnlyTransaction();
- try {
- ListenableFuture<Optional<FlowCapableNode>> confFlowNode =
- readTrans.read(LogicalDatastoreType.CONFIGURATION, flowNodeIdent);
- if (confFlowNode.get().isPresent()) {
- return Optional.<FlowCapableNode> of(confFlowNode.get().get());
- } else {
- return Optional.absent();
- }
- }
- catch (InterruptedException | ExecutionException e) {
- LOG.error("Unexpected exception by reading flow ".concat(flowNodeIdent.toString()), e);
- return Optional.absent();
- }
- finally {
- readTrans.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.frm.reconil;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
-import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.RpcConsumerRegistry;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
-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;
-
-/**
- * forwardingrules-manager
- * org.opendaylight.controller.frm
- *
- * FlowNode Reconciliation Provider registers the FlowNodeReconilListener
- * and it holds all needed services for FlowNodeReconcilListener.
- *
- * @author <a href="mailto:vdemcak@cisco.com">Vaclav Demcak</a>
- *
- * Created: Jun 13, 2014
- */
-public class FlowNodeReconcilProvider implements AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(FlowNodeReconcilProvider.class);
-
- private SalFlowService salFlowService;
- private SalMeterService salMeterService;
- private SalGroupService salGroupService;
- private DataBroker dataService;
-
- /* DataChangeListener */
- private DataChangeListener flowNodeReconcilListener;
- private ListenerRegistration<DataChangeListener> flowNodeReconcilListenerRegistration;
-
- public void init (final DataBroker dataService) {
- LOG.info("FRM Flow Node Config Reconcil Provider initialization.");
-
- this.dataService = Preconditions.checkNotNull(dataService, "DataProviderService can not be null !");
- }
-
- public void start( final RpcConsumerRegistry rpcRegistry ) {
- Preconditions.checkArgument(rpcRegistry != null, "RpcConcumerRegistry can not be null !");
-
- this.salFlowService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalFlowService.class),
- "RPC SalFlowService not found.");
- this.salMeterService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalMeterService.class),
- "RPC SalMeterService not found.");
- this.salGroupService = Preconditions.checkNotNull(rpcRegistry.getRpcService(SalGroupService.class),
- "RPC SalGroupService not found.");
-
- /* Build Path */
- InstanceIdentifier<FlowCapableNode> flowCapableNodeIdent =
- InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class);
-
- /* ReconcilNotificationListener registration */
- this.flowNodeReconcilListener = new FlowNodeReconcilListener(FlowNodeReconcilProvider.this);
- this.flowNodeReconcilListenerRegistration = this.dataService.registerDataChangeListener(
- LogicalDatastoreType.OPERATIONAL, flowCapableNodeIdent, flowNodeReconcilListener, DataChangeScope.BASE);
- LOG.info("FRM Flow Node Config Reconcil Provider started.");
- }
-
- @Override
- public void close() {
- LOG.info("FRM Flow Node Config Reconcil Provider stopped.");
- if (flowNodeReconcilListenerRegistration != null) {
- try {
- flowNodeReconcilListenerRegistration.close();
- } catch (Exception e) {
- String errMsg = "Error by stop FRM Flow Node Config Reconcil Provider.";
- LOG.error(errMsg, e);
- throw new IllegalStateException(errMsg, e);
- } finally {
- flowNodeReconcilListenerRegistration = null;
- }
- }
- }
-
- public DataChangeListener getFlowNodeReconcilListener() {
- return flowNodeReconcilListener;
- }
-
- public DataBroker getDataService() {
- return dataService;
- }
-
- public SalFlowService getSalFlowService() {
- return salFlowService;
- }
-
- public SalMeterService getSalMeterService() {
- return salMeterService;
- }
-
- public SalGroupService getSalGroupService() {
- return salGroupService;
- }
-}
--- /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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableBuilder;
+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.Flow;
+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.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalFlowServiceMock;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class FlowListenerTest extends FRMTest {
+ RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+ NodeKey s1Key = new NodeKey(new NodeId("S1"));
+ TableKey tableKey = new TableKey((short) 2);
+
+ @Test
+ public void addTwoFlowsTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+ InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+ InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+ Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+ assertEquals(1, addFlowCalls.size());
+ assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+ flowKey = new FlowKey(new FlowId("test_Flow2"));
+ flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ addFlowCalls = salFlowService.getAddFlowCalls();
+ assertEquals(2, addFlowCalls.size());
+ assertEquals("DOM-1", addFlowCalls.get(1).getTransactionUri().getValue());
+ assertEquals(2, addFlowCalls.get(1).getTableId().intValue());
+ assertEquals(flowII, addFlowCalls.get(1).getFlowRef().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void updateFlowTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+ InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+ InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+ Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+ assertEquals(1, addFlowCalls.size());
+ assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+ flowKey = new FlowKey(new FlowId("test_Flow"));
+ flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).setOutGroup((long) 5).build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
+ assertEquals(1, updateFlowCalls.size());
+ assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
+ assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void updateFlowScopeTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+ InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+ InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+ IpMatch ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)4)).build();
+ Match match = new MatchBuilder().setIpMatch(ipMatch).build();
+ Flow flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+ assertEquals(1, addFlowCalls.size());
+ assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+ flowKey = new FlowKey(new FlowId("test_Flow"));
+ flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ ipMatch = new IpMatchBuilder().setIpDscp(new Dscp((short)5)).build();
+ match = new MatchBuilder().setIpMatch(ipMatch).build();
+ flow = new FlowBuilder().setMatch(match).setKey(flowKey).setTableId((short) 2).build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<UpdateFlowInput> updateFlowCalls = salFlowService.getUpdateFlowCalls();
+ assertEquals(1, updateFlowCalls.size());
+ assertEquals("DOM-1", updateFlowCalls.get(0).getTransactionUri().getValue());
+ assertEquals(flowII, updateFlowCalls.get(0).getFlowRef().getValue());
+ assertEquals(ipMatch, updateFlowCalls.get(0).getUpdatedFlow().getMatch().getIpMatch());
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void deleteFlowTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ FlowKey flowKey = new FlowKey(new FlowId("test_Flow"));
+ InstanceIdentifier<Table> tableII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey);
+ InstanceIdentifier<Flow> flowII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Table.class, tableKey).child(Flow.class, flowKey);
+ Table table = new TableBuilder().setKey(tableKey).setFlow(Collections.<Flow>emptyList()).build();
+ Flow flow = new FlowBuilder().setKey(flowKey).setTableId((short) 2).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, tableII, table);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowII, flow);
+ assertCommit(writeTx.submit());
+ SalFlowServiceMock salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<AddFlowInput> addFlowCalls = salFlowService.getAddFlowCalls();
+ assertEquals(1, addFlowCalls.size());
+ assertEquals("DOM-0", addFlowCalls.get(0).getTransactionUri().getValue());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, flowII);
+ assertCommit(writeTx.submit());
+ salFlowService = (SalFlowServiceMock) forwardingRulesManager.getSalFlowService();
+ List<RemoveFlowInput> removeFlowCalls = salFlowService.getRemoveFlowCalls();
+ assertEquals(1, removeFlowCalls.size());
+ assertEquals("DOM-1", removeFlowCalls.get(0).getTransactionUri().getValue());
+ assertEquals(flowII, removeFlowCalls.get(0).getFlowRef().getValue());
+
+ forwardingRulesManager.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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.GroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalGroupServiceMock;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class GroupListenerTest extends FRMTest {
+ RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+ NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+ @Test
+ public void addTwoGroupsTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+ InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+ Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ assertCommit(writeTx.submit());
+ SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+ assertEquals(1, addGroupCalls.size());
+ assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+ groupKey = new GroupKey(new GroupId((long) 256));
+ groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+ group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ assertCommit(writeTx.submit());
+ salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ addGroupCalls = salGroupService.getAddGroupCalls();
+ assertEquals(2, addGroupCalls.size());
+ assertEquals("DOM-1", addGroupCalls.get(1).getTransactionUri().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void updateGroupTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+ InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+ Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ assertCommit(writeTx.submit());
+ SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+ assertEquals(1, addGroupCalls.size());
+ assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+ group = new GroupBuilder().setKey(groupKey).setGroupName("Group2").build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ assertCommit(writeTx.submit());
+ salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ List<UpdateGroupInput> updateGroupCalls = salGroupService.getUpdateGroupCalls();
+ assertEquals(1, updateGroupCalls.size());
+ assertEquals("DOM-1", updateGroupCalls.get(0).getTransactionUri().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void removeGroupTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ GroupKey groupKey = new GroupKey(new GroupId((long) 255));
+ InstanceIdentifier<Group> groupII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Group.class, groupKey);
+ Group group = new GroupBuilder().setKey(groupKey).setGroupName("Group1").build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, groupII, group);
+ assertCommit(writeTx.submit());
+ SalGroupServiceMock salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ List<AddGroupInput> addGroupCalls = salGroupService.getAddGroupCalls();
+ assertEquals(1, addGroupCalls.size());
+ assertEquals("DOM-0", addGroupCalls.get(0).getTransactionUri().getValue());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, groupII);
+ assertCommit(writeTx.submit());
+ salGroupService = (SalGroupServiceMock) forwardingRulesManager.getSalGroupService();
+ List<RemoveGroupInput> removeGroupCalls = salGroupService.getRemoveGroupCalls();
+ assertEquals(1, removeGroupCalls.size());
+ assertEquals("DOM-1", removeGroupCalls.get(0).getTransactionUri().getValue());
+
+ forwardingRulesManager.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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.Meter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.MeterId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+import test.mock.util.SalMeterServiceMock;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class MeterListenerTest extends FRMTest {
+ RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+ NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+ @Test
+ public void addTwoMetersTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+ InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+ Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ assertCommit(writeTx.submit());
+ SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+ assertEquals(1, addMeterCalls.size());
+ assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+ meterKey = new MeterKey(new MeterId((long) 2001));
+ meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+ meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_two").setBarrier(true).build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ assertCommit(writeTx.submit());
+ salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ addMeterCalls = salMeterService.getAddMeterCalls();
+ assertEquals(2, addMeterCalls.size());
+ assertEquals("DOM-1", addMeterCalls.get(1).getTransactionUri().getValue());
+ assertEquals(meterII, addMeterCalls.get(1).getMeterRef().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void updateMeterTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+ InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+ Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").setBarrier(false).build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ assertCommit(writeTx.submit());
+ SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+ assertEquals(1, addMeterCalls.size());
+ assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+ meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_two").setBarrier(true).build();
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ assertCommit(writeTx.submit());
+ salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ List<UpdateMeterInput> updateMeterCalls = salMeterService.getUpdateMeterCalls();
+ assertEquals(1, updateMeterCalls.size());
+ assertEquals("DOM-1", updateMeterCalls.get(0).getTransactionUri().getValue());
+ assertEquals(meterII, updateMeterCalls.get(0).getMeterRef().getValue());
+
+ forwardingRulesManager.close();
+ }
+
+ @Test
+ public void removeMeterTest() throws Exception {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ MeterKey meterKey = new MeterKey(new MeterId((long) 2000));
+ InstanceIdentifier<Meter> meterII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class).child(Meter.class, meterKey);
+ Meter meter = new MeterBuilder().setKey(meterKey).setMeterName("meter_one").build();
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, meterII, meter);
+ assertCommit(writeTx.submit());
+ SalMeterServiceMock salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ List<AddMeterInput> addMeterCalls = salMeterService.getAddMeterCalls();
+ assertEquals(1, addMeterCalls.size());
+ assertEquals("DOM-0", addMeterCalls.get(0).getTransactionUri().getValue());
+
+ writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.CONFIGURATION, meterII);
+ assertCommit(writeTx.submit());
+ salMeterService = (SalMeterServiceMock) forwardingRulesManager.getSalMeterService();
+ List<RemoveMeterInput> removeMeterCalls = salMeterService.getRemoveMeterCalls();
+ assertEquals(1, removeMeterCalls.size());
+ assertEquals("DOM-1", removeMeterCalls.get(0).getTransactionUri().getValue());
+ assertEquals(meterII, removeMeterCalls.get(0).getMeterRef().getValue());
+
+ forwardingRulesManager.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 test.mock;
+
+import org.junit.Test;
+import org.opendaylight.controller.frm.impl.ForwardingRulesManagerImpl;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import test.mock.util.FRMTest;
+import test.mock.util.RpcProviderRegistryMock;
+
+import java.util.concurrent.ExecutionException;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class NodeListenerTest extends FRMTest {
+
+ RpcProviderRegistry rpcProviderRegistryMock = new RpcProviderRegistryMock();
+ NodeKey s1Key = new NodeKey(new NodeId("S1"));
+
+ @Test
+ public void addRemoveNodeTest() throws ExecutionException, InterruptedException {
+ ForwardingRulesManagerImpl forwardingRulesManager = new ForwardingRulesManagerImpl(getDataBroker(), rpcProviderRegistryMock);
+ forwardingRulesManager.start();
+
+ addFlowCapableNode(s1Key);
+
+ InstanceIdentifier<FlowCapableNode> nodeII = InstanceIdentifier.create(Nodes.class).child(Node.class, s1Key)
+ .augmentation(FlowCapableNode.class);
+
+ boolean nodeActive = forwardingRulesManager.isNodeActive(nodeII);
+ assertTrue(nodeActive);
+
+ removeNode(s1Key);
+
+ nodeActive = forwardingRulesManager.isNodeActive(nodeII);
+ assertFalse(nodeActive);
+ }
+
+
+}
--- /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 test.mock.util;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
+
+ private DataBrokerTestCustomizer testCustomizer;
+ private DataBroker dataBroker;
+ private DOMDataBroker domBroker;
+
+
+ @Override
+ protected void setupWithSchema(final SchemaContext context) {
+ testCustomizer = createDataBrokerTestCustomizer();
+ dataBroker = testCustomizer.createDataBroker();
+ domBroker = testCustomizer.createDOMDataBroker();
+ testCustomizer.updateSchema(context);
+ setupWithDataBroker(dataBroker);
+ }
+
+ protected void setupWithDataBroker(final DataBroker dataBroker) {
+ // Intentionally left No-op, subclasses may customize it
+ }
+
+ protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+ return new DataBrokerTestCustomizer();
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ public DOMDataBroker getDomBroker() {
+ return domBroker;
+ }
+
+ protected static final void assertCommit(final ListenableFuture<Void> commit) {
+ try {
+ commit.get(500, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new IllegalStateException(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 test.mock.util;
+
+import org.junit.Before;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public abstract class AbstractSchemaAwareTest {
+
+ private Iterable<YangModuleInfo> moduleInfos;
+ private SchemaContext schemaContext;
+
+
+ protected Iterable<YangModuleInfo> getModuleInfos() {
+ return BindingReflections.loadModuleInfos();
+ }
+
+
+ @Before
+ public final void setup() {
+ moduleInfos = getModuleInfos();
+ ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+ moduleContext.addModuleInfos(moduleInfos);
+ schemaContext = moduleContext.tryToCreateSchemaContext().get();
+ setupWithSchema(schemaContext);
+ }
+
+ /**
+ * Setups test with Schema context.
+ * This method is called before {@link #setupWithSchemaService(SchemaService)}
+ *
+ * @param context
+ */
+ protected abstract void setupWithSchema(SchemaContext context);
+
+}
--- /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 test.mock.util;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import javassist.ClassPool;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBackwardsCompatibleDataBroker;
+import org.opendaylight.controller.md.sal.binding.impl.ForwardedBindingDataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.DOMDataBrokerImpl;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.yangtools.sal.binding.generator.impl.RuntimeGeneratedMappingServiceImpl;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class DataBrokerTestCustomizer {
+
+ private DOMDataBroker domDataBroker;
+ private final RuntimeGeneratedMappingServiceImpl mappingService;
+ private final MockSchemaService schemaService;
+ private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+ private final BindingToNormalizedNodeCodec bindingToNormalized ;
+
+ public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
+ return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+ .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+ .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
+ .build();
+ }
+
+ public DataBrokerTestCustomizer() {
+ schemaService = new MockSchemaService();
+ ClassPool pool = ClassPool.getDefault();
+ mappingService = new RuntimeGeneratedMappingServiceImpl(pool);
+ DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+ BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+ GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+ bindingToNormalized = new BindingToNormalizedNodeCodec(loading, mappingService, codecRegistry);
+ schemaService.registerSchemaContextListener(bindingToNormalized);
+ }
+
+ public DOMStore createConfigurationDatastore() {
+ InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG",
+ MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+ schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMStore createOperationalDatastore() {
+ InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER",
+ MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor());
+ schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMDataBroker createDOMDataBroker() {
+ return new DOMDataBrokerImpl(getDatastores(), getCommitCoordinatorExecutor());
+ }
+
+ public ListeningExecutorService getCommitCoordinatorExecutor() {
+ return MoreExecutors.sameThreadExecutor();
+ }
+
+ public DataBroker createDataBroker() {
+ return new ForwardedBindingDataBroker(getDOMDataBroker(), bindingToNormalized, schemaService );
+ }
+
+ public ForwardedBackwardsCompatibleDataBroker createBackwardsCompatibleDataBroker() {
+ return new ForwardedBackwardsCompatibleDataBroker(getDOMDataBroker(), bindingToNormalized, getSchemaService(), MoreExecutors.sameThreadExecutor());
+ }
+
+ private SchemaService getSchemaService() {
+ return schemaService;
+ }
+
+ private DOMDataBroker getDOMDataBroker() {
+ if(domDataBroker == null) {
+ domDataBroker = createDOMDataBroker();
+ }
+ return domDataBroker;
+ }
+
+ private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+ if (datastores == null) {
+ datastores = createDatastores();
+ }
+ return datastores;
+ }
+
+ public void updateSchema(final SchemaContext ctx) {
+ schemaService.changeSchema(ctx);
+ mappingService.onGlobalContextUpdated(ctx);
+ }
+
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+
+public abstract class FRMTest extends AbstractDataBrokerTest{
+
+ public void addFlowCapableNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+ Nodes nodes = new NodesBuilder().setNode(Collections.<Node>emptyList()).build();
+ InstanceIdentifier<Node> flowNodeIdentifier = InstanceIdentifier.create(Nodes.class)
+ .child(Node.class, nodeKey);
+
+ FlowCapableNodeBuilder fcnBuilder = new FlowCapableNodeBuilder();
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setKey(nodeKey);
+ nodeBuilder.addAugmentation(FlowCapableNode.class, fcnBuilder.build());
+
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.OPERATIONAL, flowNodeIdentifier, nodeBuilder.build());
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Nodes.class), nodes);
+ writeTx.put(LogicalDatastoreType.CONFIGURATION, flowNodeIdentifier, nodeBuilder.build());
+ assertCommit(writeTx.submit());
+ }
+
+ public void removeNode(NodeKey nodeKey) throws ExecutionException, InterruptedException {
+ WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+ writeTx.delete(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.create(Nodes.class).child(Node.class, nodeKey));
+ writeTx.submit().get();
+ }
+}
--- /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 test.mock.util;
+
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.dom.broker.impl.SchemaContextProvider;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+
+@SuppressWarnings("deprecation")
+public final class MockSchemaService implements SchemaService, SchemaContextProvider {
+
+ private SchemaContext schemaContext;
+
+ ListenerRegistry<SchemaContextListener> listeners = ListenerRegistry.create();
+
+ @Override
+ public void addModule(final Module module) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized SchemaContext getGlobalContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public synchronized SchemaContext getSessionContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public ListenerRegistration<SchemaContextListener> registerSchemaContextListener(
+ final SchemaContextListener listener) {
+ return listeners.register(listener);
+ }
+
+ @Override
+ public void removeModule(final Module module) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public synchronized SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ public synchronized void changeSchema(final SchemaContext newContext) {
+ schemaContext = newContext;
+ for (ListenerRegistration<SchemaContextListener> listener : listeners) {
+ listener.getInstance().onGlobalContextUpdated(schemaContext);
+ }
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.controller.md.sal.common.api.routing.RouteChangeListener;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.controller.sal.binding.api.rpc.RpcContextIdentifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.RpcService;
+
+public class RpcProviderRegistryMock implements RpcProviderRegistry {
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RpcRegistration<T> addRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface, T implementation) throws IllegalStateException {
+ return null;
+ }
+
+ @Override
+ public <L extends RouteChangeListener<RpcContextIdentifier, InstanceIdentifier<?>>> ListenerRegistration<L> registerRouteChangeListener(L listener) {
+ return null;
+ }
+
+ @Override
+ public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
+ if (serviceInterface.equals(SalFlowService.class)) {
+ return (T) new SalFlowServiceMock();
+ } else if (serviceInterface.equals(SalGroupService.class)) {
+ return (T) new SalGroupServiceMock();
+ } else if (serviceInterface.equals(SalMeterService.class)) {
+ return (T) new SalMeterServiceMock();
+ } else {
+ return null;
+ }
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalFlowServiceMock implements SalFlowService{
+ private List<AddFlowInput> addFlowCalls = new ArrayList<>();
+ private List<RemoveFlowInput> removeFlowCalls = new ArrayList<>();
+ private List<UpdateFlowInput> updateFlowCalls = new ArrayList<>();
+
+ @Override
+ public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
+ addFlowCalls.add(input);
+ return null;
+ }
+
+
+ @Override
+ public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
+ removeFlowCalls.add(input);
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
+ updateFlowCalls.add(input);
+ return null;
+ }
+
+ public List<AddFlowInput> getAddFlowCalls() {
+ return addFlowCalls;
+ }
+
+ public List<RemoveFlowInput> getRemoveFlowCalls() {
+ return removeFlowCalls;
+ }
+
+ public List<UpdateFlowInput> getUpdateFlowCalls() {
+ return updateFlowCalls;
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.SalGroupService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalGroupServiceMock implements SalGroupService {
+ private List<AddGroupInput> addGroupCalls = new ArrayList<>();
+ private List<RemoveGroupInput> removeGroupCalls = new ArrayList<>();
+ private List<UpdateGroupInput> updateGroupCalls = new ArrayList<>();
+
+ @Override
+ public Future<RpcResult<AddGroupOutput>> addGroup(AddGroupInput input) {
+ addGroupCalls.add(input);
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<RemoveGroupOutput>> removeGroup(RemoveGroupInput input) {
+ removeGroupCalls.add(input);
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<UpdateGroupOutput>> updateGroup(UpdateGroupInput input) {
+ updateGroupCalls.add(input);
+ return null;
+ }
+
+ public List<AddGroupInput> getAddGroupCalls() {
+ return addGroupCalls;
+ }
+
+ public List<RemoveGroupInput> getRemoveGroupCalls() {
+ return removeGroupCalls;
+ }
+
+ public List<UpdateGroupInput> getUpdateGroupCalls() {
+ return updateGroupCalls;
+ }
+}
--- /dev/null
+package test.mock.util;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.RemoveMeterOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterOutput;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Future;
+
+public class SalMeterServiceMock implements SalMeterService {
+ private List<AddMeterInput> addMeterCalls = new ArrayList<>();
+ private List<RemoveMeterInput> removeMeterCalls = new ArrayList<>();
+ private List<UpdateMeterInput> updateMeterCalls = new ArrayList<>();
+
+ @Override
+ public Future<RpcResult<AddMeterOutput>> addMeter(AddMeterInput input) {
+ addMeterCalls.add(input);
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<RemoveMeterOutput>> removeMeter(RemoveMeterInput input) {
+ removeMeterCalls.add(input);
+ return null;
+ }
+
+ @Override
+ public Future<RpcResult<UpdateMeterOutput>> updateMeter(UpdateMeterInput input) {
+ updateMeterCalls.add(input);
+ return null;
+ }
+
+ public List<AddMeterInput> getAddMeterCalls() {
+ return addMeterCalls;
+ }
+
+ public List<RemoveMeterInput> getRemoveMeterCalls() {
+ return removeMeterCalls;
+ }
+
+ public List<UpdateMeterInput> getUpdateMeterCalls() {
+ return updateMeterCalls;
+ }
+}
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-config-datastore-provider</type>
<name>config-store-service</name>
- <schema-service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <name>yang-schema-service</name>
- </schema-service>
+ <inmemory-config-datastore-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </inmemory-config-datastore-provider>
</module>
<module>
<type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">prefix:inmemory-operational-datastore-provider</type>
<name>operational-store-service</name>
- <operational-schema-service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <name>yang-schema-service</name>
- </operational-schema-service>
+ <inmemory-operational-datastore-provider xmlns="urn:opendaylight:params:xml:ns:yang:controller:inmemory-datastore-provider">
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ </inmemory-operational-datastore-provider>
</module>
<!--
Tree-based in-memory data store. This is the data store which is currently
<dependencies>
<dependency>
- <groupId>com.google.protobuf</groupId>
- <artifactId>protobuf-java</artifactId>
- <version>2.5.0</version>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-clustering-commons</artifactId>
+ <version>1.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
package org.opendaylight.controller.cluster.example.messages;
import com.google.protobuf.GeneratedMessage;
-import org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.example.KeyValueMessages;
import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
import java.io.Serializable;
import java.util.HashMap;
import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
import org.opendaylight.controller.cluster.raft.ReplicatedLogImplEntry;
import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
import java.util.ArrayList;
import java.util.Iterator;
import com.google.protobuf.GeneratedMessage;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
import java.util.Map;
+++ /dev/null
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: VotingMessages.proto
-
-package org.opendaylight.controller.cluster.raft.protobuff.messages;
-
-public final class VotingMessages {
- private VotingMessages() {}
- public static void registerAllExtensions(
- com.google.protobuf.ExtensionRegistry registry) {
- }
- public interface RequestVoteOrBuilder
- extends com.google.protobuf.MessageOrBuilder {
-
- // optional int64 term = 1;
- /**
- * <code>optional int64 term = 1;</code>
- */
- boolean hasTerm();
- /**
- * <code>optional int64 term = 1;</code>
- */
- long getTerm();
-
- // optional string candidateId = 2;
- /**
- * <code>optional string candidateId = 2;</code>
- */
- boolean hasCandidateId();
- /**
- * <code>optional string candidateId = 2;</code>
- */
- java.lang.String getCandidateId();
- /**
- * <code>optional string candidateId = 2;</code>
- */
- com.google.protobuf.ByteString
- getCandidateIdBytes();
-
- // optional int64 lastLongIndex = 3;
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- boolean hasLastLongIndex();
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- long getLastLongIndex();
-
- // optional int64 lastLongTerm = 4;
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- boolean hasLastLongTerm();
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- long getLastLongTerm();
- }
- /**
- * Protobuf type {@code org.opendaylight.controller.cluster.raft.RequestVote}
- */
- public static final class RequestVote extends
- com.google.protobuf.GeneratedMessage
- implements RequestVoteOrBuilder {
- // Use RequestVote.newBuilder() to construct.
- private RequestVote(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
- super(builder);
- this.unknownFields = builder.getUnknownFields();
- }
- private RequestVote(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
- private static final RequestVote defaultInstance;
- public static RequestVote getDefaultInstance() {
- return defaultInstance;
- }
-
- public RequestVote getDefaultInstanceForType() {
- return defaultInstance;
- }
-
- private final com.google.protobuf.UnknownFieldSet unknownFields;
- @java.lang.Override
- public final com.google.protobuf.UnknownFieldSet
- getUnknownFields() {
- return this.unknownFields;
- }
- private RequestVote(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- initFields();
- int mutable_bitField0_ = 0;
- com.google.protobuf.UnknownFieldSet.Builder unknownFields =
- com.google.protobuf.UnknownFieldSet.newBuilder();
- try {
- boolean done = false;
- while (!done) {
- int tag = input.readTag();
- switch (tag) {
- case 0:
- done = true;
- break;
- default: {
- if (!parseUnknownField(input, unknownFields,
- extensionRegistry, tag)) {
- done = true;
- }
- break;
- }
- case 8: {
- bitField0_ |= 0x00000001;
- term_ = input.readInt64();
- break;
- }
- case 18: {
- bitField0_ |= 0x00000002;
- candidateId_ = input.readBytes();
- break;
- }
- case 24: {
- bitField0_ |= 0x00000004;
- lastLongIndex_ = input.readInt64();
- break;
- }
- case 32: {
- bitField0_ |= 0x00000008;
- lastLongTerm_ = input.readInt64();
- break;
- }
- }
- }
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- throw e.setUnfinishedMessage(this);
- } catch (java.io.IOException e) {
- throw new com.google.protobuf.InvalidProtocolBufferException(
- e.getMessage()).setUnfinishedMessage(this);
- } finally {
- this.unknownFields = unknownFields.build();
- makeExtensionsImmutable();
- }
- }
- public static final com.google.protobuf.Descriptors.Descriptor
- getDescriptor() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
- }
-
- protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
- internalGetFieldAccessorTable() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable
- .ensureFieldAccessorsInitialized(
- org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.class, org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.Builder.class);
- }
-
- public static com.google.protobuf.Parser<RequestVote> PARSER =
- new com.google.protobuf.AbstractParser<RequestVote>() {
- public RequestVote parsePartialFrom(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return new RequestVote(input, extensionRegistry);
- }
- };
-
- @java.lang.Override
- public com.google.protobuf.Parser<RequestVote> getParserForType() {
- return PARSER;
- }
-
- private int bitField0_;
- // optional int64 term = 1;
- public static final int TERM_FIELD_NUMBER = 1;
- private long term_;
- /**
- * <code>optional int64 term = 1;</code>
- */
- public boolean hasTerm() {
- return ((bitField0_ & 0x00000001) == 0x00000001);
- }
- /**
- * <code>optional int64 term = 1;</code>
- */
- public long getTerm() {
- return term_;
- }
-
- // optional string candidateId = 2;
- public static final int CANDIDATEID_FIELD_NUMBER = 2;
- private java.lang.Object candidateId_;
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public boolean hasCandidateId() {
- return ((bitField0_ & 0x00000002) == 0x00000002);
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public java.lang.String getCandidateId() {
- java.lang.Object ref = candidateId_;
- if (ref instanceof java.lang.String) {
- return (java.lang.String) ref;
- } else {
- com.google.protobuf.ByteString bs =
- (com.google.protobuf.ByteString) ref;
- java.lang.String s = bs.toStringUtf8();
- if (bs.isValidUtf8()) {
- candidateId_ = s;
- }
- return s;
- }
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public com.google.protobuf.ByteString
- getCandidateIdBytes() {
- java.lang.Object ref = candidateId_;
- if (ref instanceof java.lang.String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- candidateId_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
-
- // optional int64 lastLongIndex = 3;
- public static final int LASTLONGINDEX_FIELD_NUMBER = 3;
- private long lastLongIndex_;
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public boolean hasLastLongIndex() {
- return ((bitField0_ & 0x00000004) == 0x00000004);
- }
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public long getLastLongIndex() {
- return lastLongIndex_;
- }
-
- // optional int64 lastLongTerm = 4;
- public static final int LASTLONGTERM_FIELD_NUMBER = 4;
- private long lastLongTerm_;
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public boolean hasLastLongTerm() {
- return ((bitField0_ & 0x00000008) == 0x00000008);
- }
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public long getLastLongTerm() {
- return lastLongTerm_;
- }
-
- private void initFields() {
- term_ = 0L;
- candidateId_ = "";
- lastLongIndex_ = 0L;
- lastLongTerm_ = 0L;
- }
- private byte memoizedIsInitialized = -1;
- public final boolean isInitialized() {
- byte isInitialized = memoizedIsInitialized;
- if (isInitialized != -1) return isInitialized == 1;
-
- memoizedIsInitialized = 1;
- return true;
- }
-
- public void writeTo(com.google.protobuf.CodedOutputStream output)
- throws java.io.IOException {
- getSerializedSize();
- if (((bitField0_ & 0x00000001) == 0x00000001)) {
- output.writeInt64(1, term_);
- }
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- output.writeBytes(2, getCandidateIdBytes());
- }
- if (((bitField0_ & 0x00000004) == 0x00000004)) {
- output.writeInt64(3, lastLongIndex_);
- }
- if (((bitField0_ & 0x00000008) == 0x00000008)) {
- output.writeInt64(4, lastLongTerm_);
- }
- getUnknownFields().writeTo(output);
- }
-
- private int memoizedSerializedSize = -1;
- public int getSerializedSize() {
- int size = memoizedSerializedSize;
- if (size != -1) return size;
-
- size = 0;
- if (((bitField0_ & 0x00000001) == 0x00000001)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(1, term_);
- }
- if (((bitField0_ & 0x00000002) == 0x00000002)) {
- size += com.google.protobuf.CodedOutputStream
- .computeBytesSize(2, getCandidateIdBytes());
- }
- if (((bitField0_ & 0x00000004) == 0x00000004)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(3, lastLongIndex_);
- }
- if (((bitField0_ & 0x00000008) == 0x00000008)) {
- size += com.google.protobuf.CodedOutputStream
- .computeInt64Size(4, lastLongTerm_);
- }
- size += getUnknownFields().getSerializedSize();
- memoizedSerializedSize = size;
- return size;
- }
-
- private static final long serialVersionUID = 0L;
- @java.lang.Override
- protected java.lang.Object writeReplace()
- throws java.io.ObjectStreamException {
- return super.writeReplace();
- }
-
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- com.google.protobuf.ByteString data)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- com.google.protobuf.ByteString data,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data, extensionRegistry);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(byte[] data)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- byte[] data,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws com.google.protobuf.InvalidProtocolBufferException {
- return PARSER.parseFrom(data, extensionRegistry);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(java.io.InputStream input)
- throws java.io.IOException {
- return PARSER.parseFrom(input);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- java.io.InputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseFrom(input, extensionRegistry);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseDelimitedFrom(java.io.InputStream input)
- throws java.io.IOException {
- return PARSER.parseDelimitedFrom(input);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseDelimitedFrom(
- java.io.InputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseDelimitedFrom(input, extensionRegistry);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- com.google.protobuf.CodedInputStream input)
- throws java.io.IOException {
- return PARSER.parseFrom(input);
- }
- public static org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parseFrom(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- return PARSER.parseFrom(input, extensionRegistry);
- }
-
- public static Builder newBuilder() { return Builder.create(); }
- public Builder newBuilderForType() { return newBuilder(); }
- public static Builder newBuilder(org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote prototype) {
- return newBuilder().mergeFrom(prototype);
- }
- public Builder toBuilder() { return newBuilder(this); }
-
- @java.lang.Override
- protected Builder newBuilderForType(
- com.google.protobuf.GeneratedMessage.BuilderParent parent) {
- Builder builder = new Builder(parent);
- return builder;
- }
- /**
- * Protobuf type {@code org.opendaylight.controller.cluster.raft.RequestVote}
- */
- public static final class Builder extends
- com.google.protobuf.GeneratedMessage.Builder<Builder>
- implements org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVoteOrBuilder {
- public static final com.google.protobuf.Descriptors.Descriptor
- getDescriptor() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
- }
-
- protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
- internalGetFieldAccessorTable() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable
- .ensureFieldAccessorsInitialized(
- org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.class, org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.Builder.class);
- }
-
- // Construct using org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.newBuilder()
- private Builder() {
- maybeForceBuilderInitialization();
- }
-
- private Builder(
- com.google.protobuf.GeneratedMessage.BuilderParent parent) {
- super(parent);
- maybeForceBuilderInitialization();
- }
- private void maybeForceBuilderInitialization() {
- if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
- }
- }
- private static Builder create() {
- return new Builder();
- }
-
- public Builder clear() {
- super.clear();
- term_ = 0L;
- bitField0_ = (bitField0_ & ~0x00000001);
- candidateId_ = "";
- bitField0_ = (bitField0_ & ~0x00000002);
- lastLongIndex_ = 0L;
- bitField0_ = (bitField0_ & ~0x00000004);
- lastLongTerm_ = 0L;
- bitField0_ = (bitField0_ & ~0x00000008);
- return this;
- }
-
- public Builder clone() {
- return create().mergeFrom(buildPartial());
- }
-
- public com.google.protobuf.Descriptors.Descriptor
- getDescriptorForType() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
- }
-
- public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote getDefaultInstanceForType() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.getDefaultInstance();
- }
-
- public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote build() {
- org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote result = buildPartial();
- if (!result.isInitialized()) {
- throw newUninitializedMessageException(result);
- }
- return result;
- }
-
- public org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote buildPartial() {
- org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote result = new org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote(this);
- int from_bitField0_ = bitField0_;
- int to_bitField0_ = 0;
- if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
- to_bitField0_ |= 0x00000001;
- }
- result.term_ = term_;
- if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
- to_bitField0_ |= 0x00000002;
- }
- result.candidateId_ = candidateId_;
- if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
- to_bitField0_ |= 0x00000004;
- }
- result.lastLongIndex_ = lastLongIndex_;
- if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
- to_bitField0_ |= 0x00000008;
- }
- result.lastLongTerm_ = lastLongTerm_;
- result.bitField0_ = to_bitField0_;
- onBuilt();
- return result;
- }
-
- public Builder mergeFrom(com.google.protobuf.Message other) {
- if (other instanceof org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote) {
- return mergeFrom((org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote)other);
- } else {
- super.mergeFrom(other);
- return this;
- }
- }
-
- public Builder mergeFrom(org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote other) {
- if (other == org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote.getDefaultInstance()) return this;
- if (other.hasTerm()) {
- setTerm(other.getTerm());
- }
- if (other.hasCandidateId()) {
- bitField0_ |= 0x00000002;
- candidateId_ = other.candidateId_;
- onChanged();
- }
- if (other.hasLastLongIndex()) {
- setLastLongIndex(other.getLastLongIndex());
- }
- if (other.hasLastLongTerm()) {
- setLastLongTerm(other.getLastLongTerm());
- }
- this.mergeUnknownFields(other.getUnknownFields());
- return this;
- }
-
- public final boolean isInitialized() {
- return true;
- }
-
- public Builder mergeFrom(
- com.google.protobuf.CodedInputStream input,
- com.google.protobuf.ExtensionRegistryLite extensionRegistry)
- throws java.io.IOException {
- org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote parsedMessage = null;
- try {
- parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- parsedMessage = (org.opendaylight.controller.cluster.raft.protobuff.messages.VotingMessages.RequestVote) e.getUnfinishedMessage();
- throw e;
- } finally {
- if (parsedMessage != null) {
- mergeFrom(parsedMessage);
- }
- }
- return this;
- }
- private int bitField0_;
-
- // optional int64 term = 1;
- private long term_ ;
- /**
- * <code>optional int64 term = 1;</code>
- */
- public boolean hasTerm() {
- return ((bitField0_ & 0x00000001) == 0x00000001);
- }
- /**
- * <code>optional int64 term = 1;</code>
- */
- public long getTerm() {
- return term_;
- }
- /**
- * <code>optional int64 term = 1;</code>
- */
- public Builder setTerm(long value) {
- bitField0_ |= 0x00000001;
- term_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int64 term = 1;</code>
- */
- public Builder clearTerm() {
- bitField0_ = (bitField0_ & ~0x00000001);
- term_ = 0L;
- onChanged();
- return this;
- }
-
- // optional string candidateId = 2;
- private java.lang.Object candidateId_ = "";
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public boolean hasCandidateId() {
- return ((bitField0_ & 0x00000002) == 0x00000002);
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public java.lang.String getCandidateId() {
- java.lang.Object ref = candidateId_;
- if (!(ref instanceof java.lang.String)) {
- java.lang.String s = ((com.google.protobuf.ByteString) ref)
- .toStringUtf8();
- candidateId_ = s;
- return s;
- } else {
- return (java.lang.String) ref;
- }
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public com.google.protobuf.ByteString
- getCandidateIdBytes() {
- java.lang.Object ref = candidateId_;
- if (ref instanceof String) {
- com.google.protobuf.ByteString b =
- com.google.protobuf.ByteString.copyFromUtf8(
- (java.lang.String) ref);
- candidateId_ = b;
- return b;
- } else {
- return (com.google.protobuf.ByteString) ref;
- }
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public Builder setCandidateId(
- java.lang.String value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000002;
- candidateId_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public Builder clearCandidateId() {
- bitField0_ = (bitField0_ & ~0x00000002);
- candidateId_ = getDefaultInstance().getCandidateId();
- onChanged();
- return this;
- }
- /**
- * <code>optional string candidateId = 2;</code>
- */
- public Builder setCandidateIdBytes(
- com.google.protobuf.ByteString value) {
- if (value == null) {
- throw new NullPointerException();
- }
- bitField0_ |= 0x00000002;
- candidateId_ = value;
- onChanged();
- return this;
- }
-
- // optional int64 lastLongIndex = 3;
- private long lastLongIndex_ ;
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public boolean hasLastLongIndex() {
- return ((bitField0_ & 0x00000004) == 0x00000004);
- }
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public long getLastLongIndex() {
- return lastLongIndex_;
- }
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public Builder setLastLongIndex(long value) {
- bitField0_ |= 0x00000004;
- lastLongIndex_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int64 lastLongIndex = 3;</code>
- */
- public Builder clearLastLongIndex() {
- bitField0_ = (bitField0_ & ~0x00000004);
- lastLongIndex_ = 0L;
- onChanged();
- return this;
- }
-
- // optional int64 lastLongTerm = 4;
- private long lastLongTerm_ ;
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public boolean hasLastLongTerm() {
- return ((bitField0_ & 0x00000008) == 0x00000008);
- }
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public long getLastLongTerm() {
- return lastLongTerm_;
- }
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public Builder setLastLongTerm(long value) {
- bitField0_ |= 0x00000008;
- lastLongTerm_ = value;
- onChanged();
- return this;
- }
- /**
- * <code>optional int64 lastLongTerm = 4;</code>
- */
- public Builder clearLastLongTerm() {
- bitField0_ = (bitField0_ & ~0x00000008);
- lastLongTerm_ = 0L;
- onChanged();
- return this;
- }
-
- // @@protoc_insertion_point(builder_scope:org.opendaylight.controller.cluster.raft.RequestVote)
- }
-
- static {
- defaultInstance = new RequestVote(true);
- defaultInstance.initFields();
- }
-
- // @@protoc_insertion_point(class_scope:org.opendaylight.controller.cluster.raft.RequestVote)
- }
-
- private static com.google.protobuf.Descriptors.Descriptor
- internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor;
- private static
- com.google.protobuf.GeneratedMessage.FieldAccessorTable
- internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable;
-
- public static com.google.protobuf.Descriptors.FileDescriptor
- getDescriptor() {
- return descriptor;
- }
- private static com.google.protobuf.Descriptors.FileDescriptor
- descriptor;
- static {
- java.lang.String[] descriptorData = {
- "\n\024VotingMessages.proto\022(org.opendaylight" +
- ".controller.cluster.raft\"]\n\013RequestVote\022" +
- "\014\n\004term\030\001 \001(\003\022\023\n\013candidateId\030\002 \001(\t\022\025\n\rla" +
- "stLongIndex\030\003 \001(\003\022\024\n\014lastLongTerm\030\004 \001(\003B" +
- "O\n;org.opendaylight.controller.cluster.r" +
- "aft.protobuff.messagesB\016VotingMessagesH\001"
- };
- com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
- new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
- public com.google.protobuf.ExtensionRegistry assignDescriptors(
- com.google.protobuf.Descriptors.FileDescriptor root) {
- descriptor = root;
- internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor =
- getDescriptor().getMessageTypes().get(0);
- internal_static_org_opendaylight_controller_cluster_raft_RequestVote_fieldAccessorTable = new
- com.google.protobuf.GeneratedMessage.FieldAccessorTable(
- internal_static_org_opendaylight_controller_cluster_raft_RequestVote_descriptor,
- new java.lang.String[] { "Term", "CandidateId", "LastLongIndex", "LastLongTerm", });
- return null;
- }
- };
- com.google.protobuf.Descriptors.FileDescriptor
- .internalBuildGeneratedFileFrom(descriptorData,
- new com.google.protobuf.Descriptors.FileDescriptor[] {
- }, assigner);
- }
-
- // @@protoc_insertion_point(outer_class_scope)
-}
+++ /dev/null
-package org.opendaylight.controller.cluster.raft;
-
-option java_package = "org.opendaylight.controller.cluster.raft.protobuff.messages";
-option java_outer_classname = "VotingMessages";
-option optimize_for = SPEED;
-
-message RequestVote {
- optional int64 term = 1;
- optional string candidateId = 2;
- optional int64 lastLongIndex = 3;
- optional int64 lastLongTerm = 4;
-
-}
import akka.event.LoggingAdapter;
import com.google.protobuf.GeneratedMessage;
import org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages;
-import org.opendaylight.controller.cluster.raft.protobuff.messages.MockPayloadMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages;
+import org.opendaylight.controller.protobuff.messages.cluster.raft.test.MockPayloadMessages;
import com.google.common.base.Preconditions;
import java.io.Serializable;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.opendaylight.controller.sal.core.api.RpcProvisionRegistry;
import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.binding.BaseIdentity;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.RpcService;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
-import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Function;
-import com.google.common.collect.FluentIterable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
class DomToBindingRpcForwarder implements RpcImplementation, InvocationHandler {
private final Logger LOG = LoggerFactory.getLogger(DomToBindingRpcForwarder.class);
static {
try {
EQUALS_METHOD = Object.class.getMethod("equals", Object.class);
- } catch (Exception e) {
- throw new RuntimeException(e);
+ } catch (NoSuchMethodException | SecurityException e) {
+ throw new ExceptionInInitializerError(e);
}
}
}
/**
- * Constructor for Routed RPC Forwareder.
+ * Constructor for Routed RPC Forwarder.
*
* @param service
* @param context
<packaging>bundle</packaging>
- <dependencies>
+ <dependencies>
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-actor_${scala.version}</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-cluster_${scala.version}</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-persistence-experimental_${scala.version}</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-remote_${scala.version}</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-testkit_${scala.version}</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>org.scala-lang</groupId>
+ <artifactId>scala-library</artifactId>
+ </dependency>
+
+
+ <dependency>
+ <groupId>com.typesafe.akka</groupId>
+ <artifactId>akka-slf4j_${scala.version}</artifactId>
+ </dependency>
+
+
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<artifactId>yang-binding</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>sal-akka-raft</artifactId>
- <version>1.1-SNAPSHOT</version>
- </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>jsr305</artifactId>
<version>2.0.1</version>
</dependency>
-
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-core</artifactId>
- <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.codahale.metrics</groupId>
+ <artifactId>metrics-graphite</artifactId>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>org.opendaylight.controller.*</include>
+ </includes>
+ <excludes>
+ <exclude>org.opendaylight.controller.protobuff.*</exclude>
+ </excludes>
+ <check>false</check>
+ </configuration>
+ <executions>
+ <execution>
+ <id>pre-test</id>
+ <goals>
+ <goal>prepare-agent</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>post-test</id>
+ <goals>
+ <goal>report</goal>
+ </goals>
+ <phase>test</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
</project>
package org.opendaylight.controller.cluster.datastore.node;
-import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
import org.opendaylight.controller.cluster.datastore.node.utils.PathUtils;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeSerializer;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
}
public NormalizedNodeMessages.Container encode(YangInstanceIdentifier id, NormalizedNode node){
+
+ NormalizedNodeMessages.Container.Builder builder = NormalizedNodeMessages.Container.newBuilder();
String parentPath = "";
if(id != null){
parentPath = PathUtils.getParentPath(PathUtils.toString(id));
}
+ builder.setParentPath(parentPath);
+ if(node != null) {
+ builder.setNormalizedNode(NormalizedNodeSerializer.serialize(node));
+ }
- NormalizedNodeToProtocolBufferNode encoder = new NormalizedNodeToProtocolBufferNode();
- encoder.encode(parentPath, node);
-
- return encoder.getContainer();
-
-
+ return builder.build();
}
public NormalizedNode<?,?> decode(YangInstanceIdentifier id, NormalizedNodeMessages.Node node){
- NodeToNormalizedNodeBuilder currentOp = NodeToNormalizedNodeBuilder.from(ctx);
-
- for(YangInstanceIdentifier.PathArgument pathArgument : id.getPathArguments()){
- currentOp = currentOp.getChild(pathArgument);
- }
-
- QName nodeType = null;
-
- if(id.getPath().size() < 1){
- nodeType = null;
- } else {
- final YangInstanceIdentifier.PathArgument pathArgument = id.getPath().get(id.getPath().size() - 1);
- if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier){
- nodeType = null;
- } else {
- nodeType = pathArgument.getNodeType();
- }
- }
- if((node != null)&& (!node.getType().isEmpty())){
- return currentOp.normalize(nodeType, node);
- } else{
- return null;
- }
+ if(node.getIntType() < 0 || node.getSerializedSize() == 0){
+ return null;
+ }
+ return NormalizedNodeSerializer.deSerialize(node);
}
--- /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.cluster.datastore.node.utils.serialization;
+
+/**
+ * NormalizedNodeDeSerializationContext provides methods which help in decoding
+ * certain components of a NormalizedNode properly
+ */
+
+public interface NormalizedNodeDeSerializationContext {
+ String getNamespace(int namespace);
+ String getRevision(int revision);
+ String getLocalName(int localName);
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import java.net.URI;
+import java.util.Date;
+
+/**
+ * NormalizedNodeSerializationContext provides methods which help in encoding
+ * certain components of a NormalizedNode properly
+ */
+public interface NormalizedNodeSerializationContext {
+ int addNamespace(URI namespace);
+ int addRevision(Date revision);
+ int addLocalName(String localName);
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ANY_XML_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.AUGMENTATION_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.CHOICE_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.CONTAINER_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_SET_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.LEAF_SET_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.MAP_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.MAP_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ORDERED_LEAF_SET_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.ORDERED_MAP_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.UNKEYED_LIST_ENTRY_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.UNKEYED_LIST_NODE_TYPE;
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.NormalizedNodeType.getSerializableNodeType;
+
+/**
+ * NormalizedNodeSerializer can be used to convert a Normalized node to and and
+ * from a protocol buffer message.
+ *
+ *
+ */
+public class NormalizedNodeSerializer {
+
+ /**
+ * Serialize a NormalizedNode into a protocol buffer message
+ * <p>
+ * The significant things to be aware of the Serialization process are
+ * <ul>
+ * <li>Repeated strings like namespaces, revisions and localNames are
+ * compressed to codes and stored in the top level of the normalized
+ * node protocol buffer message
+ * </li>
+ * <li>All value types are encoded for each leaf value. This is so that
+ * the deSerialization process does not need to use the schema context to
+ * figure out how to decode values
+ * </li>
+ * </ul>
+ *
+ * One question which may arise is why not use something like gzip to
+ * compress the protocol buffer message instead of rolling our own
+ * encoding scheme. This has to be explored further as it is a more
+ * general solution.
+ *
+ * @param node
+ * @return
+ */
+ public static NormalizedNodeMessages.Node serialize(NormalizedNode node){
+ Preconditions.checkNotNull(node, "node should not be null");
+ return new Serializer(node).serialize();
+ }
+
+
+ /**
+ * DeSerialize a protocol buffer message back into a NormalizedNode
+ *
+ * @param node
+ * @return
+ */
+ public static NormalizedNode deSerialize(NormalizedNodeMessages.Node node){
+ return new DeSerializer(node).deSerialize();
+ }
+
+ /**
+ * DeSerialize a PathArgument which is in the protocol buffer format into
+ * a yang PathArgument. The protocol buffer path argument is specially
+ * encoded and can only be interpreted in the context of a top level
+ * serialized NormalizedNode protocol buffer message. The reason for this
+ * is that during the NormalizedNode serialization process certain repeated
+ * strings are encoded into a "codes" list and the actual strings are
+ * replaced by an integer which is an index into that list.
+ *
+ * @param node
+ * @param pathArgument
+ * @return
+ */
+ public static YangInstanceIdentifier.PathArgument deSerialize(NormalizedNodeMessages.Node node, NormalizedNodeMessages.PathArgument pathArgument){
+ Preconditions.checkNotNull(node, "node should not be null");
+ Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+ return new DeSerializer(node).deSerialize(pathArgument);
+ }
+
+ private static class Serializer implements NormalizedNodeSerializationContext {
+
+ private final NormalizedNode node;
+
+ private final Map<Object, Integer> codeMap = new HashMap<>();
+ private final List<String> codes = new ArrayList<>();
+
+ private Serializer(NormalizedNode node) {
+ this.node = node;
+ }
+
+ private NormalizedNodeMessages.Node serialize() {
+ return this.serialize(node).addAllCode(codes).build();
+ }
+
+ private NormalizedNodeMessages.Node.Builder serialize(
+ NormalizedNode node) {
+ NormalizedNodeMessages.Node.Builder builder =
+ NormalizedNodeMessages.Node.newBuilder();
+
+ builder.setPathArgument(PathArgumentSerializer.serialize(this, node.getIdentifier()));
+ Integer nodeType = getSerializableNodeType(node).ordinal();
+ builder.setIntType(nodeType);
+ Object value = node.getValue();
+
+ // We need to do a specific check of the type of the node here
+ // because if we looked at the value type alone we will not be
+ // able to distinguish if the value was supposed to be added
+ // as a child or whether the value should be added as a value of the
+ // node.
+ // One use case where this check is necessary when you have a node
+ // with a bits value. In that case the value of the node is a Set
+ // which is also a Collection. Without the following check being
+ // done first the code would flow into the Collection if condition
+ // and the Set would be added as child nodes
+ if(nodeType == NormalizedNodeType.LEAF_NODE_TYPE.ordinal() ||
+ nodeType == NormalizedNodeType.LEAF_SET_ENTRY_NODE_TYPE.ordinal()){
+
+ ValueSerializer.serialize(builder, this, value);
+
+ } else if (value instanceof Iterable) {
+ Iterable iterable = (Iterable) value;
+
+ for (Object o : iterable) {
+ if (o instanceof NormalizedNode) {
+ builder.addChild(serialize((NormalizedNode) o));
+ }
+ }
+
+ } else if (value instanceof NormalizedNode) {
+
+ builder.addChild(serialize((NormalizedNode) value));
+
+ } else {
+
+ ValueSerializer.serialize(builder, this, value);
+ }
+
+ return builder;
+ }
+
+
+ @Override public int addNamespace(URI namespace) {
+ int namespaceInt = getCode(namespace);
+
+ if(namespaceInt == -1) {
+ namespaceInt = addCode(namespace, namespace.toString());
+ }
+ return namespaceInt;
+ }
+
+ @Override public int addRevision(Date revision) {
+ if(revision == null){
+ return -1;
+ }
+
+ int revisionInt = getCode(revision);
+ if(revisionInt == -1) {
+ String formattedRevision =
+ SimpleDateFormatUtil.getRevisionFormat().format(revision);
+ revisionInt = addCode(revision, formattedRevision);
+ }
+ return revisionInt;
+ }
+
+ @Override public int addLocalName(String localName) {
+ int localNameInt = getCode(localName);
+ if(localNameInt == -1) {
+ localNameInt = addCode(localName, localName.toString());
+ }
+ return localNameInt;
+
+ }
+
+ public int addCode(Object code, String codeStr){
+ int count = codes.size();
+ codes.add(codeStr);
+ codeMap.put(code, Integer.valueOf(count));
+ return count;
+ }
+
+ public int getCode(Object code){
+ if(codeMap.containsKey(code)){
+ return codeMap.get(code);
+ }
+ return -1;
+ }
+ }
+
+ private static class DeSerializer implements NormalizedNodeDeSerializationContext {
+ private static Map<NormalizedNodeType, DeSerializationFunction>
+ deSerializationFunctions = new HashMap<>();
+
+ static {
+ deSerializationFunctions.put(CONTAINER_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode>
+ builder = Builders.containerBuilder();
+
+ builder
+ .withNodeIdentifier(deSerializer.toNodeIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildDataContainer(builder, node);
+
+ }
+
+ });
+
+ deSerializationFunctions.put(LEAF_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>>
+ builder = Builders.leafBuilder();
+
+ builder
+ .withNodeIdentifier(deSerializer.toNodeIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildNormalizedNode(builder, node);
+
+ }
+ });
+
+ deSerializationFunctions.put(MAP_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ CollectionNodeBuilder<MapEntryNode, MapNode>
+ builder = Builders.mapBuilder();
+
+ return deSerializer.buildCollectionNode(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(MAP_ENTRY_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+ builder = Builders.mapEntryBuilder();
+
+ builder.withNodeIdentifier(deSerializer.toNodeIdentifierWithPredicates(
+ node.getPathArgument()));
+
+ return deSerializer.buildDataContainer(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(AUGMENTATION_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ DataContainerNodeBuilder<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode>
+ builder = Builders.augmentationBuilder();
+
+ builder.withNodeIdentifier(
+ deSerializer.toAugmentationIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildDataContainer(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(LEAF_SET_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ ListNodeBuilder<Object, LeafSetEntryNode<Object>>
+ builder = Builders.leafSetBuilder();
+
+ return deSerializer.buildListNode(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(LEAF_SET_ENTRY_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>>
+ builder = Builders.leafSetEntryBuilder();
+
+ builder.withNodeIdentifier(deSerializer.toNodeWithValue(
+ node.getPathArgument()));
+
+ return deSerializer.buildNormalizedNode(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(CHOICE_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ChoiceNode>
+ builder =
+ Builders.choiceBuilder();
+
+ builder
+ .withNodeIdentifier(deSerializer.toNodeIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildDataContainer(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(ORDERED_LEAF_SET_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ ListNodeBuilder<Object, LeafSetEntryNode<Object>>
+ builder =
+ Builders.orderedLeafSetBuilder();
+
+ return deSerializer.buildListNode(builder, node);
+
+
+ }
+ });
+
+ deSerializationFunctions.put(ORDERED_MAP_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ CollectionNodeBuilder<MapEntryNode, OrderedMapNode>
+ builder =
+ Builders.orderedMapBuilder();
+
+ return deSerializer.buildCollectionNode(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(UNKEYED_LIST_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode>
+ builder =
+ Builders.unkeyedListBuilder();
+
+ return deSerializer.buildCollectionNode(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(UNKEYED_LIST_ENTRY_NODE_TYPE,
+ new DeSerializationFunction() {
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode>
+ builder =
+ Builders.unkeyedListEntryBuilder();
+
+ builder
+ .withNodeIdentifier(deSerializer.toNodeIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildDataContainer(builder, node);
+ }
+ });
+
+ deSerializationFunctions.put(ANY_XML_NODE_TYPE,
+ new DeSerializationFunction() {
+
+ @Override public NormalizedNode apply(
+ DeSerializer deSerializer,
+ NormalizedNodeMessages.Node node) {
+ NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Node<?>, AnyXmlNode>
+ builder =
+ Builders.anyXmlBuilder();
+
+ builder
+ .withNodeIdentifier(deSerializer.toNodeIdentifier(
+ node.getPathArgument()));
+
+ return deSerializer.buildNormalizedNode(builder, node);
+ }
+ });
+
+ }
+
+ private final NormalizedNodeMessages.Node node;
+
+ public DeSerializer(NormalizedNodeMessages.Node node){
+ this.node = node;
+ }
+
+ public NormalizedNode deSerialize(){
+ return deSerialize(node);
+ }
+
+ private NormalizedNode deSerialize(NormalizedNodeMessages.Node node){
+ Preconditions.checkNotNull(node, "node should not be null");
+ DeSerializationFunction deSerializationFunction =
+ Preconditions.checkNotNull(deSerializationFunctions.get(NormalizedNodeType.values()[node.getIntType()]), "Unknown type " + node);
+
+ return deSerializationFunction.apply(this, node);
+ }
+
+
+ private NormalizedNode buildCollectionNode(
+ CollectionNodeBuilder builder,
+ NormalizedNodeMessages.Node node) {
+
+ builder.withNodeIdentifier(toNodeIdentifier(node.getPathArgument()));
+
+ for(NormalizedNodeMessages.Node child : node.getChildList()){
+ builder.withChild(deSerialize(child));
+ }
+
+ return builder.build();
+ }
+
+
+ private NormalizedNode buildListNode(
+ ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder,
+ NormalizedNodeMessages.Node node) {
+ builder.withNodeIdentifier(toNodeIdentifier(node.getPathArgument()));
+
+ for(NormalizedNodeMessages.Node child : node.getChildList()){
+ builder.withChild((LeafSetEntryNode<Object>) deSerialize(child));
+ }
+
+ return builder.build();
+ }
+
+ private NormalizedNode buildDataContainer(DataContainerNodeBuilder builder, NormalizedNodeMessages.Node node){
+
+ for(NormalizedNodeMessages.Node child : node.getChildList()){
+ builder.withChild((DataContainerChild<?, ?>) deSerialize(child));
+ }
+
+ //TODO : Also handle attributes
+
+ return builder.build();
+ }
+
+ private NormalizedNode buildNormalizedNode(NormalizedNodeAttrBuilder builder, NormalizedNodeMessages.Node node){
+
+ builder.withValue(ValueSerializer.deSerialize(this, node));
+
+ //TODO : Also handle attributes
+
+ return builder.build();
+
+ }
+
+
+ private YangInstanceIdentifier.NodeIdentifierWithPredicates toNodeIdentifierWithPredicates(
+ NormalizedNodeMessages.PathArgument path) {
+ return (YangInstanceIdentifier.NodeIdentifierWithPredicates) PathArgumentSerializer.deSerialize(this, path);
+ }
+
+ private YangInstanceIdentifier.AugmentationIdentifier toAugmentationIdentifier(
+ NormalizedNodeMessages.PathArgument path) {
+ return (YangInstanceIdentifier.AugmentationIdentifier) PathArgumentSerializer.deSerialize(this, path);
+ }
+
+ private YangInstanceIdentifier.NodeWithValue toNodeWithValue(
+ NormalizedNodeMessages.PathArgument path) {
+ return (YangInstanceIdentifier.NodeWithValue) PathArgumentSerializer.deSerialize(
+ this, path);
+ }
+
+ private YangInstanceIdentifier.NodeIdentifier toNodeIdentifier(NormalizedNodeMessages.PathArgument path){
+ return (YangInstanceIdentifier.NodeIdentifier) PathArgumentSerializer.deSerialize(
+ this, path);
+ }
+
+ @Override public String getNamespace(int namespace) {
+ return node.getCode(namespace);
+ }
+
+ @Override public String getRevision(int revision) {
+ return node.getCode(revision);
+ }
+
+ @Override public String getLocalName(int localName) {
+ return node.getCode(localName);
+ }
+
+ public YangInstanceIdentifier.PathArgument deSerialize(
+ NormalizedNodeMessages.PathArgument pathArgument) {
+ return PathArgumentSerializer.deSerialize(this, pathArgument);
+ }
+
+ private static interface DeSerializationFunction {
+ NormalizedNode apply(DeSerializer deserializer, NormalizedNodeMessages.Node node);
+ }
+ }
+
+
+
+
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+
+public enum NormalizedNodeType {
+ CONTAINER_NODE_TYPE,
+ LEAF_NODE_TYPE,
+ MAP_NODE_TYPE,
+ MAP_ENTRY_NODE_TYPE,
+ AUGMENTATION_NODE_TYPE,
+ LEAF_SET_NODE_TYPE,
+ LEAF_SET_ENTRY_NODE_TYPE,
+ CHOICE_NODE_TYPE,
+ ORDERED_LEAF_SET_NODE_TYPE,
+ ORDERED_MAP_NODE_TYPE,
+ UNKEYED_LIST_NODE_TYPE,
+ UNKEYED_LIST_ENTRY_NODE_TYPE,
+ ANY_XML_NODE_TYPE;
+
+ public static NormalizedNodeType getSerializableNodeType(NormalizedNode node){
+ Preconditions.checkNotNull(node, "node should not be null");
+
+ if(node instanceof ContainerNode){
+ return CONTAINER_NODE_TYPE;
+ } else if(node instanceof LeafNode){
+ return LEAF_NODE_TYPE;
+ } else if(node instanceof MapNode){
+ return MAP_NODE_TYPE;
+ } else if(node instanceof MapEntryNode){
+ return MAP_ENTRY_NODE_TYPE;
+ } else if(node instanceof AugmentationNode){
+ return AUGMENTATION_NODE_TYPE;
+ } else if(node instanceof LeafSetNode){
+ return LEAF_SET_NODE_TYPE;
+ } else if(node instanceof LeafSetEntryNode){
+ return LEAF_SET_ENTRY_NODE_TYPE;
+ } else if(node instanceof ChoiceNode){
+ return CHOICE_NODE_TYPE;
+ } else if(node instanceof OrderedLeafSetNode){
+ return ORDERED_LEAF_SET_NODE_TYPE;
+ } else if(node instanceof OrderedMapNode){
+ return ORDERED_MAP_NODE_TYPE;
+ } else if(node instanceof UnkeyedListNode){
+ return UNKEYED_LIST_NODE_TYPE;
+ } else if(node instanceof UnkeyedListEntryNode){
+ return UNKEYED_LIST_ENTRY_NODE_TYPE;
+ } else if(node instanceof AnyXmlNode){
+ return ANY_XML_NODE_TYPE;
+ }
+ throw new IllegalArgumentException("Node type unknown : " + node.getClass().getSimpleName());
+ }
+
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFactory;
+import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.opendaylight.controller.cluster.datastore.node.utils.serialization.PathArgumentType.getSerializablePathArgumentType;
+
+public class PathArgumentSerializer {
+ private static final Map<Class, PathArgumentAttributesGetter> pathArgumentAttributesGetters = new HashMap<>();
+
+ public static NormalizedNodeMessages.PathArgument serialize(NormalizedNodeSerializationContext context, YangInstanceIdentifier.PathArgument pathArgument){
+ Preconditions.checkNotNull(context, "context should not be null");
+ Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+ QName nodeType = null;
+ if (!(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier)) {
+ nodeType = pathArgument.getNodeType();
+ }
+
+ NormalizedNodeMessages.PathArgument.Builder builder =
+ NormalizedNodeMessages.PathArgument.newBuilder();
+
+ NormalizedNodeMessages.PathArgument serializablePathArgument =
+ builder
+ .setIntType(getSerializablePathArgumentType(pathArgument))
+ .setNodeType(encodeQName(context, nodeType))
+ .addAllAttribute(getPathArgumentAttributes(context, pathArgument))
+ .build();
+
+ return serializablePathArgument;
+ }
+
+
+ public static YangInstanceIdentifier.PathArgument deSerialize(NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.PathArgument pathArgument){
+ Preconditions.checkNotNull(context, "context should not be null");
+ Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+ return parsePathArgument(context, pathArgument);
+ }
+
+
+ private static interface PathArgumentAttributesGetter {
+ Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument);
+ }
+
+ static {
+ pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeWithValue.class, new PathArgumentAttributesGetter() {
+ @Override
+ public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+ NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument) {
+ List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+ new ArrayList<>();
+
+ YangInstanceIdentifier.NodeWithValue identifier
+ = (YangInstanceIdentifier.NodeWithValue) pathArgument;
+
+ NormalizedNodeMessages.PathArgumentAttribute attribute =
+ buildAttribute(context, null, identifier.getValue());
+
+ attributes.add(attribute);
+
+ return attributes;
+
+ }
+ });
+
+ pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeIdentifierWithPredicates.class, new PathArgumentAttributesGetter() {
+ @Override
+ public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+ NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument) {
+
+ List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+ new ArrayList<>();
+
+ YangInstanceIdentifier.NodeIdentifierWithPredicates identifier
+ = (YangInstanceIdentifier.NodeIdentifierWithPredicates) pathArgument;
+
+ for (QName key : identifier.getKeyValues().keySet()) {
+ Object value = identifier.getKeyValues().get(key);
+ NormalizedNodeMessages.PathArgumentAttribute attribute =
+ buildAttribute(context, key, value);
+
+ attributes.add(attribute);
+
+ }
+
+ return attributes;
+
+ }
+ });
+
+ pathArgumentAttributesGetters.put(YangInstanceIdentifier.AugmentationIdentifier.class, new PathArgumentAttributesGetter() {
+ @Override
+ public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+ NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument) {
+
+ List<NormalizedNodeMessages.PathArgumentAttribute> attributes =
+ new ArrayList<>();
+
+ YangInstanceIdentifier.AugmentationIdentifier identifier
+ = (YangInstanceIdentifier.AugmentationIdentifier) pathArgument;
+
+ for (QName key : identifier.getPossibleChildNames()) {
+ Object value = key;
+ NormalizedNodeMessages.PathArgumentAttribute attribute =
+ buildAttribute(context, key, value);
+
+ attributes.add(attribute);
+
+ }
+
+ return attributes;
+
+ }
+ });
+
+
+ pathArgumentAttributesGetters.put(YangInstanceIdentifier.NodeIdentifier.class, new PathArgumentAttributesGetter() {
+ @Override
+ public Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> get(
+ NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument) {
+ return Collections.emptyList();
+ }
+ });
+ }
+
+ private static NormalizedNodeMessages.PathArgumentAttribute buildAttribute(NormalizedNodeSerializationContext context,QName name, Object value){
+ NormalizedNodeMessages.PathArgumentAttribute.Builder builder =
+ NormalizedNodeMessages.PathArgumentAttribute.newBuilder();
+
+ builder.setName(encodeQName(context, name));
+ ValueSerializer.serialize(builder, context, value);
+
+ return builder.build();
+
+ }
+
+ private static NormalizedNodeMessages.QName.Builder encodeQName(NormalizedNodeSerializationContext context, QName qName){
+ if(qName == null){
+ return NormalizedNodeMessages.QName.getDefaultInstance().toBuilder();
+ }
+ NormalizedNodeMessages.QName.Builder qNameBuilder =
+ NormalizedNodeMessages.QName.newBuilder();
+
+ qNameBuilder.setNamespace(context.addNamespace(qName.getNamespace()));
+
+ qNameBuilder.setRevision(context.addRevision(qName.getRevision()));
+
+ qNameBuilder.setLocalName(context.addLocalName(qName.getLocalName()));
+
+ return qNameBuilder;
+ }
+
+ private static Iterable<? extends NormalizedNodeMessages.PathArgumentAttribute> getPathArgumentAttributes(
+ NormalizedNodeSerializationContext context,
+ YangInstanceIdentifier.PathArgument pathArgument) {
+
+ return pathArgumentAttributesGetters.get(pathArgument.getClass()).get(context, pathArgument);
+
+ }
+
+
+ private static String qNameToString(NormalizedNodeDeSerializationContext context,
+ NormalizedNodeMessages.QName qName){
+ // If this serializer is used qName cannot be null (see encodeQName)
+ // adding null check only in case someone tried to deSerialize a protocol buffer node
+ // that was not serialized using the PathArgumentSerializer
+ Preconditions.checkNotNull(qName, "qName should not be null");
+ Preconditions.checkArgument(!"".equals(qName.getLocalName()),
+ "qName.localName cannot be empty qName = " + qName.toString());
+ Preconditions.checkArgument(qName.getNamespace() != -1, "qName.namespace should be valid");
+
+ StringBuilder sb = new StringBuilder();
+ String namespace = context.getNamespace(qName.getNamespace());
+ String revision = "";
+ String localName = context.getLocalName(qName.getLocalName());
+ if(qName.getRevision() != -1){
+ revision = context.getRevision(qName.getRevision());
+ sb.append("(").append(namespace).append("?revision=").append(
+ revision).append(")").append(
+ localName);
+ } else {
+ sb.append("(").append(namespace).append(")").append(
+ localName);
+ }
+
+ return sb.toString();
+
+ }
+
+ /**
+ * Parse a protocol buffer PathArgument and return an MD-SAL PathArgument
+ *
+ * @param pathArgument protocol buffer PathArgument
+ * @return MD-SAL PathArgument
+ */
+ private static YangInstanceIdentifier.PathArgument parsePathArgument(
+ NormalizedNodeDeSerializationContext context,
+ NormalizedNodeMessages.PathArgument pathArgument) {
+
+ Preconditions.checkArgument(pathArgument.getIntType() >= 0
+ && pathArgument.getIntType() < PathArgumentType.values().length,
+ "Illegal PathArgumentType " + pathArgument.getIntType());
+
+ switch(PathArgumentType.values()[pathArgument.getIntType()]){
+ case NODE_IDENTIFIER_WITH_VALUE : {
+
+ YangInstanceIdentifier.NodeWithValue nodeWithValue =
+ new YangInstanceIdentifier.NodeWithValue(
+ QNameFactory.create(qNameToString(context, pathArgument.getNodeType())),
+ parseAttribute(context, pathArgument.getAttribute(0)));
+
+ return nodeWithValue;
+ }
+
+ case NODE_IDENTIFIER_WITH_PREDICATES : {
+
+ YangInstanceIdentifier.NodeIdentifierWithPredicates
+ nodeIdentifierWithPredicates =
+ new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+ QNameFactory.create(qNameToString(context, pathArgument.getNodeType())),
+ toAttributesMap(context, pathArgument.getAttributeList()));
+
+ return nodeIdentifierWithPredicates;
+ }
+
+ case AUGMENTATION_IDENTIFIER: {
+
+ Set<QName> qNameSet = new HashSet<>();
+
+ for(NormalizedNodeMessages.PathArgumentAttribute attribute : pathArgument.getAttributeList()){
+ qNameSet.add(QNameFactory.create(qNameToString(context, attribute.getName())));
+ }
+
+ return new YangInstanceIdentifier.AugmentationIdentifier(qNameSet);
+
+ }
+ default: {
+ return NodeIdentifierFactory.getArgument(qNameToString(context,
+ pathArgument.getNodeType()));
+ }
+
+ }
+ }
+
+ private static Map<QName, Object> toAttributesMap(
+ NormalizedNodeDeSerializationContext context,
+ List<NormalizedNodeMessages.PathArgumentAttribute> attributesList) {
+
+ Map<QName, Object> map = new HashMap<>();
+
+ for(NormalizedNodeMessages.PathArgumentAttribute attribute : attributesList){
+ NormalizedNodeMessages.QName name = attribute.getName();
+ Object value = parseAttribute(context, attribute);
+
+ map.put(QNameFactory.create(qNameToString(context, name)), value);
+ }
+
+ return map;
+ }
+
+ private static Object parseAttribute(NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.PathArgumentAttribute attribute){
+ return ValueSerializer.deSerialize(context, attribute);
+ }
+
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+public enum PathArgumentType {
+ AUGMENTATION_IDENTIFIER,
+ NODE_IDENTIFIER,
+ NODE_IDENTIFIER_WITH_VALUE,
+ NODE_IDENTIFIER_WITH_PREDICATES;
+
+ public static int getSerializablePathArgumentType(YangInstanceIdentifier.PathArgument pathArgument){
+ Preconditions.checkNotNull(pathArgument, "pathArgument should not be null");
+
+ if(pathArgument instanceof YangInstanceIdentifier.AugmentationIdentifier){
+ return AUGMENTATION_IDENTIFIER.ordinal();
+ } else if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifier){
+ return NODE_IDENTIFIER.ordinal();
+ } else if(pathArgument instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates){
+ return NODE_IDENTIFIER_WITH_PREDICATES.ordinal();
+ } else if(pathArgument instanceof YangInstanceIdentifier.NodeWithValue){
+ return NODE_IDENTIFIER_WITH_VALUE.ordinal();
+ }
+ throw new IllegalArgumentException("Unknown type of PathArgument = " + pathArgument.toString());
+ }
+
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.cluster.datastore.node.utils.QNameFactory;
+import org.opendaylight.controller.cluster.datastore.util.InstanceIdentifierUtils;
+import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ValueSerializer {
+ public static void serialize(NormalizedNodeMessages.Node.Builder builder,
+ NormalizedNodeSerializationContext context, Object value){
+ builder.setIntValueType(ValueType.getSerializableType(value).ordinal());
+
+ if(value instanceof YangInstanceIdentifier) {
+ builder.setInstanceIdentifierValue(
+ InstanceIdentifierUtils.toSerializable((YangInstanceIdentifier) value));
+ } else if(value instanceof Set) {
+ Set set = (Set) value;
+ if(!set.isEmpty()){
+ for(Object o : set){
+ if(o instanceof String){
+ builder.addBitsValue(o.toString());
+ } else {
+ throw new IllegalArgumentException("Expected value type to be Bits but was : " +
+ value.toString());
+ }
+ }
+ }
+ } else {
+ builder.setValue(value.toString());
+ }
+ }
+
+ public static void serialize(NormalizedNodeMessages.PathArgumentAttribute.Builder builder,
+ NormalizedNodeSerializationContext context, Object value){
+
+ builder.setType(ValueType.getSerializableType(value).ordinal());
+ builder.setValue(value.toString());
+ }
+
+ public static Object deSerialize(
+ NormalizedNodeDeSerializationContext context, NormalizedNodeMessages.Node node) {
+ if(node.getIntValueType() == ValueType.YANG_IDENTIFIER_TYPE.ordinal()){
+ return InstanceIdentifierUtils.fromSerializable(
+ node.getInstanceIdentifierValue());
+ } else if(node.getIntValueType() == ValueType.BITS_TYPE.ordinal()){
+ return new HashSet(node.getBitsValueList());
+ }
+ return deSerializeBasicTypes(node.getIntValueType(), node.getValue());
+ }
+
+ public static Object deSerialize(
+ NormalizedNodeDeSerializationContext context,
+ NormalizedNodeMessages.PathArgumentAttribute attribute) {
+ return deSerializeBasicTypes(attribute.getType(), attribute.getValue());
+ }
+
+
+ private static Object deSerializeBasicTypes(int valueType, String value) {
+ Preconditions.checkArgument(valueType >= 0 && valueType < ValueType.values().length,
+ "Illegal value type " + valueType );
+
+ switch(ValueType.values()[valueType]){
+ case SHORT_TYPE: {
+ return Short.valueOf(value);
+ }
+ case BOOL_TYPE: {
+ return Boolean.valueOf(value);
+ }
+ case BYTE_TYPE: {
+ return Byte.valueOf(value);
+ }
+ case INT_TYPE : {
+ return Integer.valueOf(value);
+ }
+ case LONG_TYPE: {
+ return Long.valueOf(value);
+ }
+ case QNAME_TYPE: {
+ return QNameFactory.create(value);
+ }
+ case BIG_INTEGER_TYPE: {
+ return new BigInteger(value);
+ }
+ case BIG_DECIMAL_TYPE: {
+ return new BigDecimal(value);
+ }
+ default: {
+ return value;
+ }
+ }
+ }
+
+}
--- /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.cluster.datastore.node.utils.serialization;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public enum ValueType {
+ SHORT_TYPE,
+ BYTE_TYPE,
+ INT_TYPE,
+ LONG_TYPE,
+ BOOL_TYPE,
+ QNAME_TYPE,
+ BITS_TYPE,
+ YANG_IDENTIFIER_TYPE,
+ STRING_TYPE,
+ BIG_INTEGER_TYPE,
+ BIG_DECIMAL_TYPE;
+
+ private static Map<Class, ValueType> types = new HashMap<>();
+
+ static {
+ types.put(String.class, STRING_TYPE);
+ types.put(Byte.class, BYTE_TYPE);
+ types.put(Integer.class, INT_TYPE);
+ types.put(Long.class, LONG_TYPE);
+ types.put(Boolean.class, BOOL_TYPE);
+ types.put(QName.class, QNAME_TYPE);
+ types.put(Set.class, BITS_TYPE);
+ types.put(YangInstanceIdentifier.class, YANG_IDENTIFIER_TYPE);
+ types.put(Short.class,SHORT_TYPE);
+ types.put(BigInteger.class, BIG_INTEGER_TYPE);
+ types.put(BigDecimal.class, BIG_DECIMAL_TYPE);
+ }
+
+ public static final ValueType getSerializableType(Object node){
+ Preconditions.checkNotNull(node, "node should not be null");
+
+ if(types.containsKey(node.getClass())) {
+ return types.get(node.getClass());
+ } else if(node instanceof Set){
+ return BITS_TYPE;
+ }
+
+ throw new IllegalArgumentException("Unknown value type " + node.getClass().getSimpleName());
+ }
+}
import akka.actor.ActorPath;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
-import akka.dispatch.BoundedMailbox;
+import akka.dispatch.BoundedDequeBasedMailbox;
import akka.dispatch.MailboxType;
-import akka.dispatch.MessageQueue;
import akka.dispatch.ProducesMessageQueue;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.MetricRegistry;
import java.util.concurrent.TimeUnit;
-public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<BoundedMailbox.MessageQueue> {
+public class MeteredBoundedMailbox implements MailboxType, ProducesMessageQueue<MeteredBoundedMailbox.MeteredMessageQueue> {
private MeteredMessageQueue queue;
private Integer capacity;
private MetricsReporter reporter;
private final String QUEUE_SIZE = "queue-size";
+ private final String CAPACITY = "mailbox-capacity";
+ private final String TIMEOUT = "mailbox-push-timeout-time";
private final Long DEFAULT_TIMEOUT = 10L;
public MeteredBoundedMailbox(ActorSystem.Settings settings, Config config) {
Preconditions.checkArgument( config.hasPath("mailbox-capacity"), "Missing configuration [mailbox-capacity]" );
- this.capacity = config.getInt("mailbox-capacity");
+ this.capacity = config.getInt(CAPACITY);
Preconditions.checkArgument( this.capacity > 0, "mailbox-capacity must be > 0");
Long timeout = -1L;
- if ( config.hasPath("mailbox-push-timeout-time") ){
- timeout = config.getDuration("mailbox-push-timeout-time", TimeUnit.NANOSECONDS);
+ if ( config.hasPath(TIMEOUT) ){
+ timeout = config.getDuration(TIMEOUT, TimeUnit.NANOSECONDS);
} else {
timeout = DEFAULT_TIMEOUT;
}
@Override
- public MessageQueue create(final scala.Option<ActorRef> owner, scala.Option<ActorSystem> system) {
+ public MeteredMessageQueue create(final scala.Option<ActorRef> owner, scala.Option<ActorSystem> system) {
this.queue = new MeteredMessageQueue(this.capacity, this.pushTimeOut);
monitorQueueSize(owner, this.queue);
return this.queue;
return; //there's no actor to monitor
}
actorPath = owner.get().path();
- MetricRegistry registry = reporter.getMetricsRegistry();
+ String actorInstanceId = Integer.toString(owner.get().hashCode());
- String actorName = registry.name(actorPath.toString(), QUEUE_SIZE);
+ MetricRegistry registry = reporter.getMetricsRegistry();
+ String actorName = registry.name(actorPath.toString(), actorInstanceId, QUEUE_SIZE);
if (registry.getMetrics().containsKey(actorName))
return; //already registered
- reporter.getMetricsRegistry().register(actorName,
+ registry.register(actorName,
new Gauge<Integer>() {
@Override
public Integer getValue() {
}
- public static class MeteredMessageQueue extends BoundedMailbox.MessageQueue {
+ public static class MeteredMessageQueue extends BoundedDequeBasedMailbox.MessageQueue {
public MeteredMessageQueue(int capacity, FiniteDuration pushTimeOut) {
super(capacity, pushTimeOut);
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: KeyValueMessages.proto
-package org.opendaylight.controller.cluster.example.protobuff.messages;
+package org.opendaylight.controller.protobuff.messages.cluster.example;
public final class KeyValueMessages {
private KeyValueMessages() {}
public static void registerAllExtensions(
com.google.protobuf.ExtensionRegistry registry) {
- registry.add(org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages.key);
- registry.add(org.opendaylight.controller.cluster.example.protobuff.messages.KeyValueMessages.value);
+ registry.add(org.opendaylight.controller.protobuff.messages.cluster.example.KeyValueMessages.key);
+ registry.add(org.opendaylight.controller.protobuff.messages.cluster.example.KeyValueMessages.value);
}
public static final int KEY_FIELD_NUMBER = 2;
/**
*/
public static final
com.google.protobuf.GeneratedMessage.GeneratedExtension<
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
java.lang.String> key = com.google.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.String.class,
*/
public static final
com.google.protobuf.GeneratedMessage.GeneratedExtension<
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload,
java.lang.String> value = com.google.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
java.lang.String.class,
"e\022R.org.opendaylight.controller.cluster." +
"raft.AppendEntries.ReplicatedLogEntry.Pa" +
"yload\030\003 \001(\tBT\n>org.opendaylight.controll" +
- "er.cluster.example.protobuff.messagesB\020K" +
+ "er.protobuff.messages.cluster.exampleB\020K" +
"eyValueMessagesH\001"
};
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
com.google.protobuf.Descriptors.FileDescriptor
.internalBuildGeneratedFileFrom(descriptorData,
new com.google.protobuf.Descriptors.FileDescriptor[] {
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.getDescriptor(),
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.getDescriptor(),
}, assigner);
}
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: AppendEntriesMessages.proto
-package org.opendaylight.controller.cluster.raft.protobuff.messages;
+package org.opendaylight.controller.protobuff.messages.cluster.raft;
public final class AppendEntriesMessages {
private AppendEntriesMessages() {}
/**
* <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
*/
- java.util.List<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>
+ java.util.List<org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>
getLogEntriesList();
/**
* <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
*/
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index);
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry getLogEntries(int index);
/**
* <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
*/
/**
* <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
*/
- java.util.List<? extends org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder>
+ java.util.List<? extends org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder>
getLogEntriesOrBuilderList();
/**
* <code>repeated .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry logEntries = 5;</code>
*/
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntryOrBuilder getLogEntriesOrBuilder(
int index);
// optional int64 leaderCommit = 6;
}
case 42: {
if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) {
- logEntries_ = new java.util.ArrayList<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>();
+ logEntries_ = new java.util.ArrayList<org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry>();
mutable_bitField0_ |= 0x00000010;
}
- logEntries_.add(input.readMessage(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PARSER, extensionRegistry));
+ logEntries_.add(input.readMessage(org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PARSER, extensionRegistry));
break;
}
case 48: {
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_fieldAccessorTable
.ensureFieldAccessorsInitialized(
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.Builder.class);
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.Builder.class);
}
public static com.google.protobuf.Parser<AppendEntries> PARSER =
/**
* <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
*/
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getData();
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload getData();
/**
* <code>optional .org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry.Payload data = 3;</code>
*/
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder();
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.PayloadOrBuilder getDataOrBuilder();
}
/**
* Protobuf type {@code org.opendaylight.controller.cluster.raft.AppendEntries.ReplicatedLogEntry}
break;
}
case 26: {
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder subBuilder = null;
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder subBuilder = null;
if (((bitField0_ & 0x00000004) == 0x00000004)) {
subBuilder = data_.toBuilder();
}
- data_ = input.readMessage(org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.PARSER, extensionRegistry);
+ data_ = input.readMessage(org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(data_);
data_ = subBuilder.buildPartial();
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_fieldAccessorTable
.ensureFieldAccessorsInitialized(
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder.class);
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Builder.class);
}
public static com.google.protobuf.Parser<ReplicatedLogEntry> PARSER =
com.google.protobuf.GeneratedMessage.ExtendableMessage<
Payload> implements PayloadOrBuilder {
// Use Payload.newBuilder() to construct.
- private Payload(com.google.protobuf.GeneratedMessage.ExtendableBuilder<org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, ?> builder) {
+ private Payload(com.google.protobuf.GeneratedMessage.ExtendableBuilder<org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload, ?> builder) {
super(builder);
this.unknownFields = builder.getUnknownFields();
}
}
public static final com.google.protobuf.Descriptors.Descriptor
getDescriptor() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_descriptor;
}
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
internalGetFieldAccessorTable() {
- return org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable
+ return org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.internal_static_org_opendaylight_controller_cluster_raft_AppendEntries_ReplicatedLogEntry_Payload_fieldAccessorTable
.ensureFieldAccessorsInitialized(
- org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.class, org.opendaylight.controller.cluster.raft.protobuff.messages.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder.class);
+ org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.class, org.opendaylight.controller.protobuff.messages.cluster.raft.AppendEntriesMessages.AppendEntries.ReplicatedLogEntry.Payload.Builder.class);
}
public