diff --git a/.gitignore b/.gitignore index 49e9ad86..87966d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,11 @@ -target/ -.classpath -.project -.settings/ -.externalToolBuilders/ -maven-eclipse.xml -.checkstyle -.idea -*.iws -*.iml +target/ +target-ide/ +.classpath +.project +.settings/ +.externalToolBuilders/ +maven-eclipse.xml +.checkstyle +.idea +*.iws +*.iml diff --git a/artifacts/pom.xml b/artifacts/pom.xml index a54a33e0..54204e90 100644 --- a/artifacts/pom.xml +++ b/artifacts/pom.xml @@ -14,14 +14,17 @@ org.opendaylight.odlparent odlparent-lite - 1.8.0-SNAPSHOT + 2.0.0 org.opendaylight.openflowjava openflowjava-artifacts - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT pom + + ODL :: openflowjava :: ${project.artifactId} @@ -94,4 +97,3 @@ - diff --git a/features/features-openflowjava/pom.xml b/features/features-openflowjava/pom.xml new file mode 100644 index 00000000..036501c4 --- /dev/null +++ b/features/features-openflowjava/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + org.opendaylight.odlparent + feature-repo-parent + 2.0.0 + + + + org.opendaylight.openflowjava + features-openflowjava + 0.10.0-SNAPSHOT + feature + + ODL :: openflowjava :: ${project.artifactId} + + + + ${project.groupId} + odl-openflowjava-all + ${project.version} + xml + features + + + ${project.groupId} + odl-openflowjava-protocol + ${project.version} + xml + features + + + + diff --git a/features/odl-openflowjava-all/pom.xml b/features/odl-openflowjava-all/pom.xml new file mode 100644 index 00000000..38d7c4fe --- /dev/null +++ b/features/odl-openflowjava-all/pom.xml @@ -0,0 +1,33 @@ + + + + 4.0.0 + + org.opendaylight.odlparent + single-feature-parent + 2.0.0 + + + + org.opendaylight.openflowjava + odl-openflowjava-all + 0.10.0-SNAPSHOT + feature + + + ODL :: openflowjava :: ${project.artifactId} + + + + org.opendaylight.openflowjava + odl-openflowjava-protocol + ${project.version} + xml + features + + + + diff --git a/features/odl-openflowjava-protocol/pom.xml b/features/odl-openflowjava-protocol/pom.xml new file mode 100644 index 00000000..9092873c --- /dev/null +++ b/features/odl-openflowjava-protocol/pom.xml @@ -0,0 +1,157 @@ + + + + 4.0.0 + + org.opendaylight.odlparent + single-feature-parent + 2.0.0 + + + + org.opendaylight.openflowjava + odl-openflowjava-protocol + 0.10.0-SNAPSHOT + feature + + + ODL :: openflowjava :: ${project.artifactId} + + + 0.7.0-SNAPSHOT + 1.6.0-SNAPSHOT + 2.3.0-SNAPSHOT + 0.11.0-SNAPSHOT + 1.9.0 + + + + + + + + org.opendaylight.openflowjava + openflowjava-artifacts + ${project.version} + import + pom + + + + + org.opendaylight.odlparent + odl-netty-4 + ${odlparent.netty} + import + pom + + + + + org.opendaylight.mdsal + mdsal-artifacts + ${mdsal.version} + import + pom + + + + org.opendaylight.mdsal.model + mdsal-model-artifacts + ${mdsal.model.version} + import + pom + + + + + org.opendaylight.controller + config-artifacts + ${config.version} + import + pom + + + org.opendaylight.controller + mdsal-artifacts + ${controller.mdsal.version} + import + pom + + + + + + + + org.opendaylight.mdsal + odl-mdsal-binding-base + xml + features + + + org.opendaylight.mdsal.model + odl-mdsal-models + xml + features + + + org.opendaylight.controller + odl-config-api + xml + features + + + org.opendaylight.controller + odl-mdsal-common + xml + features + + + org.opendaylight.odlparent + odl-netty-4 + xml + features + + + + org.opendaylight.openflowjava + openflow-protocol-api + + + org.opendaylight.openflowjava + openflow-protocol-spi + + + org.opendaylight.openflowjava + openflow-protocol-impl + + + org.opendaylight.openflowjava + openflowjava-util + + + + org.opendaylight.openflowjava + openflowjava-config + xml + configstats + + + org.opendaylight.openflowjava + openflowjava-blueprint-config + xml + config + + + org.opendaylight.openflowjava + openflowjava-blueprint-config + xml + legacyConfig + + + + diff --git a/features/odl-openflowjava-protocol/src/main/feature/feature.xml b/features/odl-openflowjava-protocol/src/main/feature/feature.xml new file mode 100644 index 00000000..b1261d3f --- /dev/null +++ b/features/odl-openflowjava-protocol/src/main/feature/feature.xml @@ -0,0 +1,9 @@ + + + + + mvn:org.opendaylight.openflowjava/openflowjava-config/${project.version}/xml/configstats + mvn:org.opendaylight.openflowjava/openflowjava-blueprint-config/${project.version}/xml/config + mvn:org.opendaylight.openflowjava/openflowjava-blueprint-config/${project.version}/xml/legacyConfig + + diff --git a/features/pom.xml b/features/pom.xml index 099cebe7..44633fb4 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -3,179 +3,23 @@ 4.0.0 org.opendaylight.odlparent - features-parent - 1.8.0-SNAPSHOT + odlparent-lite + 2.0.0 org.opendaylight.openflowjava - features-openflowjava - 0.9.0-SNAPSHOT - jar - - - 0.6.0-SNAPSHOT - 1.5.0-SNAPSHOT - 2.2.0-SNAPSHOT - 1.5.0-SNAPSHOT - 0.10.0-SNAPSHOT - - - - - - - org.opendaylight.openflowjava - openflowjava-artifacts - ${project.version} - import - pom - - - - - org.opendaylight.odlparent - odlparent-artifacts - 1.8.0-SNAPSHOT - import - pom - - - - - org.opendaylight.mdsal - mdsal-artifacts - ${mdsal.version} - import - pom - - - - org.opendaylight.mdsal.model - mdsal-model-artifacts - ${mdsal.model.version} - import - pom - - - - - org.opendaylight.controller - config-artifacts - ${config.version} - import - pom - - - org.opendaylight.controller - mdsal-artifacts - ${controller.mdsal.version} - import - pom - - - - - - - - - org.opendaylight.mdsal - features-mdsal - ${mdsal.version} - features - xml - - - org.opendaylight.mdsal.model - features-mdsal-model - ${mdsal.model.version} - features - xml - - - org.opendaylight.controller - features-config - features - xml - - - org.opendaylight.controller - features-mdsal - ${controller.mdsal.version} - features - xml - - - org.opendaylight.odlparent - features-odlparent - features - xml - - - - - org.opendaylight.openflowjava - openflow-protocol-api - - - org.opendaylight.openflowjava - openflow-protocol-spi - - - org.opendaylight.openflowjava - openflow-protocol-impl - - - - org.opendaylight.openflowjava - openflowjava-blueprint-config - xml - config - - - org.opendaylight.openflowjava - openflowjava-blueprint-config - xml - legacyConfig - - - - org.opendaylight.openflowjava - openflowjava-util - - - ${project.groupId} - openflowjava-config - xml - configstats - - - io.netty - netty-codec - - - io.netty - netty-handler - - - io.netty - netty-common - - - io.netty - netty-buffer - - - io.netty - netty-transport - - - io.netty - netty-transport-native-epoll - - linux-x86_64 - - + features-aggregator + 0.10.0-SNAPSHOT + pom + + ODL :: openflowjava :: ${project.artifactId} + + + features-openflowjava + odl-openflowjava-protocol + odl-openflowjava-all + diff --git a/features/src/main/features/features.xml b/features/src/main/features/features.xml deleted file mode 100644 index 63be9313..00000000 --- a/features/src/main/features/features.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - mvn:org.opendaylight.yangtools/features-yangtools/{{VERSION}}/xml/features - mvn:org.opendaylight.controller/features-config/{{VERSION}}/xml/features - mvn:org.opendaylight.mdsal/features-mdsal/{{VERSION}}/xml/features - mvn:org.opendaylight.controller/features-mdsal/{{VERSION}}/xml/features - mvn:org.opendaylight.mdsal.model/features-mdsal-model/{{VERSION}}/xml/features - mvn:org.opendaylight.odlparent/features-odlparent/{{VERSION}}/xml/features - - odl-openflowjava-protocol - - - odl-mdsal-binding-base - odl-mdsal-models - odl-config-api - odl-mdsal-common - odl-netty - mvn:org.opendaylight.openflowjava/openflow-protocol-api/{{VERSION}} - mvn:org.opendaylight.openflowjava/openflow-protocol-spi/{{VERSION}} - mvn:org.opendaylight.openflowjava/openflow-protocol-impl/{{VERSION}} - mvn:org.opendaylight.openflowjava/openflowjava-util/{{VERSION}} - mvn:org.opendaylight.openflowjava/openflowjava-blueprint-config/{{VERSION}} - mvn:org.opendaylight.openflowjava/openflowjava-config/${project.version}/xml/configstats - mvn:org.opendaylight.openflowjava/openflowjava-blueprint-config/${project.version}/xml/config - mvn:org.opendaylight.openflowjava/openflowjava-blueprint-config/${project.version}/xml/legacyConfig - - diff --git a/openflow-protocol-api/pom.xml b/openflow-protocol-api/pom.xml index 3d815745..5a2777d0 100644 --- a/openflow-protocol-api/pom.xml +++ b/openflow-protocol-api/pom.xml @@ -4,22 +4,24 @@ org.opendaylight.mdsal binding-parent - 0.10.0-SNAPSHOT + 0.11.0-SNAPSHOT org.opendaylight.openflowjava openflow-protocol-api - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT bundle - Openflow Protocol Library - API + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD - 2.2.0-SNAPSHOT - 0.10.0-SNAPSHOT + 2.3.0-SNAPSHOT + 0.11.0-SNAPSHOT @@ -75,7 +77,7 @@ org.mockito - mockito-all + mockito-core diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java index 89cd461f..a61ea513 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java @@ -10,6 +10,7 @@ import com.google.common.annotations.Beta; import java.net.InetSocketAddress; import java.util.concurrent.Future; +import org.opendaylight.openflowjava.protocol.api.extensibility.AlienMessageListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolService; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; @@ -35,6 +36,7 @@ public interface ConnectionAdapter extends OpenflowProtocolService { * @return address of the remote end - address of a switch if connected */ InetSocketAddress getRemoteAddress(); + /** * @param messageListener here will be pushed all messages from switch */ @@ -45,6 +47,12 @@ public interface ConnectionAdapter extends OpenflowProtocolService { */ void setSystemListener(SystemNotificationsListener systemListener); + /** + * Set handler for alien messages received from device + * @param alienMessageListener here will be pushed all alien messages from switch + */ + void setAlienMessageListener(AlienMessageListener alienMessageListener); + /** * Throws exception if any of required listeners is missing */ diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java index 3212078c..3b9e7752 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java @@ -9,6 +9,7 @@ import com.google.common.annotations.Beta; import com.google.common.util.concurrent.FutureCallback; +import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; @@ -44,5 +45,38 @@ public interface OutboundQueue { * @param callback Callback to be invoked, or null if no callback should be invoked. * @throws IllegalArgumentException if the slot is already committed or was never reserved. */ - void commitEntry(@Nonnull Long xid, @Nullable OfHeader message, @Nullable FutureCallback callback); + void commitEntry( + @Nonnull Long xid, + @Nullable OfHeader message, + @Nullable FutureCallback callback); + + /** + * Commit the specified offset using a message. Specified callback will + * be invoked once we know how it has resolved, either with a normal response, + * implied completion via a barrier, or failure (such as connection drop). For + * multipart responses, {@link FutureCallback#onSuccess(Object)} will be invoked + * multiple times as the corresponding responses arrive. If the request is completed + * with a response, the object reported will be non-null. If the request's completion + * is implied by a barrier, the object reported will be null. + * + * If this request fails on the remote device, {@link FutureCallback#onFailure(Throwable)} + * will be called with an instance of {@link DeviceRequestFailedException}. + * + * If the request fails due to local reasons, {@link FutureCallback#onFailure(Throwable)} + * will be called with an instance of {@link OutboundQueueException}. In particular, if + * this request failed because the device disconnected, {@link OutboundQueueException#DEVICE_DISCONNECTED} + * will be reported. + * + * @param xid Previously-reserved XID + * @param message Message which should be sent out, or null if the reservation + * should be cancelled. + * @param callback Callback to be invoked, or null if no callback should be invoked. + * @param isComplete Function to determine if OfHeader is processing is complete + * @throws IllegalArgumentException if the slot is already committed or was never reserved. + */ + void commitEntry( + @Nonnull Long xid, + @Nullable OfHeader message, + @Nullable FutureCallback callback, + @Nullable Function isComplete); } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java new file mode 100644 index 00000000..a3cd7c6c --- /dev/null +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java @@ -0,0 +1,19 @@ +/* + * 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.openflowjava.protocol.api.extensibility; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +public interface AlienMessageListener { + + /** + * Handler for alien but successfully deserialized messages for device + * @param message alien message + */ + void onAlienMessage(OfHeader message); +} diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java index b227453e..5a0658eb 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java @@ -13,6 +13,8 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; @@ -33,6 +35,20 @@ */ public interface DeserializerExtensionProvider { + /** + * Registers deserializer. + * Throws IllegalStateException when there is + * a deserializer already registered under given key. + *

+ * If the deserializer implements {@link DeserializerRegistryInjector} interface, + * the deserializer is injected with DeserializerRegistry instance. + * + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerDeserializer(MessageCodeKey key, + OFGeneralDeserializer deserializer); + /** * Unregisters custom deserializer * @param key used for deserializer lookup @@ -112,4 +128,18 @@ void registerMeterBandDeserializer(ExperimenterIdDeserializerKey key, */ void registerQueuePropertyDeserializer(ExperimenterIdDeserializerKey key, OFDeserializer deserializer); + + /** + * Registers type to class mapping used to assign return type when deserializing message + * @param key type to class key + * @param clazz return class + */ + void registerDeserializerMapping(TypeToClassKey key, Class clazz); + + /** + * Unregisters type to class mapping used to assign return type when deserializing message + * @param key type to class key + * @return true if mapping was successfully removed + */ + boolean unregisterDeserializerMapping(TypeToClassKey key); } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java index a0fe9391..c80df7b9 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java @@ -8,13 +8,13 @@ package org.opendaylight.openflowjava.protocol.api.extensibility; import io.netty.buffer.ByteBuf; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * @author michal.polkorab * @param output message type */ -public interface HeaderDeserializer extends OFGeneralDeserializer { +public interface HeaderDeserializer extends OFGeneralDeserializer { /** * Deserializes byte message headers diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java index b8b8a029..427d84ce 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java @@ -8,14 +8,14 @@ package org.opendaylight.openflowjava.protocol.api.extensibility; import io.netty.buffer.ByteBuf; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * Does only-header serialization (such as oxm_ids, action_ids, instruction_ids) * @author michal.polkorab * @param input message type */ -public interface HeaderSerializer extends OFGeneralSerializer { +public interface HeaderSerializer extends OFGeneralSerializer { /** * Serializes object headers (e.g. for Multipart message - Table Features) diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java index f108b7c8..366cd3ab 100755 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java @@ -14,6 +14,7 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.InstructionSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; @@ -34,6 +35,21 @@ */ public interface SerializerExtensionProvider { + /** + * Registers serializer + * Throws IllegalStateException when there is + * a serializer already registered under given key. + * + * If the serializer implements {@link SerializerRegistryInjector} interface, + * the serializer is injected with SerializerRegistry instance. + * + * @param serializer key type + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerSerializer(MessageTypeKey key, + OFGeneralSerializer serializer); + /** * Unregisters custom serializer * @param key used for serializer lookup diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java similarity index 95% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassKey.java rename to openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java index 0f6b9caf..71eed094 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java @@ -5,7 +5,7 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowjava.protocol.impl.util; +package org.opendaylight.openflowjava.protocol.api.keys; /** * @author michal.polkorab diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java index 8c6539b6..58d6ccd4 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java @@ -68,10 +68,6 @@ public abstract class EncodeConstants { public static final long ONF_EXPERIMENTER_ID = 0x4F4E4600; /** ONFOXM_ET_TCP_FLAGS value */ public static final int ONFOXM_ET_TCP_FLAGS = 42; - /** ONF_ET_BUNDLE_CONTROL message type */ - public static final int ONF_ET_BUNDLE_CONTROL = 2300; - /** ONF_ET_BUNDLE_ADD_MESSAGE message type */ - public static final int ONF_ET_BUNDLE_ADD_MESSAGE = 2301; private EncodeConstants() { //not called diff --git a/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang b/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang index 17c89408..29a20351 100644 --- a/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang +++ b/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang @@ -3,13 +3,6 @@ module openflow-approved-extensions { prefix "ofext"; import yang-ext {prefix ext;} - import ietf-inet-types {prefix inet;} - import ietf-yang-types {prefix yang;} - - import openflow-types {prefix oft;} - import openflow-protocol {prefix ofproto;} - import openflow-action {prefix ofaction;} - import openflow-instruction {prefix ofinstruction;} import openflow-extensible-match {prefix oxm;} import openflow-augments {prefix aug;} @@ -18,78 +11,6 @@ module openflow-approved-extensions { } //ONF Approved OpenFlow Extensions - - // ONF experimenter error codes - typedef onf-experimenter-error-code { - description "Error codes for experimenter error type."; - type enumeration { - enum ONFERR_ET_UNKNOWN { - description "Unspecified error."; - value 2300; - } - enum ONFERR_ET_EPERM { - description "Permissions error."; - value 2301; - } - enum ONFERR_ET_BAD_ID { - description "Bundle ID doesn’t exist."; - value 2302; - } - enum ONFERR_ET_BUNDLE_EXIST { - description "Bundle ID already exist."; - value 2303; - } - enum ONFERR_ET_BUNDLE_CLOSED { - description "Bundle ID is closed."; - value 2304; - } - enum ONFERR_ET_OUT_OF_BUNDLES { - description "Too many bundles IDs."; - value 2305; - } - enum ONFERR_ET_BAD_TYPE { - description "Unsupported or unknown message control type."; - value 2306; - } - enum ONFERR_ET_BAD_FLAGS { - description "Unsupported, unknown, or inconsistent flags."; - value 2307; - } - enum ONFERR_ET_MSG_BAD_LEN { - description "Length problem in included message."; - value 2308; - } - enum ONFERR_ET_MSG_BAD_XID { - description "Inconsistent or duplicate XID."; - value 2309; - } - enum ONFERR_ET_MSG_UNSUP { - description "Unsupported message in this bundle."; - value 2310; - } - enum ONFERR_ET_MSG_CONFLICT { - description "Unsupported message combination in this bundle."; - value 2311; - } - enum ONFERR_ET_MSG_TOO_MANY { - description "Can not handle this many messages in bundle."; - value 2312; - } - enum ONFERR_ET_MSG_FAILED { - description "One message in bundle failed."; - value 2313; - } - enum ONFERR_ET_TIMEOUT { - description "Bundle is taking too long."; - value 2314; - } - enum ONFERR_ET_BUNDLE_IN_PROGRESS { - description "Bundle is locking the resource."; - value 2315; - } - } - } - // Extension 109 - TCP FLAGS identity tcp_flags { base oxm:match-field; @@ -108,124 +29,4 @@ module openflow-approved-extensions { } } - // Extension 230 - Bundle Extension (experimenterID 0x4F4E4600) - typedef bundle-id { - description "Identify the bundle."; - type uint32; - } - - typedef bundle-control-type { - description "Bundle control message type."; - type enumeration { - enum ONF_BCT_OPEN_REQUEST { - value 0; - } - enum ONF_BCT_OPEN_REPLY { - value 1; - } - enum ONF_BCT_CLOSE_REQUEST { - value 2; - } - enum ONF_BCT_CLOSE_REPLY { - value 3; - } - enum ONF_BCT_COMMIT_REQUEST { - value 4; - } - enum ONF_BCT_COMMIT_REPLY { - value 5; - } - enum ONF_BCT_DISCARD_REQUEST { - value 6; - } - enum ONF_BCT_DISCARD_REPLY { - value 7; - } - } - } - - typedef bundle-flags { - description "Bundle configuration flags."; - type bits { - bit atomic { - description "Execute atomically."; - position 0; - } - bit ordered { - description "Execute in specified order."; - position 1; - } - } - } - - typedef bundle-property-type { - description "Bundle property types."; - type enumeration { - enum ONF_ET_BPT_EXPERIMENTER { - description "Experimenter property."; - value 65535; //0xFFFF - } - } - } - - grouping bundle-properties { - list bundle-property { - description "Bundle properties list."; - leaf type { - type bundle-property-type; - } - choice bundle-property-entry { - case bundle-experimenter-property { - leaf experimenter { - type oft:experimenter-id; - } - leaf exp-type { - type uint32; - } - choice bundle-experimenter-property-data { - // to be augmented by vendors - } - } - } - } - } - - augment "/ofproto:experimenter/ofproto:input/ofproto:experimenter-data-of-choice" { - case bundle-control { - description "ONF_ET_BUNDLE_CONTROL message in OpenFlow Switch Extension 230."; - leaf bundle-id { - type bundle-id; - } - leaf type { - type bundle-control-type; - } - leaf flags { - type bundle-flags; - } - uses bundle-properties; - } - case bundle-add-message { - description "ONF_ET_BUNDLE_ADD_MESSAGE in OpenFlow Switch Extension 230."; - leaf bundle-id { - type bundle-id; - } - leaf flags { - type bundle-flags; - } - // Inner message - choice message { - description "Message added to the bundle."; - case flow-mod-case { - uses ofproto:flow-mod; - } - case group-mod-case { - uses ofproto:group-mod; - } - case port-mod-case { - uses ofproto:port-mod; - } - } - uses bundle-properties; - } - } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassKeyTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java similarity index 90% rename from openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassKeyTest.java rename to openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java index a9ebcf43..8b6192d3 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassKeyTest.java +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java @@ -6,12 +6,11 @@ * and is available at http://www.eclipse.org/legal/epl-v10.html */ -package org.opendaylight.openflowjava.protocol.impl.deserialization; +package org.opendaylight.openflowjava.protocol.api.keys; import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.util.TypeToClassKey; /** * * @author madamjak diff --git a/openflow-protocol-impl/pom.xml b/openflow-protocol-impl/pom.xml index e91846e0..62c2ddd3 100644 --- a/openflow-protocol-impl/pom.xml +++ b/openflow-protocol-impl/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent openflow-protocol-impl bundle - Openflow Protocol Library - IMPL + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD @@ -52,12 +54,12 @@ - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl ${salGeneratorPath} - org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + org.opendaylight.mdsal.binding.yang.unified.doc.generator.maven.DocumentationGeneratorImpl ${project.build.directory}/site/models @@ -144,7 +146,7 @@ org.mockito - mockito-all + mockito-core org.opendaylight.controller diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java index 7ecc39e1..612afcb7 100755 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java @@ -38,6 +38,7 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; @@ -141,7 +142,7 @@ private ServerFacade createAndConfigureServer() { // TODO : Add option to disable Epoll. boolean isEpollEnabled = Epoll.isAvailable(); - if (transportProtocol.equals(TransportProtocol.TCP) || transportProtocol.equals(TransportProtocol.TLS)) { + if ((TransportProtocol.TCP.equals(transportProtocol) || TransportProtocol.TLS.equals(transportProtocol))) { server = new TcpHandler(connConfig.getAddress(), connConfig.getPort()); final TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer(); ((TcpHandler) server).setChannelInitializer(channelInitializer); @@ -151,7 +152,7 @@ private ServerFacade createAndConfigureServer() { connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler, isEpollEnabled); connectionInitializer.setChannelInitializer(channelInitializer); connectionInitializer.run(); - } else if (transportProtocol.equals(TransportProtocol.UDP)){ + } else if (TransportProtocol.UDP.equals(transportProtocol)){ server = new UdpHandler(connConfig.getAddress(), connConfig.getPort()); ((UdpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); ((UdpHandler) server).setChannelInitializer(factory.createUdpChannelInitializer()); @@ -301,4 +302,23 @@ public ConnectionConfiguration getConfiguration() { return this.connConfig; } + @Override + public void registerSerializer(MessageTypeKey key, OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerDeserializer(MessageCodeKey key, OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerDeserializerMapping(final TypeToClassKey key, final Class clazz) { + deserializationFactory.registerMapping(key, clazz); + } + + @Override + public boolean unregisterDeserializerMapping(final TypeToClassKey key) { + return deserializationFactory.unregisterMapping(key); + } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java index 16106a1a..b4356ee4 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java @@ -10,23 +10,30 @@ import com.google.common.base.Preconditions; import com.google.common.base.Verify; +import com.google.common.util.concurrent.FutureCallback; + import io.netty.channel.Channel; + import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.function.Function; + import javax.annotation.Nonnull; import javax.annotation.concurrent.GuardedBy; + import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueue; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; abstract class AbstractStackedOutboundQueue implements OutboundQueue { private static final Logger LOG = LoggerFactory.getLogger(AbstractStackedOutboundQueue.class); - protected static final AtomicLongFieldUpdater LAST_XID_OFFSET_UPDATER = AtomicLongFieldUpdater .newUpdater(AbstractStackedOutboundQueue.class, "lastXid"); @@ -55,6 +62,11 @@ abstract class AbstractStackedOutboundQueue implements OutboundQueue { unflushedSegments.add(firstSegment); } + @Override + public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback) { + commitEntry(xid, message, callback, OutboundQueueEntry.DEFAULT_IS_COMPLETE); + } + @GuardedBy("unflushedSegments") protected void ensureSegment(final StackedSegment first, final int offset) { final int segmentOffset = offset / StackedSegment.SEGMENT_SIZE; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java index 8d9c8746..e9de9ca2 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java @@ -15,6 +15,7 @@ import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration; +import org.opendaylight.openflowjava.protocol.api.extensibility.AlienMessageListener; import org.opendaylight.openflowjava.protocol.impl.core.OFVersionDetector; import org.opendaylight.openflowjava.protocol.impl.core.PipelineHandlers; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; @@ -47,6 +48,7 @@ public class ConnectionAdapterImpl extends AbstractConnectionAdapterStatistics i private ConnectionReadyListener connectionReadyListener; private OpenflowProtocolListener messageListener; private SystemNotificationsListener systemListener; + private AlienMessageListener alienMessageListener; private AbstractOutboundQueueManager outputManager; private OFVersionDetector versionDetector; @@ -80,6 +82,11 @@ public void setSystemListener(final SystemNotificationsListener systemListener) this.systemListener = systemListener; } + @Override + public void setAlienMessageListener(final AlienMessageListener alienMessageListener) { + this.alienMessageListener = alienMessageListener; + } + @Override public void consumeDeviceMessage(final DataObject message) { LOG.debug("ConsumeIntern msg on {}", channel); @@ -131,19 +138,24 @@ public void consumeDeviceMessage(final DataObject message) { } } else if (message instanceof OfHeader) { LOG.debug("OF header msg received"); + boolean found = false; if (outputManager == null || !outputManager.onMessage((OfHeader) message)) { final RpcResponseKey key = createRpcResponseKey((OfHeader) message); final ResponseExpectedRpcListener listener = findRpcResponse(key); if (listener != null) { + found = true; LOG.debug("Corresponding rpcFuture found"); - listener.completed((OfHeader)message); + listener.completed((OfHeader) message); LOG.debug("After setting rpcFuture"); responseCache.invalidate(key); - } else { - LOG.warn("received unexpected rpc response: {}", key); } } + + if (!found && alienMessageListener != null) { + LOG.debug("Alien message {} received", message.getImplementedInterface()); + alienMessageListener.onAlienMessage((OfHeader) message); + } } else { LOG.warn("message listening not supported for type: {}", message.getClass()); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java index 72efc18a..d88566b8 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java @@ -10,24 +10,47 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.FutureCallback; + +import java.util.function.Function; + import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; 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.slf4j.Logger; import org.slf4j.LoggerFactory; final class OutboundQueueEntry { private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntry.class); + public static final Function DEFAULT_IS_COMPLETE = new Function() { + + @Override + public Boolean apply(final OfHeader message) { + if (message instanceof MultipartReplyMessage) { + return !((MultipartReplyMessage) message).getFlags().isOFPMPFREQMORE(); + } + + return true; + } + + }; + private FutureCallback callback; private OfHeader message; private boolean completed; private boolean barrier; private volatile boolean committed; private OutboundQueueException lastException = null; + private Function isCompletedFunction = DEFAULT_IS_COMPLETE; void commit(final OfHeader message, final FutureCallback callback) { + commit(message, callback, DEFAULT_IS_COMPLETE); + } + + void commit(final OfHeader message, final FutureCallback callback, + final Function isCompletedFunction) { if (this.completed) { LOG.warn("Can't commit a completed message."); if (callback != null) { @@ -37,6 +60,7 @@ void commit(final OfHeader message, final FutureCallback callback) { this.message = message; this.callback = callback; this.barrier = message instanceof BarrierInput; + this.isCompletedFunction = isCompletedFunction; // Volatile write, needs to be last this.committed = true; @@ -90,13 +114,7 @@ boolean complete(final OfHeader response) { // Multipart requests are special, we have to look at them to see // if there is something outstanding and adjust ourselves accordingly - final boolean reallyComplete; - if (response instanceof MultipartReplyMessage) { - reallyComplete = !((MultipartReplyMessage) response).getFlags().isOFPMPFREQMORE(); - LOG.debug("Multipart reply {}", response); - } else { - reallyComplete = true; - } + final boolean reallyComplete = isCompletedFunction.apply(response); completed = reallyComplete; if (callback != null) { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java index cafd114c..dd1e9520 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java @@ -8,8 +8,12 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; import com.google.common.util.concurrent.FutureCallback; + import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.function.Function; + import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,10 +31,11 @@ final class StackedOutboundQueue extends AbstractStackedOutboundQueue { * This method is expected to be called from multiple threads concurrently */ @Override - public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback) { + public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback, + final Function isCompletedFunction) { final OutboundQueueEntry entry = getEntry(xid); - entry.commit(message, callback); + entry.commit(message, callback, isCompletedFunction); if (entry.isBarrier()) { long my = xid; for (;;) { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java index 2917631a..76b1243a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java @@ -9,10 +9,17 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; import com.google.common.util.concurrent.FutureCallback; + import io.netty.channel.Channel; + +import java.util.function.Function; + import javax.annotation.Nonnull; + import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,14 +39,15 @@ public class StackedOutboundQueueNoBarrier extends AbstractStackedOutboundQueue * This method is expected to be called from multiple threads concurrently */ @Override - public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback) { + public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback, + final Function isCompletedFunction) { final OutboundQueueEntry entry = getEntry(xid); if (message instanceof FlowModInput) { callback.onSuccess(null); - entry.commit(message, null); + entry.commit(message, null, isCompletedFunction); } else { - entry.commit(message, callback); + entry.commit(message, callback, isCompletedFunction); } LOG.trace("Queue {} committed XID {}", this, xid); @@ -111,4 +119,5 @@ int writeEntries(@Nonnull final Channel channel, final long now) { return entries; } + } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java index bf535b2d..de631b11 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java @@ -8,15 +8,14 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization; -import com.google.common.collect.ImmutableMap; import io.netty.buffer.ByteBuf; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.util.TypeToClassKey; import org.opendaylight.yangtools.yang.binding.DataObject; /** @@ -26,20 +25,17 @@ */ public class DeserializationFactory { - private final Map> messageClassMap; + private final Map> messageClassMap = new ConcurrentHashMap<>(); private DeserializerRegistry registry; /** * Constructor */ public DeserializationFactory() { - final Map> temp = new HashMap<>(); - TypeToClassMapInitializer.initializeTypeToClassMap(temp); + TypeToClassMapInitializer.initializeTypeToClassMap(messageClassMap); // Register type to class map for additional deserializers - TypeToClassMapInitializer.initializeAdditionalTypeToClassMap(temp); - - messageClassMap = ImmutableMap.copyOf(temp); + TypeToClassMapInitializer.initializeAdditionalTypeToClassMap(messageClassMap); } /** @@ -60,6 +56,28 @@ public DataObject deserialize(final ByteBuf rawMessage, final short version) { return dataObject; } + /** + * Register new type to class mapping used to assign return type when deserializing message + * @param key type to class key + * @param clazz return class + */ + public void registerMapping(final TypeToClassKey key, final Class clazz) { + messageClassMap.put(key, clazz); + } + + /** + * Unregister type to class mapping used to assign return type when deserializing message + * @param key type to class key + * @return true if mapping was successfully removed + */ + public boolean unregisterMapping(final TypeToClassKey key) { + if (key == null) { + throw new IllegalArgumentException("TypeToClassKey is null"); + } + + return messageClassMap.remove(key) != null; + } + /** * @param registry */ diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java index 488db9c6..79873cc1 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java @@ -9,8 +9,6 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.BundleControlFactory; -import org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.OnfExperimenterErrorFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoRequestMessageFactory; @@ -103,12 +101,6 @@ public static void registerMessageDeserializers(final DeserializerRegistry regis helper.registerDeserializer(25, RoleRequestOutput.class, new RoleReplyMessageFactory()); helper.registerDeserializer(27, GetAsyncOutput.class, new GetAsyncReplyMessageFactory()); - // register ONF approved experimenter serializers - helper.registerExperimenterErrorDeserializer(EncodeConstants.ONF_EXPERIMENTER_ID, - new OnfExperimenterErrorFactory()); - helper.registerExperimenterDeserializer(EncodeConstants.ONF_EXPERIMENTER_ID, - EncodeConstants.ONF_ET_BUNDLE_CONTROL, new BundleControlFactory()); - // register OF v1.4 message deserializers helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF14_VERSION_ID, registry); helper.registerDeserializer(0, HelloMessage.class, new HelloMessageFactory()); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java index 61cce25d..61fe027f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java @@ -10,7 +10,7 @@ import java.util.Map; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.util.TypeToClassInitHelper; -import org.opendaylight.openflowjava.protocol.impl.util.TypeToClassKey; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java deleted file mode 100644 index 0d52e0c8..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactory.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.deserialization.experimenter; - -import io.netty.buffer.ByteBuf; -import java.util.ArrayList; -import java.util.List; -import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleControlType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundlePropertyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterPropertyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControlBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; - -/** - * Translates BundleControl messages (OpenFlow v1.3 extension #230). - */ -public class BundleControlFactory implements OFDeserializer, DeserializerRegistryInjector { - - private DeserializerRegistry deserializerRegistry; - - @Override - public BundleControl deserialize(ByteBuf message) { - BundleId bundleId = new BundleId(message.readUnsignedInt()); - BundleControlType type = BundleControlType.forValue(message.readUnsignedShort()); - BundleFlags flags = createBundleFlags(message.readUnsignedShort()); - BundleControlBuilder builder = new BundleControlBuilder(); - List properties = createBundleProperties(message); - return builder.setBundleId(bundleId) - .setType(type) - .setFlags(flags) - .setBundleProperty(properties) - .build(); - } - - private static BundleFlags createBundleFlags(final int flags) { - Boolean isAtomic = (flags & (1 << 0)) != 0; - Boolean isOrdered = (flags & (1 << 1)) != 0; - return new BundleFlags(isAtomic, isOrdered); - } - - private List createBundleProperties(final ByteBuf message) { - List properties = new ArrayList<>(); - while (message.readableBytes() > 0) { - BundlePropertyType type = BundlePropertyType.forValue(message.readUnsignedShort()); - int length = message.readUnsignedShort(); - if (type != null && type.equals(BundlePropertyType.ONFETBPTEXPERIMENTER)) { - properties.add(createExperimenterBundleProperty(length, message)); - } else { - message.skipBytes(length); - } - } - return properties; - } - - private BundleProperty createExperimenterBundleProperty(final int length, final ByteBuf message) { - BundleExperimenterPropertyBuilder experimenterProperty = new BundleExperimenterPropertyBuilder(); - long experimenterId = message.readUnsignedInt(); - long expType = message.readUnsignedInt(); - experimenterProperty.setExperimenter(new ExperimenterId(experimenterId)); - experimenterProperty.setExpType(expType); - - OFDeserializer deserializer = deserializerRegistry.getDeserializer( - ExperimenterDeserializerKeyFactory.createBundlePropertyDeserializerKey(EncodeConstants.OF13_VERSION_ID, - experimenterId, expType)); - experimenterProperty.setBundleExperimenterPropertyData(deserializer.deserialize(message.readBytes(length - 12))); - - return new BundlePropertyBuilder().setType(BundlePropertyType.ONFETBPTEXPERIMENTER) - .setBundlePropertyEntry(experimenterProperty.build()) - .build(); - } - - @Override - public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { - this.deserializerRegistry = deserializerRegistry; - } - -} - - diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java deleted file mode 100644 index a104531d..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactory.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.deserialization.experimenter; - -import io.netty.buffer.ByteBuf; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.OnfExperimenterErrorCode; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdError; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdErrorBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Translates (ONF approved) experimenter error messages. - */ -public class OnfExperimenterErrorFactory implements OFDeserializer { - - private static final Logger LOG = LoggerFactory.getLogger(OnfExperimenterErrorFactory.class); - private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE"; - private static final String UNKNOWN_CODE = "UNKNOWN_CODE"; - - @Override - public ErrorMessage deserialize(ByteBuf message) { - ErrorMessageBuilder builder = new ErrorMessageBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); - builder.setXid(message.readUnsignedInt()); - - int type = message.readUnsignedShort(); - ErrorType errorType = ErrorType.forValue(type); - if (errorType != null && errorType.equals(ErrorType.EXPERIMENTER)) { - builder.setType(errorType.getIntValue()); - builder.setTypeString(errorType.getName()); - } else { - LOG.warn("Deserializing other than {} error message with {}", ErrorType.EXPERIMENTER.getName(), - this.getClass().getCanonicalName()); - builder.setType(type); - builder.setTypeString(UNKNOWN_TYPE); - } - - int code = message.readUnsignedShort(); - OnfExperimenterErrorCode errorCode = OnfExperimenterErrorCode.forValue(code); - if (errorCode != null) { - builder.setCode(errorCode.getIntValue()); - builder.setCodeString(errorCode.getName()); - } else { - builder.setCode(code); - builder.setCodeString(UNKNOWN_CODE); - } - - builder.addAugmentation(ExperimenterIdError.class, new ExperimenterIdErrorBuilder() - .setExperimenter(new ExperimenterId(message.readUnsignedInt())) - .build()); - - if (message.readableBytes() > 0) { - byte[] data = new byte[message.readableBytes()]; - message.readBytes(data); - builder.setData(data); - } - return builder.build(); - } -} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java index 08b9bc54..23551bb7 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java @@ -9,8 +9,6 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.serialization.experimenter.BundleAddMessageFactory; -import org.opendaylight.openflowjava.protocol.impl.serialization.experimenter.BundleControlFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.BarrierInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoReplyInputMessageFactory; @@ -39,9 +37,6 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.factories.TableModInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.VendorInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.CommonMessageRegistryHelper; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.message.FlowModCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.message.GroupModCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.message.PortModCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; @@ -116,16 +111,5 @@ public static void registerMessageSerializers(SerializerRegistry serializerRegis registryHelper.registerSerializer(SetAsyncInput.class, new SetAsyncInputMessageFactory()); registryHelper.registerSerializer(SetConfigInput.class, new SetConfigMessageFactory()); registryHelper.registerSerializer(TableModInput.class, new TableModInputMessageFactory()); - - // register ONF approved experimenter serializers - registryHelper.registerExperimenterSerializer(EncodeConstants.ONF_EXPERIMENTER_ID, - EncodeConstants.ONF_ET_BUNDLE_CONTROL, new BundleControlFactory()); - registryHelper.registerExperimenterSerializer(EncodeConstants.ONF_EXPERIMENTER_ID, - EncodeConstants.ONF_ET_BUNDLE_ADD_MESSAGE, new BundleAddMessageFactory()); - - // register serializers for inner messages of BundleAddMessage - registryHelper.registerSerializer(FlowModCase.class, new FlowModInputMessageFactory()); - registryHelper.registerSerializer(GroupModCase.class, new GroupModInputMessageFactory()); - registryHelper.registerSerializer(PortModCase.class, new PortModInputMessageFactory()); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactory.java deleted file mode 100644 index 3fc2896a..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import java.util.List; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yangtools.yang.binding.DataContainer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Abstract class for common stuff of bundle messages. - */ -public abstract class AbstractBundleMessageFactory implements OFSerializer, - SerializerRegistryInjector { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractBundleMessageFactory.class); - protected SerializerRegistry serializerRegistry; - - @Override - public void serialize(T input, ByteBuf outBuffer) { - // to be extended - } - - @Override - public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { - this.serializerRegistry = serializerRegistry; - } - - protected static void writeBundleFlags(final BundleFlags bundleFlags, final ByteBuf outBuffer) { - int flagsBitMap = ByteBufUtils.fillBitMask(0, bundleFlags.isAtomic(), bundleFlags.isOrdered()); - outBuffer.writeShort(flagsBitMap); - } - - protected void writeBundleProperties(final List properties, final ByteBuf outBuffer) { - for (BundleProperty property : properties) { - BundlePropertyType type = property.getType(); - if (type != null && type.equals(BundlePropertyType.ONFETBPTEXPERIMENTER)) { - int startIndex = outBuffer.writerIndex(); - outBuffer.writeShort(type.getIntValue()); - int lengthIndex = outBuffer.writerIndex(); - outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); - writeBundleExperimenterProperty(property, outBuffer); - outBuffer.setShort(lengthIndex, outBuffer.writerIndex() - startIndex); - } else { - LOG.warn("lTrying to serialize unknown bundle property (type: {}), skipping", type.getIntValue() ); - } - } - } - - protected void writeBundleExperimenterProperty(final BundleProperty bundleProperty, final ByteBuf outBuffer) { - BundleExperimenterProperty property = (BundleExperimenterProperty) bundleProperty.getBundlePropertyEntry(); - int experimenterId = property.getExperimenter().getValue().intValue(); - int expType = property.getExpType().intValue(); - outBuffer.writeInt(experimenterId); - outBuffer.writeInt(expType); - OFSerializer serializer = serializerRegistry.getSerializer( - ExperimenterSerializerKeyFactory.createBundlePropertySerializerKey(EncodeConstants.OF13_VERSION_ID, - experimenterId, expType)); - serializer.serialize(property.getBundleExperimenterPropertyData(), outBuffer); - } - -} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactory.java deleted file mode 100644 index 9ceec4de..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import java.util.List; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleAddMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.Message; -import org.opendaylight.yangtools.yang.binding.DataContainer; - -/** - * Translates BundleAddMessage messages (OpenFlow v1.3 extension #230). - */ -public class BundleAddMessageFactory extends AbstractBundleMessageFactory { - - @Override - public void serialize(BundleAddMessage input, ByteBuf outBuffer) { - outBuffer.writeInt(input.getBundleId().getValue().intValue()); - outBuffer.writeZero(2); - writeBundleFlags(input.getFlags(), outBuffer); - - int msgStart = outBuffer.writerIndex(); - serializeInnerMessage(input.getMessage(), outBuffer, input.getMessage().getImplementedInterface()); - int msgLength = outBuffer.writerIndex() - msgStart; - - List bundleProperties = input.getBundleProperty(); - if (bundleProperties != null && !bundleProperties.isEmpty()) { - outBuffer.writeZero(paddingNeeded(msgLength)); - writeBundleProperties(input.getBundleProperty(), outBuffer); - } - } - - private void serializeInnerMessage(final Message innerMessage, final ByteBuf outBuffer, - final Class clazz) { - OFSerializer serializer = serializerRegistry.getSerializer( - new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, clazz)); - serializer.serialize((T)innerMessage, outBuffer); - } - - private static int paddingNeeded(final int length) { - int paddingRemainder = length % EncodeConstants.PADDING; - return (paddingRemainder != 0) ? (EncodeConstants.PADDING - paddingRemainder) : 0; - } - -} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactory.java deleted file mode 100644 index 069f34fe..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl; - -/** - * Translates BundleControl messages (OpenFlow v1.3 extension #230). - */ -public class BundleControlFactory extends AbstractBundleMessageFactory { - - @Override - public void serialize(BundleControl input, ByteBuf outBuffer) { - outBuffer.writeInt(input.getBundleId().getValue().intValue()); - outBuffer.writeShort(input.getType().getIntValue()); - writeBundleFlags(input.getFlags(), outBuffer); - if (input.getBundleProperty() != null) { - writeBundleProperties(input.getBundleProperty(), outBuffer); - } - } - -} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java index 62fab014..336b3d03 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java @@ -38,6 +38,7 @@ public class FlowModInputMessageFactory implements OFSerializer, Serial @Override public void serialize(final FlowMod message, final ByteBuf outBuffer) { + int index = outBuffer.writerIndex(); ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); outBuffer.writeLong(message.getCookie().longValue()); outBuffer.writeLong(message.getCookieMask().longValue()); @@ -54,7 +55,7 @@ public void serialize(final FlowMod message, final ByteBuf outBuffer) { registry.>getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class)) .serialize(message.getMatch(), outBuffer); ListSerializer.serializeList(message.getInstruction(), INSTRUCTION_KEY_MAKER, registry, outBuffer); - ByteBufUtils.updateOFHeaderLength(outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); } @Override diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java index 7e7c4848..11c2948b 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java @@ -33,6 +33,7 @@ public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { @Override public void serialize(FlowRemovedMessage message, ByteBuf outBuffer) { + int index = outBuffer.writerIndex(); ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); outBuffer.writeLong(message.getCookie().longValue()); outBuffer.writeShort(message.getPriority()); @@ -47,7 +48,7 @@ public void serialize(FlowRemovedMessage message, ByteBuf outBuffer) { OFSerializer matchSerializer = registry .> getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class)); matchSerializer.serialize(message.getMatch(), outBuffer); - ByteBufUtils.updateOFHeaderLength(outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java index 95a3b7db..db8142a5 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java @@ -34,13 +34,14 @@ public class GroupModInputMessageFactory implements OFSerializer, Seri @Override public void serialize(GroupMod message, ByteBuf outBuffer) { + int index = outBuffer.writerIndex(); ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); outBuffer.writeShort(message.getCommand().getIntValue()); outBuffer.writeByte(message.getType().getIntValue()); outBuffer.writeZero(PADDING_IN_GROUP_MOD_MESSAGE); outBuffer.writeInt(message.getGroupId().getValue().intValue()); serializerBuckets(message.getBucketsList(), outBuffer); - ByteBufUtils.updateOFHeaderLength(outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); } private void serializerBuckets(List buckets, ByteBuf outBuffer) { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java index ded3af6d..03c39887 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java @@ -33,6 +33,7 @@ public class PortModInputMessageFactory implements OFSerializer { @Override public void serialize(final PortMod message, final ByteBuf outBuffer) { + int index = outBuffer.writerIndex(); ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); outBuffer.writeInt(message.getPortNo().getValue().intValue()); outBuffer.writeZero(PADDING_IN_PORT_MOD_MESSAGE_01); @@ -42,7 +43,7 @@ public void serialize(final PortMod message, final ByteBuf outBuffer) { outBuffer.writeInt(createPortConfigBitmask(message.getMask())); outBuffer.writeInt(createPortFeaturesBitmask(message.getAdvertise())); outBuffer.writeZero(PADDING_IN_PORT_MOD_MESSAGE_03); - ByteBufUtils.updateOFHeaderLength(outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); } /** diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java index 260d1b3f..15bc5971 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java @@ -39,15 +39,4 @@ public void registerSerializer(Class msgType, OFGeneralSerializer serializer) serializerRegistry.registerSerializer(new MessageTypeKey<>(version, msgType), serializer); } - /** - * Registers experimenter serializer in registry. - * @param experimenterId experimenterID of experimenter message - * @param type type of experimenter message - * @param serializer serializer instance - */ - public void registerExperimenterSerializer(final long experimenterId, final long type, - final OFGeneralSerializer serializer) { - serializerRegistry.registerSerializer(ExperimenterSerializerKeyFactory - .createExperimenterMessageSerializerKey(version, experimenterId, type), serializer); - } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java index 752ac3e3..6d527c4a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java @@ -10,7 +10,6 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; -import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; /** * Helper class for deserializer registration. @@ -45,27 +44,4 @@ public void registerDeserializer(final int code, final Class deserializedObje } } - /** - * Register experimenter deserializer in registry. - * @param experimenterId experimenterID of experimenter message - * @param type type of experimenter message - * @param deserializer deserializer instance - */ - public void registerExperimenterDeserializer (final long experimenterId, final long type, - final OFGeneralDeserializer deserializer) { - registry.registerDeserializer(ExperimenterDeserializerKeyFactory - .createExperimenterMessageDeserializerKey(version, experimenterId, type), deserializer); - } - - /** - * Register experimenter error deserializer in registry. - * @param experimenterId experimenterID of experimenter message - * @param deserializer deserializer instance - */ - public void registerExperimenterErrorDeserializer (final long experimenterId, - final OFGeneralDeserializer deserializer) { - registry.registerDeserializer(ExperimenterDeserializerKeyFactory - .createExperimenterErrorDeserializerKey(version, experimenterId), deserializer); - } - } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java index 339edd18..b360f89f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java @@ -8,6 +8,7 @@ package org.opendaylight.openflowjava.protocol.impl.util; import java.util.Map; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; /** * @author michal.polkorab diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java index 5b9dc17c..03cc3f99 100755 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java @@ -29,6 +29,8 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.core.ServerFacade; import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; @@ -241,6 +243,12 @@ public void testUnregisterExistingKeys(){ provider.registerMatchEntrySerializer(key16, serializer); Assert.assertTrue("Wrong -- unregister MatchEntrySerializer", provider.unregisterSerializer(key16)); Assert.assertFalse("Wrong -- unregister MatchEntrySerializer by not existing key", provider.unregisterSerializer(key15)); + // -- registerSerializer + final MessageTypeKey key17 = new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, TestSubType.class); + provider.registerSerializer(key17, serializer); + // -- registerDeserializer + final MessageCodeKey key18 = new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 42, TestSubType.class); + provider.registerDeserializer(key18, deserializer); } private static class TestSubType extends ExperimenterActionSubType { diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java index ff36181f..72bbe8e0 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java @@ -7,6 +7,7 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.util.concurrent.ListenableFuture; import java.io.IOException; import java.net.InetAddress; import java.util.concurrent.ExecutionException; @@ -19,16 +20,20 @@ import org.mockito.MockitoAnnotations; import org.opendaylight.openflowjava.protocol.impl.core.UdpChannelInitializer; import org.opendaylight.openflowjava.protocol.impl.core.UdpHandler; - -import com.google.common.util.concurrent.ListenableFuture; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author madamjak * */ public class UdpHandlerTest { - @Mock UdpChannelInitializer udpChannelInitializerMock; - UdpHandler udpHandler; + + private static final Logger LOG = LoggerFactory.getLogger(UdpHandlerTest.class); + + @Mock + private UdpChannelInitializer udpChannelInitializerMock; + private UdpHandler udpHandler; /** * Mock init */ @@ -44,12 +49,12 @@ public void startUp() { * @throws IOException */ @Test - public void testWithEmptyAddress() throws InterruptedException, ExecutionException, IOException { + public void testWithEmptyAddress() throws Exception { udpHandler = new UdpHandler(null, 0); udpHandler.setChannelInitializer(udpChannelInitializerMock); Assert.assertTrue("Wrong - start server", startupServer(false)); try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS).booleanValue()); + Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500, TimeUnit.MILLISECONDS)); } catch (TimeoutException e) { Assert.fail("Wrong - getIsOnlineFuture timed out"); } @@ -64,12 +69,12 @@ public void testWithEmptyAddress() throws InterruptedException, ExecutionExcepti * @throws IOException */ @Test - public void testWithEmptyAddressOnEpoll() throws InterruptedException, ExecutionException, IOException { + public void testWithEmptyAddressOnEpoll() throws Exception { udpHandler = new UdpHandler(null, 0); udpHandler.setChannelInitializer(udpChannelInitializerMock); Assert.assertTrue("Wrong - start server", startupServer(true)); try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS).booleanValue()); + Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); } catch (TimeoutException e) { Assert.fail("Wrong - getIsOnlineFuture timed out"); } @@ -84,13 +89,13 @@ public void testWithEmptyAddressOnEpoll() throws InterruptedException, Execution * @throws IOException */ @Test - public void testWithAddressAndPort() throws InterruptedException, ExecutionException, IOException{ + public void testWithAddressAndPort() throws Exception{ int port = 9874; udpHandler = new UdpHandler(InetAddress.getLocalHost(), port); udpHandler.setChannelInitializer(udpChannelInitializerMock); Assert.assertTrue("Wrong - start server", startupServer(false)); try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS).booleanValue()); + Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); } catch (TimeoutException e) { Assert.fail("Wrong - getIsOnlineFuture timed out"); } @@ -105,13 +110,13 @@ public void testWithAddressAndPort() throws InterruptedException, ExecutionExcep * @throws IOException */ @Test - public void testWithAddressAndPortOnEpoll() throws InterruptedException, ExecutionException, IOException{ + public void testWithAddressAndPortOnEpoll() throws Exception { int port = 9874; udpHandler = new UdpHandler(InetAddress.getLocalHost(), port); udpHandler.setChannelInitializer(udpChannelInitializerMock); Assert.assertTrue("Wrong - start server", startupServer(true)); try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS).booleanValue()); + Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); } catch (TimeoutException e) { Assert.fail("Wrong - getIsOnlineFuture timed out"); } @@ -119,25 +124,28 @@ public void testWithAddressAndPortOnEpoll() throws InterruptedException, Executi shutdownServer(); } - private Boolean startupServer(boolean isEpollEnabled) throws InterruptedException, IOException, ExecutionException { + private Boolean startupServer(final boolean isEpollEnabled) throws InterruptedException, IOException, ExecutionException { ListenableFuture online = udpHandler.getIsOnlineFuture(); /** * Test EPoll based native transport if isEpollEnabled is true. * Else use Nio based transport. */ udpHandler.initiateEventLoopGroups(null, isEpollEnabled); - (new Thread(udpHandler)).start(); - int retry = 0; - while (online.isDone() != true && retry++ < 20) { - Thread.sleep(100); - } - return online.isDone() ; + (new Thread(udpHandler)).start(); + + boolean startedSuccessfully = false; + try { + startedSuccessfully = online.get(10, TimeUnit.SECONDS); + } catch (TimeoutException e) { + LOG.warn("Timeout while waiting for UDP handler to start", e); + } + + return online.isDone(); } - private void shutdownServer() throws InterruptedException, ExecutionException { + private void shutdownServer() throws InterruptedException, ExecutionException, TimeoutException { ListenableFuture shutdownRet = udpHandler.shutdown() ; - while ( shutdownRet.isDone() != true ) - Thread.sleep(100) ; - Assert.assertTrue("Wrong - shutdown failed", shutdownRet.get()); + final Boolean shutdownSucceeded = shutdownRet.get(10, TimeUnit.SECONDS); + Assert.assertTrue("Wrong - shutdown failed", shutdownSucceeded); } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java index 9ff6e9e7..dfa01580 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java @@ -14,7 +14,7 @@ import java.util.Map; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.util.TypeToClassKey; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java deleted file mode 100644 index 77aca382..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/BundleControlFactoryTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.deserialization.experimenter; - -import io.netty.buffer.ByteBuf; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleControlType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl; - -/** - * Tests for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.BundleControlFactory}. - */ -@RunWith(MockitoJUnitRunner.class) -public class BundleControlFactoryTest { - - private OFDeserializer factory; - @Mock - DeserializerRegistry registry; - @Mock - OFDeserializer experimenterPropertyDeserializer; - - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - factory = registry.getDeserializer(ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey( - EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID, EncodeConstants.ONF_ET_BUNDLE_CONTROL)); - } - - @Test - public void testDeserializeWithoutProperties() { - ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 00 00 01 " // bundle ID - + "00 01 " // type - + "00 03"); // flags - BundleControl builtByFactory = factory.deserialize(buffer); - Assert.assertEquals(1, builtByFactory.getBundleId().getValue().intValue()); - BundleFlags flags = new BundleFlags(true, true); - Assert.assertEquals("Wrong atomic flag", flags.isAtomic(), builtByFactory.getFlags().isAtomic()); - Assert.assertEquals("Wrong ordered flag", flags.isOrdered(), builtByFactory.getFlags().isOrdered()); - Assert.assertEquals("Wrong type", BundleControlType.ONFBCTOPENREPLY, builtByFactory.getType()); - Assert.assertTrue("Properties not empty", builtByFactory.getBundleProperty().isEmpty()); - } - - @Test - public void testDeserializeWithProperties() { - ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 00 00 01 " // bundle ID - + "00 05 " // type - + "00 02 " // flags - + "ff ff " // type 1 - + "00 0c " // length 1 - + "00 00 00 01 " // experimenter ID 1 - + "00 00 00 02 " // experimenter type 1 - + "00 00 00 00 " // experimenter data 1 - + "00 00 " // type 2 - + "00 04 " // length 2 - + "00 00 00 00"); // data 2 - Mockito.when(registry.getDeserializer(Matchers.any(MessageCodeKey.class))).thenReturn(experimenterPropertyDeserializer); - ((DeserializerRegistryInjector)factory).injectDeserializerRegistry(registry); - BundleControl builtByFactory = BufferHelper.deserialize(factory, buffer); - Assert.assertEquals(1, builtByFactory.getBundleId().getValue().intValue()); - BundleFlags flags = new BundleFlags(false, true); - Assert.assertEquals("Wrong atomic flag", flags.isAtomic(), builtByFactory.getFlags().isAtomic()); - Assert.assertEquals("Wrong ordered flag", flags.isOrdered(), builtByFactory.getFlags().isOrdered()); - Assert.assertEquals("Wrong type", BundleControlType.ONFBCTCOMMITREPLY, builtByFactory.getType()); - BundleProperty property = builtByFactory.getBundleProperty().get(0); - Assert.assertEquals("Wrong bundle property type", BundlePropertyType.ONFETBPTEXPERIMENTER, property.getType()); - BundleExperimenterProperty experimenterProperty = (BundleExperimenterProperty) property.getBundlePropertyEntry(); - Assert.assertEquals("Wrong experimenter ID", 1, experimenterProperty.getExperimenter().getValue().intValue()); - Assert.assertEquals("Wrong experimenter type", 2, experimenterProperty.getExpType().longValue()); - Mockito.verify(experimenterPropertyDeserializer, Mockito.times(1)).deserialize(buffer); - } - -} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java deleted file mode 100644 index 69891413..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/experimenter/OnfExperimenterErrorFactoryTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.deserialization.experimenter; - -import io.netty.buffer.ByteBuf; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdError; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; - -/** - * Tests for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.experimenter.OnfExperimenterErrorFactory}. - */ -public class OnfExperimenterErrorFactoryTest { - - private OFDeserializer factory; - - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - factory = registry.getDeserializer(ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey( - EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID)); - } - - @Test - public void testVersion() { - ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 00 00 00 01"); - ErrorMessage builtByFactory = factory.deserialize(buffer); - BufferHelper.checkHeaderV13(builtByFactory); - } - - @Test - public void testDeserializeBase() { - ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 4f 4e 46 00"); - ErrorMessage builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong type", EncodeConstants.EXPERIMENTER_VALUE, builtByFactory.getType().intValue()); - Assert.assertEquals("Wrong type string", "EXPERIMENTER", builtByFactory.getTypeString()); - Assert.assertEquals("Wrong experimenter ID", EncodeConstants.ONF_EXPERIMENTER_ID, - builtByFactory.getAugmentation(ExperimenterIdError.class).getExperimenter().getValue().intValue()); - Assert.assertNull("Data is not null", builtByFactory.getData()); - } - - @Test - public void testDeserializeCodes() { - ByteBuf buffer = BufferHelper.buildBuffer("ff ff 08 fc 00 00 00 01"); - ErrorMessage builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2300, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_UNKNOWN", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 08 fd 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2301, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_EPERM", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 08 fe 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2302, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_ID", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 08 ff 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2303, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_EXIST", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 00 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2304, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_CLOSED", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 01 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2305, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_OUT_OF_BUNDLES", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 02 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2306, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_TYPE", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 03 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2307, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BAD_FLAGS", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 04 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2308, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_BAD_LEN", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 05 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2309, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_BAD_XID", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 06 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2310, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_UNSUP", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 07 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2311, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_CONFLICT", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 08 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2312, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_TOO_MANY", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 09 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2313, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_MSG_FAILED", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 0a 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2314, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_TIMEOUT", builtByFactory.getCodeString()); - - buffer = BufferHelper.buildBuffer("ff ff 09 0b 00 00 00 01"); - builtByFactory = factory.deserialize(buffer); - Assert.assertEquals("Wrong code", 2315, builtByFactory.getCode().intValue()); - Assert.assertEquals("Wrong code string", "ONFERR_ET_BUNDLE_IN_PROGRESS", builtByFactory.getCodeString()); - } - -} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactoryTest.java deleted file mode 100644 index 3de49975..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/AbstractBundleMessageFactoryTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -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.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundleProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.BundlePropertyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.BundleExperimenterPropertyBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.message.PortModCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.message.PortModCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfig; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; -import org.opendaylight.yangtools.yang.binding.DataContainer; - -/** - * Test for {@link org.opendaylight.openflowjava.protocol.impl.serialization.experimenter.AbstractBundleMessageFactory} - * and util methods. - */ -public class AbstractBundleMessageFactoryTest { - - @Test - public void writeBundleFlags() throws Exception { - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - AbstractBundleMessageFactory.writeBundleFlags(new BundleFlags(true, true), out); - Assert.assertEquals("Wrong flags", 3, out.readUnsignedShort()); - } - - public static List createListWithBundleExperimenterProperty(BundleExperimenterPropertyData data) { - BundlePropertyBuilder propertyBuilder = new BundlePropertyBuilder(); - propertyBuilder.setType(BundlePropertyType.ONFETBPTEXPERIMENTER); - BundleExperimenterPropertyBuilder experimenterPropertyBuilder = new BundleExperimenterPropertyBuilder(); - experimenterPropertyBuilder.setExperimenter(new ExperimenterId(1L)); - experimenterPropertyBuilder.setExpType(2L); - - experimenterPropertyBuilder.setBundleExperimenterPropertyData(data); - propertyBuilder.setBundlePropertyEntry(experimenterPropertyBuilder.build()); - return new ArrayList<>(Collections.singleton(propertyBuilder.build())); - } - - public static BundleExperimenterPropertyData createBundleExperimenterPropertyData() { - return new BundleExperimenterPropertyData() { - @Override - public Class getImplementedInterface() { - return null; - } - }; - } - - public static PortModCase createPortModCase() { - PortModCaseBuilder caseBuilder = new PortModCaseBuilder(); - caseBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID); - caseBuilder.setXid(3L); - caseBuilder.setPortNo(new PortNumber(9L)); - caseBuilder.setHwAddress(new MacAddress("08:00:27:00:B0:EB")); - caseBuilder.setConfig(new PortConfig(true, false, true, false)); - caseBuilder.setMask(new PortConfig(false, true, false, true)); - caseBuilder.setAdvertise(new PortFeatures(true, false, false, false, - false, false, false, true, - false, false, false, false, - false, false, false, false)); - return caseBuilder.build(); - } -} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactoryTest.java deleted file mode 100644 index 9e662519..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleAddMessageFactoryTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector; -import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; -import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleAddMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleAddMessageBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.bundle.add.message.Message; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortMod; - -/** - * Test for {@link org.opendaylight.openflowjava.protocol.impl.serialization.experimenter.BundleAddMessageFactory}. - */ -@RunWith(MockitoJUnitRunner.class) -public class BundleAddMessageFactoryTest { - - private OFSerializer factory; - @Mock - SerializerRegistry registry; - @Mock - OFSerializer portModSerializer; - @Mock - OFSerializer propertySerializer; - - @Before - public void setUp() { - SerializerRegistry registry = new SerializerRegistryImpl(); - registry.init(); - factory = registry.getSerializer(ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( - EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID, - EncodeConstants.ONF_ET_BUNDLE_ADD_MESSAGE)); - } - - @Test - public void testSerializeWithoutProperties() { - BundleAddMessageBuilder builder = new BundleAddMessageBuilder(); - builder.setBundleId(new BundleId(1L)); - builder.setFlags(new BundleFlags(true, false)); - - Message innerMessage = AbstractBundleMessageFactoryTest.createPortModCase(); - builder.setMessage(innerMessage); - - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - Mockito.when(registry.getSerializer(Matchers.any(MessageTypeKey.class))).thenReturn(portModSerializer); - ((SerializerRegistryInjector) factory).injectSerializerRegistry(registry); - factory.serialize(builder.build(), out); - - Assert.assertEquals("Wrong bundle ID", 1L, out.readUnsignedInt()); - long padding = out.readUnsignedShort(); - Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort()); - Mockito.verify(portModSerializer, Mockito.times(1)).serialize((PortMod)innerMessage, out); - } - - @Test - public void testSerializeWithExperimenterProperty() { - BundleAddMessageBuilder builder = new BundleAddMessageBuilder(); - builder.setBundleId(new BundleId(2L)); - builder.setFlags(new BundleFlags(true, false)); - - Message innerMessage = AbstractBundleMessageFactoryTest.createPortModCase(); - builder.setMessage(innerMessage); - - BundleExperimenterPropertyData data = AbstractBundleMessageFactoryTest.createBundleExperimenterPropertyData(); - builder.setBundleProperty(AbstractBundleMessageFactoryTest.createListWithBundleExperimenterProperty(data)); - - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - Mockito.when(registry.getSerializer(Matchers.any(MessageTypeKey.class))) - .thenReturn(portModSerializer) - .thenReturn(propertySerializer); - ((SerializerRegistryInjector) factory).injectSerializerRegistry(registry); - factory.serialize(builder.build(), out); - - Assert.assertEquals("Wrong bundle ID", 2L, out.readUnsignedInt()); - long padding = out.readUnsignedShort(); - Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort()); - Mockito.verify(portModSerializer, Mockito.times(1)).serialize((PortMod)innerMessage, out); - Mockito.verify(propertySerializer, Mockito.times(1)).serialize(data, out); - } - -} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactoryTest.java deleted file mode 100644 index 180d915a..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/experimenter/BundleControlFactoryTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2016 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.openflowjava.protocol.impl.serialization.experimenter; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.runners.MockitoJUnitRunner; -import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; -import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector; -import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; -import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleControlType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleFlags; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundleId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.BundlePropertyType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.experimenter.input.experimenter.data.of.choice.BundleControlBuilder; - -/** - * Test for {@link org.opendaylight.openflowjava.protocol.impl.serialization.experimenter.BundleControlFactory}. - */ -@RunWith(MockitoJUnitRunner.class) -public class BundleControlFactoryTest { - - private OFSerializer factory; - @Mock - SerializerRegistry registry; - @Mock - OFSerializer serializer; - - @Before - public void setUp() throws Exception { - SerializerRegistry registry = new SerializerRegistryImpl(); - registry.init(); - factory = registry.getSerializer(ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( - EncodeConstants.OF13_VERSION_ID, EncodeConstants.ONF_EXPERIMENTER_ID, EncodeConstants.ONF_ET_BUNDLE_CONTROL)); - } - - @Test - public void testSerializeWithoutProperties() { - BundleControlBuilder builder = new BundleControlBuilder(); - builder.setBundleId(new BundleId(1L)); - builder.setType(BundleControlType.ONFBCTOPENREQUEST); - builder.setFlags(new BundleFlags(true, true)); - - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - factory.serialize(builder.build(), out); - - Assert.assertEquals("Wrong bundle ID", 1L, out.readUnsignedInt()); - Assert.assertEquals("Wrong type", BundleControlType.ONFBCTOPENREQUEST.getIntValue(), out.readUnsignedShort()); - Assert.assertEquals("Wrong flags", 3, out.readUnsignedShort()); - Assert.assertTrue("Unexpected data", out.readableBytes() == 0); - } - - @Test - public void testSerializeWithExperimenterProperty() { - BundleControlBuilder builder = new BundleControlBuilder(); - builder.setBundleId(new BundleId(3L)); - builder.setType(BundleControlType.ONFBCTCOMMITREQUEST); - builder.setFlags(new BundleFlags(false, true)); - - BundleExperimenterPropertyData data = AbstractBundleMessageFactoryTest.createBundleExperimenterPropertyData(); - builder.setBundleProperty(AbstractBundleMessageFactoryTest.createListWithBundleExperimenterProperty(data)); - - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); - Mockito.when(registry.getSerializer(Matchers.any(MessageTypeKey.class))).thenReturn(serializer); - ((SerializerRegistryInjector) factory).injectSerializerRegistry(registry); - factory.serialize(builder.build(), out); - - Assert.assertEquals("Wrong bundle ID", 3L, out.readUnsignedInt()); - Assert.assertEquals("Wrong type", BundleControlType.ONFBCTCOMMITREQUEST.getIntValue(), out.readUnsignedShort()); - Assert.assertEquals("Wrong flags", 2, out.readUnsignedShort()); - Assert.assertEquals("Wrong property type", BundlePropertyType.ONFETBPTEXPERIMENTER.getIntValue(), out.readUnsignedShort()); - int length = out.readUnsignedShort(); - Assert.assertEquals("Wrong experimenter ID", 1, out.readUnsignedInt()); - Assert.assertEquals("Wrong experimenter type", 2, out.readUnsignedInt()); - Mockito.verify(serializer, Mockito.times(1)).serialize(data, out); - } - -} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java index edf21a2c..a3a72a27 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java @@ -154,8 +154,19 @@ public void testFlowModInputMessageFactory() throws Exception { FlowModInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + // simulate parent message + out.writeInt(1); + out.writeZero(2); + out.writeShort(3); + flowModFactory.serialize(message, out); + // read parent message + out.readInt(); + out.skipBytes(2); + out.readShort(); + BufferHelper.checkHeaderV13(out,(byte) 14, 128); cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; out.readBytes(cookie); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java index 616b289b..0ba90a23 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java @@ -94,8 +94,19 @@ public void testSerialize() throws Exception { builder.setMatch(matchBuilder.build()); FlowRemovedMessage message = builder.build(); ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + + // simulate parent message + serializedBuffer.writeInt(1); + serializedBuffer.writeZero(2); + serializedBuffer.writeShort(3); + factory.serialize(message, serializedBuffer); + // read parent message + serializedBuffer.readInt(); + serializedBuffer.skipBytes(2); + serializedBuffer.readShort(); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 72); Assert.assertEquals("Wrong cookie", message.getCookie().longValue(), serializedBuffer.readLong()); Assert.assertEquals("Wrong priority", message.getPriority().intValue(), serializedBuffer.readShort()); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java index 37396655..6e75130f 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java @@ -69,8 +69,19 @@ public void testGroupModInputMessage() throws Exception { GroupModInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + // simulate parent message + out.writeInt(1); + out.writeZero(2); + out.writeShort(3); + groupModFactory.serialize(message, out); + // read parent message + out.readInt(); + out.skipBytes(2); + out.readShort(); + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 32); Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readUnsignedShort()); Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readUnsignedByte()); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java index 3aebd727..f9319019 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java @@ -70,8 +70,19 @@ public void testPortModInput() throws Exception { PortModInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + // simulate parent message + out.writeInt(1); + out.writeZero(2); + out.writeShort(3); + portModFactory.serialize(message, out); + // read parent message + out.readInt(); + out.skipBytes(2); + out.readShort(); + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, MESSAGE_LENGTH); Assert.assertEquals("Wrong PortNo", message.getPortNo().getValue().longValue(), out.readUnsignedInt()); out.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_01); diff --git a/openflow-protocol-it/pom.xml b/openflow-protocol-it/pom.xml index b93ba9e6..58628b30 100644 --- a/openflow-protocol-it/pom.xml +++ b/openflow-protocol-it/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent openflow-protocol-it bundle - Openflow Protocol Integration Test + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD diff --git a/openflow-protocol-spi/pom.xml b/openflow-protocol-spi/pom.xml index 2e7057b6..67a9aa90 100644 --- a/openflow-protocol-spi/pom.xml +++ b/openflow-protocol-spi/pom.xml @@ -3,13 +3,15 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent openflow-protocol-spi bundle - Openflow Protocol Library - SPI + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD @@ -50,12 +52,12 @@ - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl + org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl ${salGeneratorPath} - org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + org.opendaylight.mdsal.binding.yang.unified.doc.generator.maven.DocumentationGeneratorImpl ${project.build.directory}/site/models diff --git a/openflowjava-blueprint-config/pom.xml b/openflowjava-blueprint-config/pom.xml index c3e6c6ca..71efa0d2 100644 --- a/openflowjava-blueprint-config/pom.xml +++ b/openflowjava-blueprint-config/pom.xml @@ -11,13 +11,15 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent openflowjava-blueprint-config Blueprint configuration files for openflowjava statistics bundle - Openflow Protocol Library - Blueprint Config + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD diff --git a/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml b/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml index 48f8bf55..08b8a52e 100644 --- a/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml +++ b/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml @@ -1,6 +1,6 @@ openflow-switch-connection-provider-default-impl - 6633 + 6653 TCP configuration/ssl/ctl.jks diff --git a/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml b/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml index 7772ecc8..13860139 100644 --- a/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml +++ b/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml @@ -1,6 +1,6 @@ openflow-switch-connection-provider-legacy-impl - 6653 + 6633 TCP configuration/ssl/ctl.jks diff --git a/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml b/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml index 2cd5a070..e1d3c000 100644 --- a/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml +++ b/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml @@ -5,7 +5,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/openflowjava-config/pom.xml b/openflowjava-config/pom.xml index 1f7bc3e0..419a0609 100644 --- a/openflowjava-config/pom.xml +++ b/openflowjava-config/pom.xml @@ -11,13 +11,15 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent openflowjava-config Configuration files for openflowjava statistics jar - Openflow Protocol Library - CONFIG + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD diff --git a/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java new file mode 100644 index 00000000..3b7bc68a --- /dev/null +++ b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java @@ -0,0 +1,162 @@ + +package org.opendaylight.openflowjava.tools; + +import java.math.BigInteger; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for configurationType complex type. + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "configurationType", propOrder = { + "controllerIp", + "devicesCount", + "ssl", + "threads", + "port", + "timeout", + "freeze", + "sleep" +}) +public class ConfigurationType { + + @XmlElement(name = "controller-ip", required = true, defaultValue = "127.0.0.1") + String controllerIp; + @XmlElement(name = "devices-count", required = true, defaultValue = "1") + @XmlSchemaType(name = "positiveInteger") + BigInteger devicesCount; + @XmlElement(defaultValue = "false") + Boolean ssl; + @XmlElement(defaultValue = "1") + @XmlSchemaType(name = "positiveInteger") + BigInteger threads; + @XmlElement(required = true, defaultValue = "6653") + @XmlSchemaType(name = "positiveInteger") + BigInteger port; + @XmlElement(defaultValue = "1000") + @XmlSchemaType(name = "positiveInteger") + BigInteger timeout; + @XmlElement(defaultValue = "3") + @XmlSchemaType(name = "positiveInteger") + BigInteger freeze; + @XmlElement(defaultValue = "100") + Long sleep; + @XmlAttribute(name = "name", required = true) + String name; + + /** + * Gets the value of the controllerIp property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getControllerIp() { + return controllerIp; + } + + /** + * Gets the value of the devicesCount property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getDevicesCount() { + return devicesCount; + } + + /** + * Gets the value of the ssl property. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isSsl() { + return ssl; + } + + /** + * Gets the value of the threads property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getThreads() { + return threads; + } + + /** + * Gets the value of the port property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getPort() { + return port; + } + + /** + * Gets the value of the timeout property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getTimeout() { + return timeout; + } + + /** + * Gets the value of the freeze property. + * + * @return + * possible object is + * {@link BigInteger } + * + */ + public BigInteger getFreeze() { + return freeze; + } + + /** + * Gets the value of the sleep property. + * + * @return + * possible object is + * {@link Long } + * + */ + public Long getSleep() { + return sleep; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + +} diff --git a/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java new file mode 100644 index 00000000..5f284e57 --- /dev/null +++ b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java @@ -0,0 +1,58 @@ + +package org.opendaylight.openflowjava.tools; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "configuration" +}) +@XmlRootElement(name = "configurations") +public class Configurations { + + @XmlElement(required = true) + private List configuration; + + /** + * Gets the value of the configuration property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the configuration property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getConfiguration().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ConfigurationType } + * + * + */ + public List getConfiguration() { + if (configuration == null) { + configuration = new ArrayList<>(); + } + return this.configuration; + } + + public void setConfiguration(List configuration) { + this.configuration = configuration; + } +} diff --git a/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java new file mode 100644 index 00000000..6733afd7 --- /dev/null +++ b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java @@ -0,0 +1,39 @@ +package org.opendaylight.openflowjava.tools; + +import org.xml.sax.SAXException; + +import javax.xml.bind.JAXBException; + +/** + * + * @author Jozef Bacigal + * Date: 8.3.2016 + */ +interface ConnectionToolConfigurationService { + + + String OPENFLOWJAVA_TOOLS_SRC_MAIN_RESOURCES = "openflowjava-tools/src/main/resources/"; + String OPENFLOWJAVA_TOOLS_SRC_MAIN_RESOURCES1 = "openflowjava-tools/src/main/resources/"; + String CONFIGURATION_XSD = "configuration.xsd"; + String CONFIGURATION_XML = "configuration.xml"; + String XML_FILE_PATH_WITH_FILE_NAME = OPENFLOWJAVA_TOOLS_SRC_MAIN_RESOURCES + CONFIGURATION_XML; + String XSD_SCHEMA_PATH_WITH_FILE_NAME = OPENFLOWJAVA_TOOLS_SRC_MAIN_RESOURCES1 + CONFIGURATION_XSD; + + /** + * Method to save configuration into XML configuration file + * @param params {@link ConnectionTestTool.Params} + * @param configurationName {@link String} + * @throws JAXBException + * @throws SAXException + */ + void marshallData(ConnectionTestTool.Params params, String configurationName) throws JAXBException, SAXException; + + /** + * Method to load data from XML configuration file. Each configuration has a name. + * @param configurationName {@link String} + * @return parameters + * @throws SAXException + * @throws JAXBException + */ + ConnectionTestTool.Params unMarshallData(String configurationName) throws SAXException, JAXBException; +} diff --git a/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java new file mode 100644 index 00000000..f309a7dd --- /dev/null +++ b/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java @@ -0,0 +1,126 @@ +package org.opendaylight.openflowjava.tools; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import java.io.File; +import java.math.BigInteger; +import java.util.List; + +/** + * @author Jozef Bacigal + * Date: 8.3.2016 + */ +public class ConnectionToolConfigurationServiceImpl implements ConnectionToolConfigurationService { + + private static final Logger LOG = LoggerFactory.getLogger(ConnectionToolConfigurationServiceImpl.class); + + @Override + public void marshallData(ConnectionTestTool.Params params, String configurationName) throws JAXBException, SAXException { + File file = new File(XML_FILE_PATH_WITH_FILE_NAME); + LOG.info("Marshaling configuration data to: {}", XML_FILE_PATH_WITH_FILE_NAME); + + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(new File(XSD_SCHEMA_PATH_WITH_FILE_NAME)); + LOG.info("with schema: {}", XSD_SCHEMA_PATH_WITH_FILE_NAME); + + JAXBContext jaxbContext = JAXBContext.newInstance(Configurations.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + + jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + jaxbMarshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, CONFIGURATION_XSD); + + jaxbMarshaller.setSchema(schema); + + Configurations configurations = new Configurations(); + + List configurationTypes = configurations.getConfiguration(); + + for (ConfigurationType configurationType : this.getSavedConfigurations()) { + configurationTypes.add(configurationType); + } + + ConfigurationType configurationType = new ConfigurationType(); + configurationType.name = configurationName; + + configurationType.controllerIp = params.controllerIP; + configurationType.devicesCount = BigInteger.valueOf(params.deviceCount); + configurationType.freeze = BigInteger.valueOf(params.freeze); + configurationType.port = BigInteger.valueOf(params.port); + configurationType.sleep = params.sleep; + configurationType.ssl = params.ssl; + configurationType.threads = BigInteger.valueOf(params.threads); + configurationType.timeout = BigInteger.valueOf(params.timeout); + + configurationTypes.add(configurationType); + + configurations.setConfiguration(configurationTypes); + jaxbMarshaller.marshal(configurations, file); + + } + + @Override + public ConnectionTestTool.Params unMarshallData(String configurationName) throws SAXException, JAXBException { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(new File(XSD_SCHEMA_PATH_WITH_FILE_NAME)); + LOG.debug("Loading schema from: {}", XSD_SCHEMA_PATH_WITH_FILE_NAME); + + JAXBContext jc = JAXBContext.newInstance(Configurations.class); + + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema(schema); + + Configurations configurations = (Configurations) unmarshaller.unmarshal(new File(XML_FILE_PATH_WITH_FILE_NAME)); + LOG.debug("Configurations ({}) are un-marshaled from {}", configurations.getConfiguration().size(), XML_FILE_PATH_WITH_FILE_NAME); + + boolean foundConfiguration = false; + ConfigurationType configuration = null; + for (ConfigurationType configurationType : configurations.getConfiguration()) { + if (configurationType.getName().equals(configurationName)) { + configuration = configurationType; + foundConfiguration = true; + } + } + ConnectionTestTool.Params params = null; + if (foundConfiguration) { + LOG.info("Configuration {} found, loading parameters.", configurationName); + params = new ConnectionTestTool.Params(); + params.controllerIP = configuration.getControllerIp(); + params.deviceCount = configuration.getDevicesCount().intValue(); + params.freeze = configuration.getFreeze().intValue(); + params.port = configuration.getPort().intValue(); + params.sleep = configuration.getSleep(); + params.ssl = configuration.isSsl(); + params.threads = configuration.getThreads().intValue(); + params.timeout = configuration.getTimeout().intValue(); + } else { + LOG.warn("Configuration {} not found. Using default parameters.", configurationName); + } + + return params; + } + + private List getSavedConfigurations() throws SAXException, JAXBException{ + + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(new File(XSD_SCHEMA_PATH_WITH_FILE_NAME)); + + JAXBContext jc = JAXBContext.newInstance(Configurations.class); + + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema(schema); + + Configurations configurations = (Configurations) unmarshaller.unmarshal(new File(XML_FILE_PATH_WITH_FILE_NAME)); + + return configurations.getConfiguration(); + + } +} diff --git a/openflowjava-tools/src/main/resources/configuration.xml b/openflowjava-tools/src/main/resources/configuration.xml new file mode 100644 index 00000000..55ecd9b8 --- /dev/null +++ b/openflowjava-tools/src/main/resources/configuration.xml @@ -0,0 +1,23 @@ + + + + 127.0.0.1 + 30 + false + 100 + 6653 + 1000 + 2 + 100 + + + 127.0.0.1 + 1 + false + 1 + 6653 + 1000 + 3 + 100 + + diff --git a/openflowjava-tools/src/main/resources/configuration.xsd b/openflowjava-tools/src/main/resources/configuration.xsd new file mode 100644 index 00000000..dcbb49f1 --- /dev/null +++ b/openflowjava-tools/src/main/resources/configuration.xsd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openflowjava-util/pom.xml b/openflowjava-util/pom.xml index 27ffc9bc..c296e5a7 100644 --- a/openflowjava-util/pom.xml +++ b/openflowjava-util/pom.xml @@ -5,11 +5,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent bundle openflowjava-util + + ODL :: openflowjava :: ${project.artifactId} diff --git a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java index f9ed9fb3..5d6869cf 100644 --- a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java @@ -15,6 +15,8 @@ import com.google.common.primitives.UnsignedBytes; import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; +import java.io.IOException; +import java.nio.ByteBuffer; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -134,6 +136,15 @@ public static void updateOFHeaderLength(final ByteBuf out) { out.setShort(EncodeConstants.OFHEADER_LENGTH_INDEX, out.readableBytes()); } + /** + * Write length OF header + * @param out writing buffer + * @param index writing index + */ + public static void updateOFHeaderLength(final ByteBuf out, int index) { + out.setShort(index + EncodeConstants.OFHEADER_LENGTH_INDEX, out.writerIndex() - index); + } + /** * Fills the bitmask from boolean map where key is bit position * @param booleanMap bit to boolean mapping @@ -366,4 +377,12 @@ public static MacAddress readIetfMacAddress(final ByteBuf buf) { buf.readBytes(tmp); return IetfYangUtil.INSTANCE.macAddressFor(tmp); } + + public static byte[] serializeList(final List list) throws IOException{ + ByteBuffer byteBuffer = ByteBuffer.allocate(list.size() * 2); + for (Short aShort : list) { + byteBuffer.putShort(aShort); + } + return byteBuffer.array(); + } } diff --git a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java index 75ada6fb..6e285f95 100644 --- a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java @@ -10,7 +10,6 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeDeserializerKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; @@ -108,14 +107,4 @@ public static ExperimenterIdDeserializerKey createMeterBandDeserializerKey( return new ExperimenterIdDeserializerKey(version, experimenterId, MeterBandExperimenterCase.class); } - /** - * @param version openflow wire version - * @param experimenterId experimenter ID - * @param type experimenter type according to vendor implementation - * @return key instance - */ - public static ExperimenterIdTypeDeserializerKey createBundlePropertyDeserializerKey( - short version, long experimenterId, long type) { - return new ExperimenterIdTypeDeserializerKey(version, experimenterId, type, BundleExperimenterPropertyData.class); - } } \ No newline at end of file diff --git a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java index 24e78deb..ea0a69ce 100755 --- a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java @@ -11,7 +11,6 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeSerializerKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.bundle.properties.bundle.property.bundle.property.entry.bundle.experimenter.property.BundleExperimenterPropertyData; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterMeterBandSubType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; @@ -69,14 +68,4 @@ public static ExperimenterIdSerializerKey createMeter return new ExperimenterIdMeterSubTypeSerializerKey<>(msgVersion, experimenterId, MeterBandExperimenterCase.class, meterSubType); } - /** - * @param msgVersion openflow wire version - * @param experimenterId experimenter ID - * @param type experimenter type according to vendor implementation - * @return key instance - */ - public static ExperimenterIdSerializerKey createBundlePropertySerializerKey( - short msgVersion, long experimenterId, long type) { - return new ExperimenterIdTypeSerializerKey<>(msgVersion, experimenterId, type, BundleExperimenterPropertyData.class); - } } \ No newline at end of file diff --git a/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java index 7113eb06..b7f0f593 100644 --- a/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java +++ b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java @@ -11,16 +11,14 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.UnpooledByteBufAllocator; - +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; @@ -30,7 +28,8 @@ */ public class ByteBufUtilsTest { - private byte[] expected = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, (byte) 0xff}; + private final byte[] EXPECTED = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05, (byte) 0xff}; + private final byte[] EXPECTEDVALUES1AND255 = new byte[]{0x00, 0x01, 0x00, (byte) 0xff}; /** * Test of {@link org.opendaylight.openflowjava.util.ByteBufUtils#hexStringToBytes(String)} @@ -39,7 +38,7 @@ public class ByteBufUtilsTest { public void testHexStringToBytes() { byte[] data = ByteBufUtils.hexStringToBytes("01 02 03 04 05 ff"); - Assert.assertArrayEquals(expected, data); + Assert.assertArrayEquals(EXPECTED, data); } /** @@ -49,7 +48,7 @@ public void testHexStringToBytes() { public void testHexStringToBytes2() { byte[] data = ByteBufUtils.hexStringToBytes("0102030405ff", false); - Assert.assertArrayEquals(expected, data); + Assert.assertArrayEquals(EXPECTED, data); } /** @@ -59,7 +58,7 @@ public void testHexStringToBytes2() { public void testHexStringToByteBuf() { ByteBuf bb = ByteBufUtils.hexStringToByteBuf("01 02 03 04 05 ff"); - Assert.assertArrayEquals(expected, byteBufToByteArray(bb)); + Assert.assertArrayEquals(EXPECTED, byteBufToByteArray(bb)); } /** @@ -70,7 +69,7 @@ public void testHexStringToGivenByteBuf() { ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.buffer(); ByteBufUtils.hexStringToByteBuf("01 02 03 04 05 ff", buffer); - Assert.assertArrayEquals(expected, byteBufToByteArray(buffer)); + Assert.assertArrayEquals(EXPECTED, byteBufToByteArray(buffer)); } private static byte[] byteBufToByteArray(ByteBuf bb) { @@ -437,4 +436,34 @@ public void testReadIpv6Address() { buffer.writeShort(10); ipv4Address = ByteBufUtils.readIpv6Address(buffer2); } + + @Test + public void testSerializeList() throws IOException { + + List shorts = new ArrayList<>(); + shorts.add((short) 1); + shorts.add((short) 255); + + final byte[] bytes = ByteBufUtils.serializeList(shorts); + Assert.assertTrue(bytes.length == shorts.size()*2); + Assert.assertArrayEquals(EXPECTEDVALUES1AND255, bytes); + } + + @Test + public void testUpdateHeader() throws IOException { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeInt(1); + int start = buffer.writerIndex(); + buffer.writeShort(4); + buffer.writeShort(EncodeConstants.EMPTY_LENGTH); + buffer.writeLong(8); + int end = buffer.writerIndex(); + + ByteBufUtils.updateOFHeaderLength(buffer, start); + Assert.assertEquals(buffer.readInt(), 1); + Assert.assertEquals(buffer.readShort(), 4); + Assert.assertEquals(buffer.readShort(), 12); + Assert.assertEquals(buffer.readLong(), 8l); + Assert.assertEquals(buffer.getShort(start + EncodeConstants.OFHEADER_LENGTH_INDEX), end - start); + } } diff --git a/parent/pom.xml b/parent/pom.xml index 00cfc5dc..4238e080 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -4,15 +4,17 @@ org.opendaylight.odlparent odlparent - 1.8.0-SNAPSHOT + 2.0.0 org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT pom - openflowjava + + ODL :: openflowjava :: ${project.artifactId} Openflow protocol library - serializes and deserializes openflow messages + handles connections with openflow devices. @@ -51,13 +53,13 @@ UTF-8 ${project.build.directory}/yang-gen-config - 1.8.0-SNAPSHOT ${project.build.directory}/yang-gen-sal - 0.6.0-SNAPSHOT - 1.5.0-SNAPSHOT - 0.10.0-SNAPSHOT - 1.1.0-SNAPSHOT + 0.7.0-SNAPSHOT + 1.6.0-SNAPSHOT + 0.11.0-SNAPSHOT + 1.2.0-SNAPSHOT + 0.7.0 @@ -90,6 +92,11 @@ import pom + + net.sourceforge.argparse4j + argparse4j + ${argparse4j.version} + @@ -98,11 +105,6 @@ org.apache.maven.plugins maven-compiler-plugin - true - - 1.7 - 1.7 - maven-source-plugin @@ -129,7 +131,7 @@ org.apache.maven.plugins - maven-checkstyle-plugin + maven-checkstyle-plugin ${checkstyle.version} false @@ -158,6 +160,21 @@ org.codehaus.mojo build-helper-maven-plugin + + + add-yang-sources + generate-sources + + add-source + + + + ${jmxGeneratorPath} + ${salGeneratorPath} + + + + @@ -250,19 +267,6 @@ - - - org.opendaylight.yangtools - yang-maven-plugin - [0.5,) - - generate-sources - - - - - - org.codehaus.groovy.maven diff --git a/pom.xml b/pom.xml index 0ed98352..e3eda8b0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT parent diff --git a/simple-client/pom.xml b/simple-client/pom.xml index 5eb462b5..b399646e 100644 --- a/simple-client/pom.xml +++ b/simple-client/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.9.0-SNAPSHOT + 0.10.0-SNAPSHOT ../parent simple-client bundle - Openflow Protocol Simple Client + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD @@ -45,5 +47,9 @@ org.slf4j slf4j-log4j12 + + net.sourceforge.argparse4j + argparse4j + diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java new file mode 100644 index 00000000..67142e38 --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016 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.openflowjava.protocol.impl.clients; + +import java.net.InetAddress; +import java.util.concurrent.Callable; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.SettableFuture; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import org.slf4j.LoggerFactory; + + +/** + * Callable client class, inspired by SimpleClient class + * Simulating device/switch connected to controller + * @author Jozef Bacigal + * Date: 4.3.2016. + */ +public class CallableClient implements Callable, OFClient { + + private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(CallableClient.class); + + private int port = 6653; + private boolean securedClient = false; + private InetAddress ipAddress = null; + private String name = "Empty name"; + + private final EventLoopGroup workerGroup; + private SettableFuture isOnlineFuture; + private SettableFuture scenarioDone; + private ScenarioHandler scenarioHandler = null; + private Bootstrap bootstrap = null; + + public CallableClient( + final int port, + final boolean securedClient, + final InetAddress ipAddress, + final String name, + final ScenarioHandler scenarioHandler, + final Bootstrap bootstrap, + final EventLoopGroup eventExecutors) { + + Preconditions.checkNotNull(ipAddress, "IP address cannot be null"); + Preconditions.checkNotNull(scenarioHandler, "Scenario handler cannot be null"); + this.port = port; + this.securedClient = securedClient; + this.ipAddress = ipAddress; + this.workerGroup = eventExecutors; + this.bootstrap = bootstrap; + this.name = name; + this.scenarioHandler = scenarioHandler; + } + + @Override + public SettableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + @Override + public SettableFuture getScenarioDone() { + return scenarioDone; + } + + @Override + public void setScenarioHandler(final ScenarioHandler scenario) { + this.scenarioHandler = scenario; + } + + @Override + public void setSecuredClient(final boolean securedClient) { + this.securedClient = securedClient; + } + + + @Override + public Boolean call() throws Exception { + Preconditions.checkNotNull(bootstrap); + Preconditions.checkNotNull(workerGroup); + LOG.info("Switch {} trying connect to controller", this.name); + SimpleClientInitializer clientInitializer = new SimpleClientInitializer(isOnlineFuture, securedClient); + clientInitializer.setScenario(scenarioHandler); + try { + bootstrap.group(workerGroup) + .channel(NioSocketChannel.class) + .handler(clientInitializer); + + bootstrap.connect(ipAddress, port).sync(); + synchronized (scenarioHandler) { + LOG.debug("WAITING FOR SCENARIO"); + while (!scenarioHandler.isScenarioFinished()) { + scenarioHandler.wait(); + } + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); + return false; + } + if (scenarioHandler.isFinishedOK()) { + LOG.info("Device {} finished scenario OK", this.name); + } else { + LOG.error("Device {} finished scenario with error", this.name); + } + return scenarioHandler.isFinishedOK(); + + } + + @Override + public void run() { + throw new UnsupportedOperationException(); + } +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java index 9b46d6c0..64217d8e 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java @@ -64,7 +64,7 @@ private ClientSslContextFactory() { } /** - * @return cliencontext + * @return client context */ public static SSLContext getClientContext() { return CLIENT_CONTEXT; diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java new file mode 100644 index 00000000..ff83c6bf --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java @@ -0,0 +1,41 @@ + +package org.opendaylight.openflowjava.protocol.impl.clients; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for eventType. + */ +@XmlType(name = "eventType") +@XmlEnum +public enum EventType { + + @XmlEnumValue("sleepEvent") + SLEEP_EVENT("sleepEvent"), + @XmlEnumValue("waitForMessageEvent") + WAIT_FOR_MESSAGE_EVENT("waitForMessageEvent"), + @XmlEnumValue("sendEvent") + SEND_EVENT("sendEvent"); + private final String value; + + EventType(String v) { + value = v; + } + + public String value() { + return value; + } + + public static EventType fromValue(String v) { + for (EventType c: EventType.values()) { + if (c.value.equals(v)) { + return c; + } + } + throw new IllegalArgumentException(v); + } + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java new file mode 100644 index 00000000..f11890ba --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java @@ -0,0 +1,80 @@ + +package org.opendaylight.openflowjava.protocol.impl.clients; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for scenarioType complex type. + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "scenario", propOrder = { + "step" +}) +public class Scenario { + + @XmlElement(required = true) + protected List step; + @XmlAttribute(name = "name", required = true) + protected String name; + + /** + * Gets the value of the step property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the step property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getStep().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Step } + * + * + */ + public List getStep() { + if (step == null) { + step = new ArrayList<>(); + } + return this.step; + } + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java index 5b4e669a..3e01cfa5 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java @@ -8,10 +8,15 @@ package org.opendaylight.openflowjava.protocol.impl.clients; +import java.io.IOException; import java.util.ArrayDeque; import java.util.Deque; +import java.util.Map; import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.xml.sax.SAXException; + +import javax.xml.bind.JAXBException; /** * Class for providing prepared handshake scenario @@ -29,8 +34,8 @@ private ScenarioFactory() { *

    *
  1. hello sent - 00000001 *
  2. hello waiting - 00000002 - *
  3. featuresrequest waiting - 00000003 - *
  4. featuresreply sent - 00000003 + *
  5. features request waiting - 00000003 + *
  6. features reply sent - 00000003 *
* @return stack filled with Handshake messages */ @@ -44,13 +49,48 @@ public static Deque createHandshakeScenario() { return stack; } + /** + * Creates stack with handshake needed messages. XID of messages: + *
    + *
  1. hello sent - 00000001 + *
  2. hello waiting - 00000021 + *
  3. features request waiting - 00000002 + *
  4. features reply sent - 00000002 + *
+ * @return stack filled with Handshake messages + */ + public static Deque createHandshakeScenarioWithBarrier() { + Deque stack = new ArrayDeque<>(); + stack.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 00 00 08 00 00 00 01"))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 00 00 10 00 00 00 15 00 01 00 08 00 00 00 12"))); //Hello message 21 + stack.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 05 00 08 00 00 00 02"))); + stack.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 06 00 20 00 00 00 02 " + + "00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 00 01 02 03 00 01 02 03"))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 14 00 08 00 00 00 00"))); //Barrier request + stack.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 15 00 08 00 00 00 04"))); //Barrier reply + return stack; + } + + /** + * Creates stack from XML file + * @return stack filled with Handshake messages + */ + public static Deque getScenarioFromXml(String scenarioName, String scenarioFile) throws JAXBException, SAXException, IOException { + ScenarioService scenarioService = new ScenarioServiceImpl(scenarioFile); + Deque stack = new ArrayDeque<>(); + for (Map.Entry clientEvent : scenarioService.getEventsFromScenario(scenarioService.unMarshallData(scenarioName)).entrySet()) { + stack.addFirst(clientEvent.getValue()); + } + return stack; + } + /** * Creates stack with handshake needed messages. XID of messages: *
    *
  1. hello sent - 00000001 *
  2. hello waiting - 00000002 - *
  3. featuresrequest waiting - 00000003 - *
  4. featuresreply sent - 00000003 + *
  5. features request waiting - 00000003 + *
  6. features reply sent - 00000003 *
* @param auxiliaryId auxiliaryId wanted in featuresReply message * @return stack filled with Handshake messages (featuresReply with auxiliaryId set) diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java index 44abb36d..88fd9b64 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java @@ -27,20 +27,30 @@ public class ScenarioHandler extends Thread { private static final Logger LOG = LoggerFactory.getLogger(ScenarioHandler.class); private Deque scenario; - private BlockingQueue ofMsg; + private final BlockingQueue ofMsg; private ChannelHandlerContext ctx; private int eventNumber; private boolean scenarioFinished = false; + private int freeze = 2; + private long sleepBetweenTries = 100L; + private boolean finishedOK = true; /** * - * @param scenario + * @param scenario {@link Deque} */ public ScenarioHandler(Deque scenario) { this.scenario = scenario; ofMsg = new LinkedBlockingQueue<>(); } + public ScenarioHandler(Deque scenario, int freeze, long sleepBetweenTries){ + this.scenario = scenario; + ofMsg = new LinkedBlockingQueue<>(); + this.sleepBetweenTries = sleepBetweenTries; + this.freeze = freeze; + } + @Override public void run() { int freezeCounter = 0; @@ -62,18 +72,22 @@ public void run() { event.setCtx(ctx); } if (peek.eventExecuted()) { + LOG.info("Scenario step finished OK, moving to next step."); scenario.removeLast(); eventNumber++; freezeCounter = 0; + finishedOK = true; } else { freezeCounter++; } - if (freezeCounter > 2) { + if (freezeCounter > freeze) { LOG.warn("Scenario frozen: {}", freezeCounter); + LOG.warn("Scenario step not finished NOT OK!", freezeCounter); + this.finishedOK = false; break; } try { - sleep(100); + sleep(sleepBetweenTries); } catch (InterruptedException e) { LOG.error(e.getMessage(), e); } @@ -126,4 +140,8 @@ public void addOfMsg(byte[] message) { public boolean isScenarioFinished() { return scenarioFinished; } + + public boolean isFinishedOK() { + return finishedOK; + } } diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java new file mode 100644 index 00000000..0221acfc --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java @@ -0,0 +1,33 @@ +package org.opendaylight.openflowjava.protocol.impl.clients; + +import org.xml.sax.SAXException; + +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.util.SortedMap; + +/** + * + * @author Jozef Bacigal + * Date: 8.3.2016 + */ +interface ScenarioService { + + String SIMPLE_CLIENT_SRC_MAIN_RESOURCES = "simple-client/src/main/resources/"; + String SIMPLE_CLIENT_SRC_MAIN_RESOURCES1 = "simple-client/src/main/resources/"; + String SCENARIO_XSD = "scenario.xsd"; + String SCENARIO_XML = "scenario.xml"; + String XSD_SCHEMA_PATH_WITH_FILE_NAME = SIMPLE_CLIENT_SRC_MAIN_RESOURCES1 + SCENARIO_XSD; + + /** + * Method to load data from XML configuration file. Each configuration has a name. + * @param scenarioName {@link String} + * @return scenarios + * @throws SAXException + * @throws JAXBException + */ + Scenario unMarshallData(String scenarioName) throws SAXException, JAXBException; + + SortedMap getEventsFromScenario(Scenario scenario) throws IOException; + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java new file mode 100644 index 00000000..9e1df907 --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java @@ -0,0 +1,81 @@ +package org.opendaylight.openflowjava.protocol.impl.clients; + +import com.google.common.base.Preconditions; +import java.io.File; +import java.io.IOException; +import java.util.SortedMap; +import java.util.TreeMap; +import javax.xml.XMLConstants; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +/** + * @author Jozef Bacigal + * Date: 9.3.2016 + */ +public class ScenarioServiceImpl implements ScenarioService { + + private static final Logger LOG = LoggerFactory.getLogger(ScenarioServiceImpl.class); + + private String XML_FILE_PATH_WITH_FILE_NAME = SIMPLE_CLIENT_SRC_MAIN_RESOURCES + SCENARIO_XML; + + public ScenarioServiceImpl(String scenarioFile){ + if (null != scenarioFile && !scenarioFile.isEmpty()) { + this.XML_FILE_PATH_WITH_FILE_NAME = scenarioFile; + } + } + + @Override + public Scenario unMarshallData(String scenarioName) throws SAXException, JAXBException { + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(new File(XSD_SCHEMA_PATH_WITH_FILE_NAME)); + LOG.debug("Loading schema from: {}", XSD_SCHEMA_PATH_WITH_FILE_NAME); + + JAXBContext jc = JAXBContext.newInstance(Scenarios.class); + + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema(schema); + + Scenarios scenarios = (Scenarios) unmarshaller.unmarshal(new File(XML_FILE_PATH_WITH_FILE_NAME)); + LOG.debug("Scenarios ({}) are un-marshaled from {}", scenarios.getScenario().size(), XML_FILE_PATH_WITH_FILE_NAME); + + boolean foundConfiguration = false; + Scenario scenarioType = null; + for (Scenario scenario : scenarios.getScenario()) { + if (scenario.getName().equals(scenarioName)) { + scenarioType = scenario; + foundConfiguration = true; + } + } + if (!foundConfiguration) { + LOG.warn("Scenario {} not found.", scenarioName); + } else { + LOG.info("Scenario {} found with {} steps.", scenarioName, scenarioType.getStep().size()); + } + return scenarioType; + } + + @Override + public SortedMap getEventsFromScenario(Scenario scenario) throws IOException { + Preconditions.checkNotNull(scenario, "Scenario name not found. Check XML file, scenario name or directories."); + SortedMap events = new TreeMap<>(); + Integer counter = 0; + for (Step step : scenario.getStep()) { + LOG.debug("Step {}: {}, type {}, bytes {}", step.getOrder(), step.getName(), step.getEvent().value(), step.getBytes().toArray()); + switch (step.getEvent()) { + case SLEEP_EVENT: events.put(counter++, new SleepEvent(1000)); break; + case SEND_EVENT: events.put(counter++, new SendEvent(ByteBufUtils.serializeList(step.getBytes()))); break; + case WAIT_FOR_MESSAGE_EVENT: events.put(counter++, new WaitForMessageEvent(ByteBufUtils.serializeList(step.getBytes()))); break; + } + } + return events; + } + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java new file mode 100644 index 00000000..5fcaa80e --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java @@ -0,0 +1,51 @@ + +package org.opendaylight.openflowjava.protocol.impl.clients; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for anonymous complex type. + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "", propOrder = { + "scenario" +}) +@XmlRootElement(name = "scenarios") +public class Scenarios { + + @XmlElement(required = true) + protected List scenario; + + /** + * Gets the value of the scenario property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the scenario property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getScenario().add(newItem);
+     * 
+ *

+ * Objects of the following type(s) are allowed in the list + * {@link Scenario } + */ + public List getScenario() { + if (scenario == null) { + scenario = new ArrayList<>(); + } + return this.scenario; + } + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java index 9318d231..98934f08 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java @@ -31,9 +31,7 @@ public class SendEvent implements ClientEvent { */ public SendEvent(byte[] msgToSend) { this.msgToSend = new byte[msgToSend.length]; - for (int i = 0; i < msgToSend.length; i++) { - this.msgToSend[i] = msgToSend[i]; - } + System.arraycopy(msgToSend, 0, this.msgToSend, 0, msgToSend.length); } @Override diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java index 98a6e1ff..21afc08b 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java @@ -25,7 +25,7 @@ public class SimpleClientInitializer extends ChannelInitializer { private SettableFuture isOnlineFuture; - private boolean secured; + private final boolean secured; private ScenarioHandler scenarioHandler; /** diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java new file mode 100644 index 00000000..82e15ab5 --- /dev/null +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java @@ -0,0 +1,108 @@ + +package org.opendaylight.openflowjava.protocol.impl.clients; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlList; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for stepType complex type. + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "step", propOrder = { + "order", + "name", + "event", + "bytes" +}) +public class Step { + + protected short order; + @XmlElement(required = true) + protected String name; + @XmlElement(required = true) + @XmlSchemaType(name = "string") + protected EventType event; + @XmlList + @XmlElement(type = Short.class) + @XmlSchemaType(name = "anySimpleType") + protected List bytes; + + /** + * Gets the value of the order property. + */ + public short getOrder() { + return order; + } + + /** + * Sets the value of the order property. + */ + public void setOrder(short value) { + this.order = value; + } + + /** + * Gets the value of the name property. + * @return possible object is {@link String } + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * @param value allowed object is {@link String } + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the event property. + * @return possible object is {@link EventType } + */ + public EventType getEvent() { + return event; + } + + /** + * Sets the value of the event property. + * @param value allowed object is {@link EventType } + */ + public void setEvent(EventType value) { + this.event = value; + } + + /** + * Gets the value of the bytes property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the bytes property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getBytes().add(newItem);
+     * 
+ *

+ * Objects of the following type(s) are allowed in the list + * {@link Short } + */ + public List getBytes() { + if (bytes == null) { + bytes = new ArrayList<>(); + } + return this.bytes; + } + +} diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java index 59228e36..0854a279 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java @@ -29,9 +29,7 @@ public class WaitForMessageEvent implements ClientEvent { */ public WaitForMessageEvent(byte[] headerExpected) { this.headerExpected = new byte[headerExpected.length]; - for (int i = 0; i < headerExpected.length; i++) { - this.headerExpected[i] = headerExpected[i]; - } + System.arraycopy(headerExpected, 0, this.headerExpected, 0, headerExpected.length); } @Override @@ -54,9 +52,9 @@ public boolean eventExecuted() { * @param headerReceived header (first 8 bytes) of expected message */ public void setHeaderReceived(byte[] headerReceived) { - this.headerReceived = new byte[headerReceived.length]; - for (int i = 0; i < headerReceived.length; i++) { - this.headerReceived[i] = headerReceived[i]; + if (headerReceived != null) { + this.headerReceived = new byte[headerReceived.length]; + System.arraycopy(headerReceived, 0, this.headerReceived, 0, headerReceived.length); } } } diff --git a/simple-client/src/main/resources/scenario.xml b/simple-client/src/main/resources/scenario.xml new file mode 100644 index 00000000..a446cadb --- /dev/null +++ b/simple-client/src/main/resources/scenario.xml @@ -0,0 +1,42 @@ + + + + + 1 + send Hello + sendEvent + 04 00 00 08 00 00 00 01 + + + 2 + wait for Hello_21 + waitForMessageEvent + 04 00 00 10 00 00 00 15 00 01 00 08 00 00 00 12 + + + 3 + wait for features request + waitForMessageEvent + 04 05 00 08 00 00 00 02 + + + 4 + features reply + sendEvent + 04 06 00 20 00 00 00 02 00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 00 01 02 03 00 01 02 03 + + + 5 + wait for barrier + waitForMessageEvent + 04 14 00 08 00 00 00 00 + + + 6 + barrier reply + sendEvent + 04 15 00 08 00 00 00 04 + + + + diff --git a/simple-client/src/main/resources/scenario.xsd b/simple-client/src/main/resources/scenario.xsd new file mode 100644 index 00000000..59727ca3 --- /dev/null +++ b/simple-client/src/main/resources/scenario.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file