When more number of flow/groups being pushed via OF bundle down to openflow switch. OVS rejects some of the bundle add messages with error OFPBFC_MSG_BAD_XID (inconsistent or duplicate transaction ID).
On further analysis, it was found that the OVS (in compliance with
openflow protocol) rejects the add bundle messages if the transaction id
in the OFP header containing the bundle add msg is different to that of
the flow/group mod present in the bundle body.
This may be due to synchronization issues in the creation of the bundle
inner msg which could have resulted in the incorrect transaction Id
being set in the bundle msg. Changes have been made to avoid the
synchronization issue now which could fix this bug.
Change-Id: Ia575eee9616607402f625e09588b84758b1e4fe2
Signed-off-by: gobinath <gobinath@ericsson.com>
+++ /dev/null
-/*
- * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.openflowplugin.extension.api;
-
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
-
-/**
- * Interface for bundle data injection.
- */
-public interface BundleMessageDataInjector {
- /**
- * Set xid.
- *
- * @param xid request id
- */
- void setXid(long xid);
-
- /**
- * Set node id.
- *
- * @param node node id
- */
- void setNode(NodeRef node);
-}
* @param <F> input message model - MD-SAL model
* @param <T> output message model - OFJava-API
*/
-public interface ConverterMessageToOFJava<F extends ExperimenterMessageOfChoice, T extends DataContainer> {
+public interface ConverterMessageToOFJava<F extends ExperimenterMessageOfChoice, T extends DataContainer,
+ D extends ConvertorData> {
/**
* Converts a message to MD-SAL model.
*
* @param experimenterMessageCase where is vendor's augmentation
+ * @param data which contains the Xid and datapathId
* @return message converted to OFJava-API
*/
- T convert(F experimenterMessageCase) throws ConversionException;
+ T convert(F experimenterMessageCase, D data) throws ConversionException;
/**
* Returns the corresponding experimenter id (vendor id).
--- /dev/null
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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.openflowplugin.extension.api;
+
+/**
+ * The base class for all convertor data.
+ */
+public abstract class ConvertorData {
+ private short version;
+ /**
+ *Instantiates a new Convertor data.
+ * @param version the version
+ */
+
+ public ConvertorData(final short version) {
+ this.version = version;
+ }
+
+ /**
+ * Gets Openflow version.
+ *
+ * @return the version
+ */
+ public short getVersion() {
+ return version;
+ }
+}
* @param converter TO OFJava (suitable for both: symmetric and multipart)
* @return closeable registration
*/
- <I extends ExperimenterMessageOfChoice, O extends DataContainer> ObjectRegistration<ConverterMessageToOFJava<I, O>>
- registerMessageConvertor(TypeVersionKey<I> key, ConverterMessageToOFJava<I, O> converter);
+ <I extends ExperimenterMessageOfChoice, O extends DataContainer, D extends ConvertorData>
+ ObjectRegistration<ConverterMessageToOFJava<I, O, D>>
+ registerMessageConvertor(TypeVersionKey<I> key, ConverterMessageToOFJava<I, O, D> converter);
/**
* Registers a message converter.
--- /dev/null
+/*
+ * Copyright (c) 2018 Ericsson India Global Services Pvt Ltd. 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.openflowplugin.extension.api;
+
+import java.math.BigInteger;
+
+public class ExtensionConvertorData extends ConvertorData {
+ private Long xid;
+
+ private BigInteger datapathId;
+
+
+ /**
+ * Instantiates a new ExtensionConvertor data.
+ *
+ * @param version the version
+ */
+ public ExtensionConvertorData(short version) {
+ super(version);
+ }
+
+ /**
+ * Gets xid.
+ *
+ * @return the xid
+ */
+ public Long getXid() {
+ return xid;
+ }
+
+ /**
+ * Sets xid.
+ *
+ * @param xid the xid
+ */
+ public void setXid(Long xid) {
+ this.xid = xid;
+ }
+
+ /**
+ * Gets datapath id.
+ *
+ * @return the datapath id
+ */
+ public BigInteger getDatapathId() {
+ return datapathId;
+ }
+
+ /**
+ * Sets datapath id.
+ *
+ * @param datapathId the datapath id
+ */
+ public void setDatapathId(BigInteger datapathId) {
+ this.datapathId = datapathId;
+ }
+}
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
* @param key the type version key
* @return found converter
*/
- <F extends ExperimenterMessageOfChoice, T extends DataContainer> ConverterMessageToOFJava<F, T> getMessageConverter(
- TypeVersionKey<F> key);
+ <F extends ExperimenterMessageOfChoice, T extends DataContainer,
+ D extends ConvertorData> ConverterMessageToOFJava<F, T, D> getMessageConverter(TypeVersionKey<F> key);
/**
* Lookup converter for experimenter message.
package org.opendaylight.openflowplugin.extension.onf.converter;
-import java.math.BigInteger;
import java.util.List;
import java.util.Optional;
-import org.opendaylight.openflowplugin.api.OFConstants;
-import org.opendaylight.openflowplugin.extension.api.BundleMessageDataInjector;
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.openflowplugin.extension.onf.OnfConstants;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.XidConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder;
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.group.update.UpdatedGroupBuilder;
-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.openflow.common.types.rev130731.ExperimenterId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnf;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.BundleAddMessageOnfBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.rev170124.experimenter.input.experimenter.data.of.choice.bundle.add.message.onf.OnfAddMessageGroupingDataBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Converter for BundleAddMessage messages (ONF approved extension #230).
*/
public class BundleAddMessageConverter implements
- ConverterMessageToOFJava<BundleAddMessageSal, BundleAddMessageOnf>,
- ConvertorMessageFromOFJava<BundleAddMessageOnf, MessagePath>,
- BundleMessageDataInjector {
+ ConverterMessageToOFJava<BundleAddMessageSal, BundleAddMessageOnf, ExtensionConvertorData>,
+ ConvertorMessageFromOFJava<BundleAddMessageOnf, MessagePath> {
+ private static final Logger LOG = LoggerFactory.getLogger(BundleAddMessageConverter.class);
private static final ConvertorExecutor CONVERTER_EXECUTOR = ConvertorManagerFactory.createDefaultManager();
- private long xid;
- private NodeRef node;
@Override
- public BundleAddMessageOnf convert(BundleAddMessageSal experimenterMessageCase) throws ConversionException {
+ public BundleAddMessageOnf convert(BundleAddMessageSal experimenterMessageCase,
+ ExtensionConvertorData extensionData) throws ConversionException {
final OnfAddMessageGroupingDataBuilder dataBuilder = new OnfAddMessageGroupingDataBuilder();
dataBuilder.setBundleId(experimenterMessageCase.getSalAddMessageData().getBundleId());
dataBuilder.setFlags(experimenterMessageCase.getSalAddMessageData().getFlags());
dataBuilder.setBundleProperty(experimenterMessageCase.getSalAddMessageData().getBundleProperty());
final BundleInnerMessage innerMessage = experimenterMessageCase.getSalAddMessageData().getBundleInnerMessage();
- final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_3);
- data.setDatapathId(digDatapathId(node));
-
+ final XidConvertorData data = new XidConvertorData(extensionData.getVersion());
+ data.setDatapathId(extensionData.getDatapathId());
+ data.setXid(extensionData.getXid());
+ LOG.trace("Flow or group pushed to the node: {} with transaction id : {} is {}",
+ data.getDatapathId(), data.getXid(),
+ experimenterMessageCase.getSalAddMessageData().getBundleInnerMessage());
if (innerMessage.getImplementedInterface().equals(BundleAddFlowCase.class)
|| innerMessage.getImplementedInterface().equals(BundleUpdateFlowCase.class)
|| innerMessage.getImplementedInterface().equals(BundleRemoveFlowCase.class)) {
}
private BundleFlowModCase convertBundleFlowCase(final BundleInnerMessage messageCase,
- final VersionDatapathIdConvertorData data) throws ConversionException {
+ final XidConvertorData data) throws ConversionException {
Optional<List<FlowModInputBuilder>> flowModInputs = Optional.empty();
final Class clazz = messageCase.getImplementedInterface();
if (clazz.equals(BundleAddFlowCase.class)) {
flowModInputs
.get()
.get(0)
- .setXid(xid)
+ .setXid(data.getXid())
.build())
.build())
.build();
}
private BundleGroupModCase convertBundleGroupCase(final BundleInnerMessage messageCase,
- final VersionDatapathIdConvertorData data) throws ConversionException {
+ final XidConvertorData data) throws ConversionException {
Optional<GroupModInputBuilder> groupModInput = Optional.empty();
final Class clazz = messageCase.getImplementedInterface();
if (clazz.equals(BundleAddGroupCase.class)) {
return new BundleGroupModCaseBuilder()
.setGroupModCaseData(
new GroupModCaseDataBuilder(groupModInput.get()
- .setXid(xid)
+ .setXid(data.getXid())
.build())
.build()
)
}
private BundlePortModCase convertBundlePortCase(final BundleInnerMessage messageCase,
- final VersionDatapathIdConvertorData data) throws ConversionException {
+ final XidConvertorData data) throws ConversionException {
Optional<PortModInput> portModInput = Optional.empty();
final Class<?> clazz = messageCase.getImplementedInterface();
if (clazz.equals(BundleUpdatePortCase.class)) {
return new BundlePortModCaseBuilder()
.setPortModCaseData(
new PortModCaseDataBuilder(portModInput.get())
- .setXid(xid)
+ .setXid(data.getXid())
.build()
)
.build();
}
}
- private static BigInteger digDatapathId(final NodeRef ref) {
- return InventoryDataServiceUtil.dataPathIdFromNodeId(ref.getValue().firstKeyOf(Node.class).getId());
- }
-
@Override
public ExperimenterId getExperimenterId() {
return new ExperimenterId(OnfConstants.ONF_EXPERIMENTER_ID);
public long getType() {
return OnfConstants.ONF_ET_BUNDLE_ADD_MESSAGE;
}
-
- @Override
- public void setXid(long xid) {
- this.xid = xid;
- }
-
- @Override
- public void setNode(NodeRef node) {
- this.node = node;
- }
}
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
+import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.openflowplugin.extension.api.path.MessagePath;
import org.opendaylight.openflowplugin.extension.onf.OnfConstants;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
* Converter for BundleControl messages (ONF approved extension #230).
*/
public class BundleControlConverter implements
- ConverterMessageToOFJava<BundleControlSal, BundleControlOnf>,
+ ConverterMessageToOFJava<BundleControlSal, BundleControlOnf, ExtensionConvertorData>,
ConvertorMessageFromOFJava<BundleControlOnf, MessagePath> {
@Override
- public BundleControlOnf
- convert(final BundleControlSal experimenterMessageCase) {
+ public BundleControlOnf convert(final BundleControlSal experimenterMessageCase, final ExtensionConvertorData data)
+ throws ConversionException {
return new BundleControlOnfBuilder().setOnfControlGroupingData(
new OnfControlGroupingDataBuilder(experimenterMessageCase.getSalControlData()).build()).build();
}
package org.opendaylight.openflowplugin.extension.onf.converter;
+import static org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil.extractDatapathId;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
+import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
import org.opendaylight.openflowplugin.extension.onf.BundleTestUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.port.rev130925.PortConfig;
@Before
public void setUp() throws Exception {
- converter.setNode(NODE_REF);
}
@Test
private void testConvert(final BundleInnerMessage message, Class clazz, final boolean withProperty)
throws Exception {
final BundleAddMessageSal original = createMessage(withProperty, message);
- final BundleAddMessageOnf converted = converter.convert(original);
+ final ExtensionConvertorData data = new ExtensionConvertorData(OFConstants.OFP_VERSION_1_3);
+ data.setDatapathId(extractDatapathId(NODE_REF));
+ final BundleAddMessageOnf converted = converter.convert(original, data);
Assert.assertEquals("Wrong BundleId", new BundleId(original.getSalAddMessageData().getBundleId().getValue()),
converted.getOnfAddMessageGroupingData().getBundleId());
Assert.assertEquals("Wrong flags",
}
@Test
- public void testConvertDownWithProperty() {
+ public void testConvertDownWithProperty() throws Exception {
testConvertDown(true);
}
@Test
- public void testConvertDownWithoutProperty() {
+ public void testConvertDownWithoutProperty() throws Exception {
testConvertDown(false);
}
testConvertUp(true);
}
- private void testConvertDown(final boolean withProperty) {
+ private void testConvertDown(final boolean withProperty) throws Exception {
final BundleControlSal original = createOFPMessage(withProperty);
- final BundleControlOnf converted = converter.convert(original);
+ final BundleControlOnf converted = converter.convert(original, null);
testConvert(original, converted, withProperty);
}
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory;
import org.opendaylight.openflowplugin.api.OFConstants;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil;
} catch (ClassCastException | IllegalStateException ex) {
Optional
.ofNullable(OFSessionUtil.getExtensionConvertorProvider().<ExperimenterMessageOfChoice,
- ExperimenterDataOfChoice>getMessageConverter(new TypeVersionKey<>(
+ ExperimenterDataOfChoice, ConvertorData>getMessageConverter(new TypeVersionKey<>(
(Class<ExperimenterMessageOfChoice>) multipartRequestExperimenter
.getExperimenterMessageOfChoice().getImplementedInterface(),
OFConstants.OFP_VERSION_1_3)))
try {
serializer.serialize(converter.convert(multipartRequestExperimenter
- .getExperimenterMessageOfChoice()), byteBuf);
+ .getExperimenterMessageOfChoice(), null), byteBuf);
} catch (ConversionException e) {
throw new IllegalStateException(e);
}
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
input.getExperimenterMessageOfChoice().getImplementedInterface(),
getVersion());
- final ConverterMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice> messageConverter =
- getExtensionConverterProvider().getMessageConverter(key);
+ final ConverterMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice,
+ ConvertorData> messageConverter = getExtensionConverterProvider().getMessageConverter(key);
if (Objects.isNull(messageConverter)) {
throw new ServiceException(new ConverterNotFoundException(key.toString()));
.setExperimenter(messageConverter.getExperimenterId())
.setExpType(messageConverter.getType())
.setExperimenterDataOfChoice(messageConverter
- .convert(input.getExperimenterMessageOfChoice()))
+ .convert(input.getExperimenterMessageOfChoice(), null))
.build())
.build())
.build();
import org.opendaylight.openflowplugin.impl.services.util.ServiceException;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorExecutor;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.XidConvertorData;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketProcessingService;
@Override
protected OfHeader buildRequest(final Xid xid, final TransmitPacketInput input) throws ServiceException {
- final PacketOutConvertorData data = new PacketOutConvertorData(getVersion());
+ final XidConvertorData data = new XidConvertorData(getVersion());
data.setDatapathId(getDatapathId());
data.setXid(xid.getValue());
*/
package org.opendaylight.openflowplugin.impl.services.sal;
+import static org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil.extractDatapathId;
+
import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.extension.api.BundleMessageDataInjector;
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.extension.api.exception.ConversionException;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SalExperimenterMessageService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.experimenter.message.service.rev151020.SendExperimenterOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.experimenter.types.rev151020.experimenter.core.message.ExperimenterMessageOfChoice;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.onf.bundle.service.rev170124.send.experimenter.input.experimenter.message.of.choice.BundleAddMessageSal;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
public class SalExperimenterMessageServiceImpl extends AbstractSimpleService<SendExperimenterInput,
- SendExperimenterOutput>
- implements SalExperimenterMessageService {
+ SendExperimenterOutput> implements SalExperimenterMessageService {
- private static final Logger LOG = LoggerFactory.getLogger(SalExperimenterMessageServiceImpl.class);
private final ExtensionConverterProvider extensionConverterProvider;
public SalExperimenterMessageServiceImpl(final RequestContextStack requestContextStack,
protected OfHeader buildRequest(Xid xid, SendExperimenterInput input) throws ServiceException {
final TypeVersionKey key =
new TypeVersionKey(input.getExperimenterMessageOfChoice().getImplementedInterface(), getVersion());
- final ConverterMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice> messageConverter =
- extensionConverterProvider.getMessageConverter(key);
+ final ConverterMessageToOFJava<ExperimenterMessageOfChoice, ExperimenterDataOfChoice,
+ ExtensionConvertorData> messageConverter = extensionConverterProvider.getMessageConverter(key);
if (messageConverter == null) {
throw new ServiceException(new ConverterNotFoundException(key.toString()));
}
-
final ExperimenterInputBuilder experimenterInputBld;
-
- if (messageConverter instanceof BundleMessageDataInjector) {
- ((BundleMessageDataInjector) messageConverter).setNode(input.getNode());
- ((BundleMessageDataInjector) messageConverter).setXid(xid.getValue());
- LOG.trace("Flow or group pushed to the node: {} with transaction id : {} is {}",
- ((BundleAddMessageSal) input.getExperimenterMessageOfChoice())
- .getSalAddMessageData().getBundleInnerMessage(),
- input.getNode().getValue().firstKeyOf(Node.class).getId(),
- xid);
- }
-
try {
+ final ExtensionConvertorData data = new ExtensionConvertorData(OFConstants.OFP_VERSION_1_3);
+ data.setXid(xid.getValue());
+ data.setDatapathId(extractDatapathId(input.getNode()));
experimenterInputBld = new ExperimenterInputBuilder()
.setExperimenter(messageConverter.getExperimenterId())
.setExpType(messageConverter.getType())
- .setExperimenterDataOfChoice(messageConverter.convert(input.getExperimenterMessageOfChoice()))
+ .setExperimenterDataOfChoice(messageConverter.convert(input.getExperimenterMessageOfChoice(), data))
.setVersion(getVersion())
.setXid(xid.getValue());
} catch (ConversionException e) {
import org.opendaylight.openflowplugin.api.openflow.device.handlers.MultiMsgCollector;
import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.impl.device.DeviceContextImpl;
protected static final Xid DUMMY_XID = new Xid(DUMMY_XID_VALUE);
protected static final long DUMMY_EXPERIMENTER_ID = 42L;
- protected static final String DUMMY_NODE_ID = "dummyNodeID";
+ protected static final String DUMMY_NODE_ID = "444";
protected static final KeyedInstanceIdentifier<Node, NodeKey> DUMMY_NODE_II = InstanceIdentifier
.create(Nodes.class)
.child(Node.class, new NodeKey(new NodeId(DUMMY_NODE_ID)));
@Mock
protected ExtensionConverterProvider mockedExtensionConverterProvider;
@Mock
- protected ConverterMessageToOFJava<ExperimenterMessageOfChoice, DataContainer> mockedExtensionConverter;
+ protected ConverterMessageToOFJava<ExperimenterMessageOfChoice, DataContainer,
+ ConvertorData> mockedExtensionConverter;
@Before
@SuppressWarnings("unchecked")
import org.mockito.Mockito;
import org.opendaylight.openflowplugin.api.openflow.device.Xid;
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ExtensionConvertorData;
import org.opendaylight.openflowplugin.extension.api.TypeVersionKey;
import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterProvider;
import org.opendaylight.openflowplugin.impl.services.ServiceMocking;
@Test
public void testBuildRequest() throws Exception {
SendExperimenterInput sendExperimenterInput = buildSendExperimenterInput();
-
final OfHeader request =
salExperimenterMessageService.buildRequest(new Xid(DUMMY_XID_VALUE), sendExperimenterInput);
assertEquals(DUMMY_XID_VALUE, request.getXid());
final ExperimenterInput input = (ExperimenterInput) request;
assertEquals(43L, input.getExperimenter().getValue().longValue());
assertEquals(44L, input.getExpType().longValue());
-
- Mockito.verify(extensionConverter).convert(sendExperimenterInput.getExperimenterMessageOfChoice());
+ Mockito.verify(extensionConverter).convert(Matchers.eq(sendExperimenterInput.getExperimenterMessageOfChoice()),
+ Matchers.any(ExtensionConvertorData.class));
}
private SendExperimenterInput buildSendExperimenterInput() {
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
? extends DataContainer>> registryActionToOFJAva;
private final Map<MessageTypeKey<?>, ConvertorActionFromOFJava<?, ?>> registryActionFromOFJAva;
private final Map<TypeVersionKey<?>, ConverterMessageToOFJava<? extends ExperimenterMessageOfChoice,
- ? extends DataContainer>> registryMessageToOFJAva;
+ ? extends DataContainer, ? extends ConvertorData>> registryMessageToOFJAva;
private final Map<MessageTypeKey<?>, ConvertorMessageFromOFJava<? extends ExperimenterDataOfChoice, MessagePath>>
registryMessageFromOFJAva;
* @param extConvertor extension convertor
* @return registration closure
*/
- private <T extends DataContainer, K extends ExperimenterMessageOfChoice> RegistrationCloserMessageToOFJava<T, K>
- hireMessageJanitor(final TypeVersionKey<K> key, final ConverterMessageToOFJava<K, T> extConvertor) {
- RegistrationCloserMessageToOFJava<T, K> janitor = new RegistrationCloserMessageToOFJava<>();
+ private <T extends DataContainer, K extends ExperimenterMessageOfChoice,
+ D extends ConvertorData> RegistrationCloserMessageToOFJava<T, K,
+ D> hireMessageJanitor(final TypeVersionKey<K> key, final ConverterMessageToOFJava<K, T, D> extConvertor) {
+ RegistrationCloserMessageToOFJava<T, K, D> janitor = new RegistrationCloserMessageToOFJava<>();
janitor.setConverter(extConvertor);
janitor.setKey(key);
janitor.setRegistrator(this);
* @param key message key
* @param converter extension convertor
*/
- public void unregister(final TypeVersionKey<?> key, final ConverterMessageToOFJava<?, ?> converter) {
- ConverterMessageToOFJava<?, ?> registeredConverter = registryMessageToOFJAva.get(key);
+ public void unregister(final TypeVersionKey<?> key, final ConverterMessageToOFJava<?, ?, ?> converter) {
+ ConverterMessageToOFJava<?, ?, ?> registeredConverter = registryMessageToOFJAva.get(key);
if (registeredConverter != null && registeredConverter == converter) {
registryMessageToOFJAva.remove(key);
}
}
@Override
- public <I extends ExperimenterMessageOfChoice, O extends DataContainer>
- ObjectRegistration<ConverterMessageToOFJava<I, O>> registerMessageConvertor(
- TypeVersionKey<I> key, ConverterMessageToOFJava<I, O> convertor) {
+ public <I extends ExperimenterMessageOfChoice, O extends DataContainer, D extends ConvertorData>
+ ObjectRegistration<ConverterMessageToOFJava<I, O, D>> registerMessageConvertor(
+ TypeVersionKey<I> key, ConverterMessageToOFJava<I, O, D> convertor) {
registryMessageToOFJAva.put(key, convertor);
return hireMessageJanitor(key, convertor);
}
}
@Override
- public <F extends ExperimenterMessageOfChoice, T extends DataContainer> ConverterMessageToOFJava<F, T>
- getMessageConverter(TypeVersionKey<F> key) {
- return (ConverterMessageToOFJava<F, T>) registryMessageToOFJAva.get(key);
+ public <F extends ExperimenterMessageOfChoice, T extends DataContainer,
+ D extends ConvertorData> ConverterMessageToOFJava<F, T, D> getMessageConverter(TypeVersionKey<F> key) {
+ return (ConverterMessageToOFJava<F, T, D>) registryMessageToOFJAva.get(key);
}
@Override
import org.opendaylight.openflowplugin.extension.api.ConverterMessageToOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorData;
import org.opendaylight.openflowplugin.extension.api.ConvertorFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorMessageFromOFJava;
import org.opendaylight.openflowplugin.extension.api.ConvertorToOFJava;
* @param <T> target type of wrapped convertor
*/
public static class RegistrationCloserMessageToOFJava<T extends DataContainer,
- K extends ExperimenterMessageOfChoice>
- extends RegistrationCloser<TypeVersionKey<K>, ConverterMessageToOFJava<K, T>> {
+ K extends ExperimenterMessageOfChoice, D extends ConvertorData>
+ extends RegistrationCloser<TypeVersionKey<K>, ConverterMessageToOFJava<K, T, D>> {
@Override
public void close() {
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionConvertorData;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.XidConvertorData;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey;
* Example usage:
* <pre>
* {@code
- * PacketOutConvertorData data = new PacketOutConvertorData(version);
+ * XidConvertorData data = new XidConvertorData(version);
* data.setDatapathId(datapathId);
* data.setXid(xid);
* Optional<PacketOutInput> ofPacketInput = convertorManager.convert(salPacket, data);
* }
* </pre>
*/
-public class PacketOutConvertor extends Convertor<TransmitPacketInput, PacketOutInput, PacketOutConvertorData> {
+public class PacketOutConvertor extends Convertor<TransmitPacketInput, PacketOutInput, XidConvertorData> {
private static final Logger LOG = LoggerFactory.getLogger(PacketOutConvertor.class);
private static final Set<Class<?>> TYPES = Collections.singleton(TransmitPacketInput.class);
}
@Override
- public PacketOutInput convert(TransmitPacketInput source, PacketOutConvertorData data) {
+ public PacketOutInput convert(TransmitPacketInput source, XidConvertorData data) {
LOG.trace("toPacketOutInput for datapathId:{}, xid:{}", data.getDatapathId(), data.getXid());
// Build Port ID from TransmitPacketInput.Ingress
PortNumber inPortNr;
package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data;
/**
- * Convertor data used in {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor}
- * containing Openflow version and XID.
+ * Convertor data used in containing Openflow version and XID.
*/
-public class PacketOutConvertorData extends VersionDatapathIdConvertorData {
+public class XidConvertorData extends VersionDatapathIdConvertorData {
private Long xid;
/**
- * Instantiates a new Packet out convertor data.
+ * Instantiates a new Xid convertor data.
*
* @param version the version
*/
- public PacketOutConvertorData(short version) {
+ public XidConvertorData(short version) {
super(version);
}
public static String bigIntegerToPaddedHex(final BigInteger dataPathId) {
return StringUtils.leftPad(dataPathId.toString(16), 16, "0");
}
+
+ public static BigInteger extractDatapathId(final NodeRef ref) {
+ return InventoryDataServiceUtil.dataPathIdFromNodeId(ref.getValue().firstKeyOf(Node.class).getId());
+ }
}
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.action.data.ActionConvertorData;
-import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.PacketOutConvertorData;
+import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.XidConvertorData;
import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder;
}
/**
- * Test for {@link PacketOutConvertor} with null parameters.
+ * Test for {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.PacketOutConvertor}
+ * with null parameters.
*/
@Test
public void toPacketOutInputAllParmNullTest() {
Short version = (short) 0x04;
Long xid = null;
- PacketOutConvertorData data = new PacketOutConvertorData(version);
+ XidConvertorData data = new XidConvertorData(version);
PacketOutInput message = convert(transmitPacketInput, data);
//FIXME : this has to be fixed along with actions changed in openflowjava
}
/**
- * Test for PacketOutConvertor.
+ * Test for XidConvertorData.
*/
@Test
public void toPacketOutInputAllParmTest() {
BigInteger datapathId = new BigInteger(1, datapathIdByte);
Long xid = 0xfffffL;
- PacketOutConvertorData data = new PacketOutConvertorData(version);
+ XidConvertorData data = new XidConvertorData(version);
data.setXid(xid);
data.setDatapathId(datapathId);
PacketOutInput message = convert(transmitPacketInput, data);
return new NodeRef(path);
}
- private PacketOutInput convert(TransmitPacketInput transmitPacketInput, PacketOutConvertorData data) {
+ private PacketOutInput convert(TransmitPacketInput transmitPacketInput, XidConvertorData data) {
Optional<PacketOutInput> messageOptional = convertorManager.convert(transmitPacketInput, data);
return messageOptional.orElse(PacketOutConvertor.defaultResult(data.getVersion()));
}