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 eaa3779f..54204e90 100644 --- a/artifacts/pom.xml +++ b/artifacts/pom.xml @@ -10,10 +10,21 @@ 4.0.0 + + + org.opendaylight.odlparent + odlparent-lite + 2.0.0 + + + org.opendaylight.openflowjava openflowjava-artifacts - 0.7.0-SNAPSHOT + 0.10.0-SNAPSHOT pom + + ODL :: openflowjava :: ${project.artifactId} @@ -34,6 +45,20 @@ test-jar test + + org.opendaylight.openflowjava + openflowjava-blueprint-config + ${project.version} + xml + config + + + org.opendaylight.openflowjava + openflowjava-blueprint-config + ${project.version} + xml + legacyConfig + ${project.groupId} openflow-protocol-spi @@ -72,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 4cc091be..44633fb4 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -3,159 +3,23 @@ 4.0.0 org.opendaylight.odlparent - features-parent - 1.6.0-SNAPSHOT + odlparent-lite + 2.0.0 org.opendaylight.openflowjava - features-openflowjava - 0.7.0-SNAPSHOT - jar - - - 0.4.0-SNAPSHOT - 1.3.0-SNAPSHOT - 2.0.0-SNAPSHOT - 1.3.0-SNAPSHOT - 0.8.0-SNAPSHOT - - - - - - - org.opendaylight.openflowjava - openflowjava-artifacts - ${project.version} - import - pom - - - - - org.opendaylight.odlparent - odlparent-artifacts - 1.6.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-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 - - + 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 111100a6..00000000 --- a/features/src/main/features/features.xml +++ /dev/null @@ -1,27 +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-config/${project.version}/xml/configstats - - diff --git a/openflow-protocol-api/pom.xml b/openflow-protocol-api/pom.xml index efaa892a..5a2777d0 100644 --- a/openflow-protocol-api/pom.xml +++ b/openflow-protocol-api/pom.xml @@ -4,22 +4,24 @@ org.opendaylight.mdsal binding-parent - 0.8.0-SNAPSHOT + 0.11.0-SNAPSHOT org.opendaylight.openflowjava openflow-protocol-api - 0.7.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.0.0-SNAPSHOT - 0.8.0-SNAPSHOT + 2.3.0-SNAPSHOT + 0.11.0-SNAPSHOT @@ -54,11 +56,11 @@ org.opendaylight.mdsal.model - ietf-inet-types + ietf-inet-types-2013-07-15 org.opendaylight.mdsal.model - ietf-yang-types + ietf-yang-types-20130715 org.opendaylight.mdsal.model @@ -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/ConnectionConfiguration.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java index 310e0a5a..578e97b5 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java @@ -50,4 +50,9 @@ public interface ConnectionConfiguration { * @return thread numbers for TcpHandler's eventloopGroups */ ThreadConfiguration getThreadConfiguration(); + + /** + * @return boolean value for usability of Barrier + */ + boolean useBarrier(); } 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/connection/TlsConfiguration.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java index 6676dd02..f5a71a8c 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java @@ -8,6 +8,8 @@ package org.opendaylight.openflowjava.protocol.api.connection; +import java.util.List; + import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; @@ -62,4 +64,9 @@ public interface TlsConfiguration { * @return password protecting specified truststore */ String getTruststorePassword(); + + /** + * @return list of cipher suites for TLS connection + */ + List getCipherSuites(); } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java index 78a6c6b8..2a290140 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java @@ -8,6 +8,8 @@ package org.opendaylight.openflowjava.protocol.api.connection; +import java.util.List; + import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; @@ -23,6 +25,7 @@ public class TlsConfigurationImpl implements TlsConfiguration { private String keyStore; private PathType keystorePathType; private PathType truststorePathType; + private List cipherSuites; /** * Default constructor @@ -35,13 +38,15 @@ public class TlsConfigurationImpl implements TlsConfiguration { */ public TlsConfigurationImpl(KeystoreType trustStoreType, String trustStore, PathType trustStorePathType, KeystoreType keyStoreType, - String keyStore, PathType keyStorePathType) { + String keyStore, PathType keyStorePathType, + List cipherSuites) { this.trustStoreType = trustStoreType; this.trustStore = trustStore; this.truststorePathType = trustStorePathType; this.keyStoreType = keyStoreType; this.keyStore = keyStore; this.keystorePathType = keyStorePathType; + this.cipherSuites = cipherSuites; } @Override @@ -88,4 +93,9 @@ public String getCertificatePassword() { public String getTruststorePassword() { return "opendaylight"; } + + @Override + public List getCipherSuites() { + return cipherSuites; + } } 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 old mode 100644 new mode 100755 index 13162491..366cd3ab --- 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 @@ -9,10 +9,12 @@ package org.opendaylight.openflowjava.protocol.api.extensibility; import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; 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; @@ -33,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 @@ -92,10 +109,21 @@ void registerMultipartRequestTFSerializer(ExperimenterIdSerializerKey key, OFSerializer serializer); + + /** + * Registers meter band serializer (used in meter-mod messages) + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerMeterBandSerializer(ExperimenterIdMeterSubTypeSerializerKey key, + OFSerializer serializer); } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java index 8f66900d..ec2cf3e1 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java @@ -13,10 +13,8 @@ /** * @author michal.polkorab - * */ -public class ExperimenterIdDeserializerKey extends MessageCodeKey - implements ExperimenterDeserializerKey { +public class ExperimenterIdDeserializerKey extends MessageCodeKey implements ExperimenterDeserializerKey { private long experimenterId; @@ -26,8 +24,8 @@ public class ExperimenterIdDeserializerKey extends MessageCodeKey * @param experimenterId experimenter / vendor ID * @param objectClass class of created object */ - public ExperimenterIdDeserializerKey(short version, - long experimenterId, Class objectClass) { + public ExperimenterIdDeserializerKey(final short version, final long experimenterId, + final Class objectClass) { super(version, EncodeConstants.EXPERIMENTER_VALUE, objectClass); this.experimenterId = experimenterId; } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java new file mode 100755 index 00000000..f568a028 --- /dev/null +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 ZTE, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.api.keys; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterMeterBandSubType; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * Created by hyy on 2016/9/8. + */ +public class ExperimenterIdMeterSubTypeSerializerKey extends ExperimenterIdSerializerKey { + + private Class meterSubType; + + /** + * @param msgVersion protocol wire version + * @param experimenterId experimenter / vendor ID + * @param objectClass class of object to be serialized + * @param meterSubType vendor defined subtype + */ + public ExperimenterIdMeterSubTypeSerializerKey(short msgVersion, long experimenterId, + Class objectClass, Class meterSubType) { + super(msgVersion, experimenterId, objectClass); + this.meterSubType = meterSubType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((meterSubType == null) ? 0 : meterSubType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ExperimenterIdMeterSubTypeSerializerKey other = (ExperimenterIdMeterSubTypeSerializerKey) obj; + if (meterSubType == null) { + if (other.meterSubType != null) { + return false; + } + } else if (!meterSubType.equals(other.meterSubType)) { + return false; + } + return true; + } + +} diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java index cb88b1ad..c956feb0 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java @@ -18,14 +18,15 @@ public class ExperimenterIdTypeDeserializerKey extends ExperimenterIdDeserialize private long type; /** - * @param msgVersion protocol wire version + * @param type of target experimenter object + * @param version protocol wire version * @param experimenterId experimenter / vendor ID * @param type data type according to vendor implementation * @param objectClass class of object to be serialized */ - public ExperimenterIdTypeDeserializerKey(short msgVersion, - long experimenterId, long type, Class objectClass) { - super(msgVersion, experimenterId, objectClass); + public ExperimenterIdTypeDeserializerKey(final short version, final long experimenterId, + final long type, Class objectClass) { + super(version, experimenterId, objectClass); this.type = type; } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java index 6597c19a..566b3623 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java @@ -28,6 +28,14 @@ public MessageCodeKey(short version, int value, Class clazz) { this.clazz = clazz; } + public int getMsgType() { + return this.msgType; + } + + public Class getClazz() { + return this.clazz; + } + @Override public int hashCode() { final int prime = 31; 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 82a09282..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 @@ -9,7 +9,7 @@ package org.opendaylight.openflowjava.protocol.api.util; /** - * Stores common constants + * Stores common constants. * @author michal.polkorab */ public abstract class EncodeConstants { @@ -20,6 +20,14 @@ public abstract class EncodeConstants { public static final byte OF10_VERSION_ID = 0x01; /** OpenFlow v1.3 wire protocol number */ public static final byte OF13_VERSION_ID = 0x04; + /** OpenFlow v1.4 wire protocol number */ + public static final byte OF14_VERSION_ID = 0x05; + /** OpenFlow v1.5 wire protocol number */ + public static final byte OF15_VERSION_ID = 0x06; + /** OpenFlow Hello message type value */ + public static final byte OF_HELLO_MESSAGE_TYPE_VALUE = 0; + /** OpenFlow PacketIn message type value */ + public static final byte OF_PACKETIN_MESSAGE_TYPE_VALUE = 10; /** Index of length in Openflow header */ public static final int OFHEADER_LENGTH_INDEX = 2; /** Size of Openflow header */ @@ -52,11 +60,14 @@ public abstract class EncodeConstants { /** Common experimenter value */ public static final int EXPERIMENTER_VALUE = 0xFFFF; - /** OF v1.0 maximal port name length */ public static final byte MAX_PORT_NAME_LENGTH = 16; - /** OF v1.3 lenght of experimenter_ids - see Multipart TableFeatures (properties) message */ - public static final byte EXPERIMENTER_IDS_LENGTH = 8; + + /** ONF Approved Extensions Constants */ + /** Experimenter ID of ONF approved extensions */ + public static final long ONF_EXPERIMENTER_ID = 0x4F4E4600; + /** ONFOXM_ET_TCP_FLAGS value */ + public static final int ONFOXM_ET_TCP_FLAGS = 42; private EncodeConstants() { //not called diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java index 3768f2f5..e47b70d6 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java @@ -8,9 +8,8 @@ package org.opendaylight.openflowjava.protocol.api.util; /** - * Stores oxm_match constants + * Stores oxm_match constants. * @author michal.polkorab - * */ public abstract class OxmMatchConstants { diff --git a/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang b/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang new file mode 100644 index 00000000..29a20351 --- /dev/null +++ b/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang @@ -0,0 +1,32 @@ +module openflow-approved-extensions { + namespace "urn:opendaylight:openflow:approved:extensions"; + prefix "ofext"; + + import yang-ext {prefix ext;} + import openflow-extensible-match {prefix oxm;} + import openflow-augments {prefix aug;} + + revision "2016-08-02" { + description "Openflow approved extensions definition"; + } + + //ONF Approved OpenFlow Extensions + // Extension 109 - TCP FLAGS + identity tcp_flags { + base oxm:match-field; + description "TCP flags from the TCP header"; + } + + augment "/oxm:oxm-container/oxm:match-entry-value/aug:experimenter-id-case" { + ext:augment-identifier "tcp-flags-container"; + container tcp-flags { + leaf flags { + type uint16; + } + leaf mask { + type binary; + } + } + } + +} \ No newline at end of file diff --git a/openflow-protocol-api/src/main/yang/openflow-augments.yang b/openflow-protocol-api/src/main/yang/openflow-augments.yang old mode 100644 new mode 100755 index e5be7e56..4a60c37e --- a/openflow-protocol-api/src/main/yang/openflow-augments.yang +++ b/openflow-protocol-api/src/main/yang/openflow-augments.yang @@ -127,5 +127,10 @@ leaf experimenter { type oft:experimenter-id; } + leaf sub-type { + type identityref { + base oft:experimenter-meter-band-sub-type; + } + } } } diff --git a/openflow-protocol-api/src/main/yang/openflow-types.yang b/openflow-protocol-api/src/main/yang/openflow-types.yang old mode 100644 new mode 100755 index 251a845e..7d11bafa --- a/openflow-protocol-api/src/main/yang/openflow-types.yang +++ b/openflow-protocol-api/src/main/yang/openflow-types.yang @@ -206,6 +206,10 @@ description "Base identity for action types"; } + identity experimenter-meter-band-sub-type { + description "The base identity for vendor's meter bands."; + } + typedef metadata { type binary; } diff --git a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java index f71d2302..be52a188 100644 --- a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java @@ -10,10 +10,14 @@ import static org.junit.Assert.*; +import java.util.List; + import org.junit.Test; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; +import com.google.common.collect.Lists; + /** * @author michal.polkorab * @@ -25,8 +29,9 @@ public class TlsConfigurationImplTest { */ @Test public void test() { + List cipherSuites = Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256"); TlsConfigurationImpl config = new TlsConfigurationImpl(KeystoreType.JKS, - "user/dir", PathType.CLASSPATH, KeystoreType.PKCS12, "/var/lib", PathType.PATH); + "user/dir", PathType.CLASSPATH, KeystoreType.PKCS12, "/var/lib", PathType.PATH, cipherSuites); assertEquals("Wrong keystore location", "/var/lib", config.getTlsKeystore()); assertEquals("Wrong truststore location", "user/dir", config.getTlsTruststore()); assertEquals("Wrong keystore type", KeystoreType.PKCS12, config.getTlsKeystoreType()); @@ -36,5 +41,6 @@ public void test() { assertEquals("Wrong certificate password", "opendaylight", config.getCertificatePassword()); assertEquals("Wrong keystore password", "opendaylight", config.getKeystorePassword()); assertEquals("Wrong truststore password", "opendaylight", config.getTruststorePassword()); + assertEquals("Wrong cipher suites", cipherSuites, config.getCipherSuites()); } } \ No newline at end of file diff --git a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java index c23d4b3c..d2aefedb 100644 --- a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2014 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.keys; import org.junit.Assert; 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 fae2c30b..62c2ddd3 100644 --- a/openflow-protocol-impl/pom.xml +++ b/openflow-protocol-impl/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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 @@ -74,7 +76,7 @@ org.opendaylight.mdsal maven-sal-api-gen-plugin - ${yangtools.version} + ${mdsal.model.version} jar @@ -144,11 +146,17 @@ org.mockito - mockito-all + mockito-core org.opendaylight.controller config-api + + io.netty + netty-transport-native-epoll + + linux-x86_64 + diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java index 042d4640..414f2c25 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java @@ -24,17 +24,19 @@ public class ChannelInitializerFactory { private SerializationFactory serializationFactory; private TlsConfiguration tlsConfig; private SwitchConnectionHandler switchConnectionHandler; + private boolean useBarrier; /** * @return PublishingChannelInitializer that initializes new channels */ public TcpChannelInitializer createPublishingChannelInitializer() { - TcpChannelInitializer initializer = new TcpChannelInitializer(); + final TcpChannelInitializer initializer = new TcpChannelInitializer(); initializer.setSwitchIdleTimeout(switchIdleTimeOut); initializer.setDeserializationFactory(deserializationFactory); initializer.setSerializationFactory(serializationFactory); initializer.setTlsConfiguration(tlsConfig); initializer.setSwitchConnectionHandler(switchConnectionHandler); + initializer.setUseBarrier(useBarrier); return initializer; } @@ -42,7 +44,7 @@ public TcpChannelInitializer createPublishingChannelInitializer() { * @return PublishingChannelInitializer that initializes new channels */ public UdpChannelInitializer createUdpChannelInitializer() { - UdpChannelInitializer initializer = new UdpChannelInitializer(); + final UdpChannelInitializer initializer = new UdpChannelInitializer(); initializer.setSwitchIdleTimeout(switchIdleTimeOut); initializer.setDeserializationFactory(deserializationFactory); initializer.setSerializationFactory(serializationFactory); @@ -53,35 +55,42 @@ public UdpChannelInitializer createUdpChannelInitializer() { /** * @param switchIdleTimeOut */ - public void setSwitchIdleTimeout(long switchIdleTimeOut) { + public void setSwitchIdleTimeout(final long switchIdleTimeOut) { this.switchIdleTimeOut = switchIdleTimeOut; } /** * @param deserializationFactory */ - public void setDeserializationFactory(DeserializationFactory deserializationFactory) { + public void setDeserializationFactory(final DeserializationFactory deserializationFactory) { this.deserializationFactory = deserializationFactory; } /** * @param serializationFactory */ - public void setSerializationFactory(SerializationFactory serializationFactory) { + public void setSerializationFactory(final SerializationFactory serializationFactory) { this.serializationFactory = serializationFactory; } /** * @param tlsConfig */ - public void setTlsConfig(TlsConfiguration tlsConfig) { + public void setTlsConfig(final TlsConfiguration tlsConfig) { this.tlsConfig = tlsConfig; } /** * @param switchConnectionHandler */ - public void setSwitchConnectionHandler(SwitchConnectionHandler switchConnectionHandler) { + public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) { this.switchConnectionHandler = switchConnectionHandler; } + + /** + * @param useBarrier + */ + public void setUseBarrier(final boolean useBarrier) { + this.useBarrier = useBarrier; + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java index 4959edaa..1e95c65c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2015 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.core; /** diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java index e0a013c1..b0fee5c3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java @@ -8,9 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.core; +import com.google.common.base.Preconditions; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; - import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl; import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder; @@ -18,8 +18,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; - /** * Holds reference to {@link ConnectionAdapterImpl} and passes messages for further processing. * Also informs on switch disconnection. @@ -27,17 +25,16 @@ */ public class DelegatingInboundHandler extends ChannelInboundHandlerAdapter { - private static final Logger LOGGER = LoggerFactory.getLogger(DelegatingInboundHandler.class); - + private static final Logger LOG = LoggerFactory.getLogger(DelegatingInboundHandler.class); private final MessageConsumer consumer; private boolean inactiveMessageSent = false; /** - * Constructs class + creates and sets MessageConsumer + * Constructs class + creates and sets MessageConsumer. * @param connectionAdapter reference for adapter communicating with upper layers outside library */ public DelegatingInboundHandler(final MessageConsumer connectionAdapter) { - LOGGER.trace("Creating DelegatingInboundHandler"); + LOG.trace("Creating DelegatingInboundHandler"); consumer = Preconditions.checkNotNull(connectionAdapter); } @@ -48,7 +45,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) { @Override public void channelInactive(final ChannelHandlerContext ctx) { - LOGGER.debug("Channel inactive"); + LOG.debug("Channel inactive"); if (!inactiveMessageSent) { DisconnectEventBuilder builder = new DisconnectEventBuilder(); builder.setInfo("Channel inactive"); @@ -59,7 +56,7 @@ public void channelInactive(final ChannelHandlerContext ctx) { @Override public void channelUnregistered(final ChannelHandlerContext ctx) { - LOGGER.debug("Channel unregistered"); + LOG.debug("Channel unregistered"); if (!inactiveMessageSent) { DisconnectEventBuilder builder = new DisconnectEventBuilder(); builder.setInfo("Channel unregistered"); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java index 9b6e863d..5f408e6c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java @@ -23,7 +23,7 @@ */ public class IdleHandler extends ReadTimeoutHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(IdleHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(IdleHandler.class); private boolean first = true; /** @@ -43,7 +43,7 @@ public void channelRead(final ChannelHandlerContext ctx, final Object msg) throw @Override protected void readTimedOut(final ChannelHandlerContext ctx) throws Exception { if (first) { - LOGGER.debug("Switch idle"); + LOG.debug("Switch idle"); SwitchIdleEventBuilder builder = new SwitchIdleEventBuilder(); builder.setInfo("Switch idle"); ctx.fireChannelRead(builder.build()); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java index 3a083eea..261beb9c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java @@ -23,27 +23,27 @@ */ public class OFDatagramPacketDecoder extends SimpleChannelInboundHandler{ - private static final Logger LOGGER = LoggerFactory.getLogger(OFDatagramPacketDecoder.class); + private static final Logger LOG = LoggerFactory.getLogger(OFDatagramPacketDecoder.class); private DeserializationFactory deserializationFactory; @Override public void channelRead0(final ChannelHandlerContext ctx, final VersionMessageUdpWrapper msg) throws Exception { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("UdpVersionMessageWrapper received"); - LOGGER.debug("<< {}", ByteBufUtils.byteBufToHexString(msg.getMessageBuffer())); + if (LOG.isDebugEnabled()) { + LOG.debug("UdpVersionMessageWrapper received"); + LOG.debug("<< {}", ByteBufUtils.byteBufToHexString(msg.getMessageBuffer())); } try { final DataObject dataObject = deserializationFactory.deserialize(msg.getMessageBuffer(),msg.getVersion()); if (dataObject == null) { - LOGGER.warn("Translated POJO is null"); + LOG.warn("Translated POJO is null"); } else { MessageConsumer consumer = UdpConnectionMap.getMessageConsumer(msg.getAddress()); consumer.consume(dataObject); } } catch(Exception e) { - LOGGER.warn("Message deserialization failed", e); + LOG.warn("Message deserialization failed", e); // TODO: delegate exception to allow easier deserialization // debugging / deserialization problem awareness } finally { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java index 73a7a00e..8b1faef3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java @@ -28,19 +28,19 @@ */ public class OFDatagramPacketEncoder extends MessageToMessageEncoder { - private static final Logger LOGGER = LoggerFactory.getLogger(OFDatagramPacketEncoder.class); + private static final Logger LOG = LoggerFactory.getLogger(OFDatagramPacketEncoder.class); private SerializationFactory serializationFactory; @Override protected void encode(ChannelHandlerContext ctx, UdpMessageListenerWrapper wrapper, List out) throws Exception { - LOGGER.trace("Encoding"); + LOG.trace("Encoding"); try { ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); serializationFactory.messageToBuffer(wrapper.getMsg().getVersion(), buffer, wrapper.getMsg()); out.add(new DatagramPacket(buffer, wrapper.getAddress())); } catch(Exception e) { - LOGGER.warn("Message serialization failed: {}", e.getMessage()); + LOG.warn("Message serialization failed: {}", e.getMessage()); Future newFailedFuture = ctx.newFailedFuture(e); wrapper.getListener().operationComplete(newFailedFuture); return; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java index ff805840..0eb29161 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java @@ -31,7 +31,7 @@ */ public class OFDatagramPacketHandler extends MessageToMessageDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(OFDatagramPacketHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(OFDatagramPacketHandler.class); /** Length of OpenFlow 1.3 header */ public static final byte LENGTH_OF_HEADER = 8; @@ -50,19 +50,19 @@ public OFDatagramPacketHandler(SwitchConnectionHandler sch) { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - LOGGER.warn("Unexpected exception from downstream.", cause); - LOGGER.warn("Closing connection."); + LOG.warn("Unexpected exception from downstream.", cause); + LOG.warn("Closing connection."); ctx.close(); } @Override protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, List out) throws Exception { - LOGGER.debug("OFDatagramPacketFramer"); + LOG.debug("OFDatagramPacketFramer"); MessageConsumer consumer = UdpConnectionMap.getMessageConsumer(msg.sender()); if (consumer == null) { ConnectionFacade connectionFacade = - adapterFactory.createConnectionFacade(ctx.channel(), msg.sender()); + adapterFactory.createConnectionFacade(ctx.channel(), msg.sender(), false); connectionHandler.onSwitchConnected(connectionFacade); connectionFacade.checkListeners(); UdpConnectionMap.addConnection(msg.sender(), connectionFacade); @@ -70,34 +70,34 @@ protected void decode(ChannelHandlerContext ctx, DatagramPacket msg, ByteBuf bb = msg.content(); int readableBytes = bb.readableBytes(); if (readableBytes < LENGTH_OF_HEADER) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("skipping bytebuf - too few bytes for header: {} < {}", readableBytes, LENGTH_OF_HEADER); - LOGGER.debug("bb: {}", ByteBufUtils.byteBufToHexString(bb)); + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for header: {} < {}", readableBytes, LENGTH_OF_HEADER); + LOG.debug("bb: {}", ByteBufUtils.byteBufToHexString(bb)); } return; } int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); - LOGGER.debug("length of actual message: {}", length); + LOG.debug("length of actual message: {}", length); if (readableBytes < length) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); - LOGGER.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); + LOG.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); } return; } - LOGGER.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); byte version = bb.readByte(); if ((version == EncodeConstants.OF13_VERSION_ID) || (version == EncodeConstants.OF10_VERSION_ID)) { - LOGGER.debug("detected version: {}", version); + LOG.debug("detected version: {}", version); ByteBuf messageBuffer = bb.slice(); out.add(new VersionMessageUdpWrapper(version, messageBuffer, msg.sender())); messageBuffer.retain(); } else { - LOGGER.warn("detected version: {} - currently not supported", version); + LOG.warn("detected version: {} - currently not supported", version); } bb.skipBytes(bb.readableBytes()); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java index de419f8b..90d0ab02 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java @@ -10,9 +10,7 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; - import java.util.List; - import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; import org.opendaylight.openflowjava.statistics.CounterEventTypes; import org.opendaylight.openflowjava.statistics.StatisticsCounters; @@ -22,47 +20,43 @@ import org.slf4j.LoggerFactory; /** - * Transforms OpenFlow Protocol messages to POJOs + * Transforms OpenFlow Protocol messages to POJOs. * @author michal.polkorab */ public class OFDecoder extends MessageToMessageDecoder { - private static final Logger LOGGER = LoggerFactory.getLogger(OFDecoder.class); + private static final Logger LOG = LoggerFactory.getLogger(OFDecoder.class); private final StatisticsCounters statisticsCounter; // TODO: make this final? private DeserializationFactory deserializationFactory; - /** - * Constructor of class - */ public OFDecoder() { - LOGGER.trace("Creating OF 1.3 Decoder"); - // TODO: pass as argument + LOG.trace("Creating OFDecoder"); + // TODO: pass as argument statisticsCounter = StatisticsCounters.getInstance(); } @Override - protected void decode(ChannelHandlerContext ctx, VersionMessageWrapper msg, - List out) throws Exception { + protected void decode(ChannelHandlerContext ctx, VersionMessageWrapper msg, List out) throws Exception { statisticsCounter.incrementCounter(CounterEventTypes.US_RECEIVED_IN_OFJAVA); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("VersionMessageWrapper received"); - LOGGER.debug("<< {}", ByteBufUtils.byteBufToHexString(msg.getMessageBuffer())); + if (LOG.isDebugEnabled()) { + LOG.debug("VersionMessageWrapper received"); + LOG.debug("<< {}", ByteBufUtils.byteBufToHexString(msg.getMessageBuffer())); } try { final DataObject dataObject = deserializationFactory.deserialize(msg.getMessageBuffer(), msg.getVersion()); if (dataObject == null) { - LOGGER.warn("Translated POJO is null"); + LOG.warn("Translated POJO is null"); statisticsCounter.incrementCounter(CounterEventTypes.US_DECODE_FAIL); } else { out.add(dataObject); statisticsCounter.incrementCounter(CounterEventTypes.US_DECODE_SUCCESS); } } catch (Exception e) { - LOGGER.warn("Message deserialization failed", e); + LOG.warn("Message deserialization failed", e); statisticsCounter.incrementCounter(CounterEventTypes.US_DECODE_FAIL); } finally { msg.getMessageBuffer().release(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java index 4c54732b..2f356693 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java @@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory; /** - * Transforms OpenFlow Protocol messages to POJOs + * Transforms OpenFlow Protocol messages to POJOs. * @author michal.polkorab * @author timotej.kubas */ @@ -34,7 +34,7 @@ public class OFEncoder extends MessageToByteEncoder { /** Constructor of class */ public OFEncoder() { statisticsCounters = StatisticsCounters.getInstance(); - LOG.trace("Creating OF13Encoder"); + LOG.trace("Creating OFEncoder"); } @Override diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java index f4ec8825..a9c5ecd2 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java @@ -12,9 +12,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; - import java.util.List; - import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.slf4j.Logger; @@ -26,21 +24,21 @@ */ public class OFFrameDecoder extends ByteToMessageDecoder { - /** Length of OpenFlow 1.3 header */ + /** Length of OpenFlow header */ public static final byte LENGTH_OF_HEADER = 8; private static final byte LENGTH_INDEX_IN_HEADER = 2; - private static final Logger LOGGER = LoggerFactory.getLogger(OFFrameDecoder.class); + private static final Logger LOG = LoggerFactory.getLogger(OFFrameDecoder.class); private ConnectionFacade connectionFacade; private boolean firstTlsPass = false; /** * Constructor of class. * @param connectionFacade ConnectionFacade that will be notified - * with ConnectionReadyNotification after TLS has been successfully set up. + * with ConnectionReadyNotification after TLS has been successfully set up. * @param tlsPresent true is TLS is required, false otherwise */ public OFFrameDecoder(ConnectionFacade connectionFacade, boolean tlsPresent) { - LOGGER.trace("Creating OFFrameDecoder"); + LOG.trace("Creating OFFrameDecoder"); if (tlsPresent) { firstTlsPass = true; } @@ -50,11 +48,11 @@ public OFFrameDecoder(ConnectionFacade connectionFacade, boolean tlsPresent) { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof io.netty.handler.ssl.NotSslRecordException) { - LOGGER.warn("Not an TLS record exception - please verify TLS configuration."); + LOG.warn("Not an TLS record exception - please verify TLS configuration."); } else { - LOGGER.warn("Unexpected exception from downstream.", cause); + LOG.warn("Unexpected exception from downstream.", cause); } - LOGGER.warn("Closing connection."); + LOG.warn("Closing connection."); ctx.close(); } @@ -66,24 +64,24 @@ protected void decode(ChannelHandlerContext chc, ByteBuf bb, List list) } int readableBytes = bb.readableBytes(); if (readableBytes < LENGTH_OF_HEADER) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("skipping bytebuf - too few bytes for header: {} < {}", readableBytes, LENGTH_OF_HEADER); - LOGGER.debug("bb: {}", ByteBufUtils.byteBufToHexString(bb)); + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for header: {} < {}", readableBytes, LENGTH_OF_HEADER); + LOG.debug("bb: {}", ByteBufUtils.byteBufToHexString(bb)); } return; } int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); - LOGGER.debug("length of actual message: {}", length); + LOG.debug("length of actual message: {}", length); if (readableBytes < length) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); - LOGGER.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); + LOG.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); } return; } - LOGGER.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); list.add(messageBuffer); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java index 0142ebfd..8e23566a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java @@ -11,6 +11,8 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.statistics.CounterEventTypes; @@ -19,25 +21,22 @@ import org.slf4j.LoggerFactory; /** - * Detects version of used OpenFlow Protocol and discards unsupported version messages + * Detects version of used OpenFlow Protocol and discards unsupported version messages. * @author michal.polkorab */ public class OFVersionDetector extends ByteToMessageDecoder { - /** Version number of OpenFlow 1.0 protocol */ - private static final byte OF10_VERSION_ID = EncodeConstants.OF10_VERSION_ID; - /** Version number of OpenFlow 1.3 protocol */ - private static final byte OF13_VERSION_ID = EncodeConstants.OF13_VERSION_ID; - private static final short OF_PACKETIN = 10; - private static final Logger LOGGER = LoggerFactory.getLogger(OFVersionDetector.class); + private static final Logger LOG = LoggerFactory.getLogger(OFVersionDetector.class); + /** IDs of accepted OpenFlow protocol versions */ + private static final List OF_VERSIONS = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID + )); private final StatisticsCounters statisticsCounters; private volatile boolean filterPacketIns; - /** - * Constructor of class. - */ public OFVersionDetector() { - LOGGER.trace("Creating OFVersionDetector"); + LOG.trace("Creating OFVersionDetector"); statisticsCounters = StatisticsCounters.getInstance(); } @@ -48,25 +47,27 @@ public void setFilterPacketIns(final boolean enabled) { @Override protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List out) { if (!in.isReadable()) { - LOGGER.debug("not enough data"); + LOG.debug("not enough data"); in.release(); return; } final byte version = in.readByte(); - if (version == OF13_VERSION_ID || version == OF10_VERSION_ID) { - LOGGER.debug("detected version: {}", version); - if (!filterPacketIns || OF_PACKETIN != in.getUnsignedByte(in.readerIndex())) { + final short messageType = in.getUnsignedByte(in.readerIndex()); + if (messageType == EncodeConstants.OF_HELLO_MESSAGE_TYPE_VALUE || OF_VERSIONS.contains(version)) { + LOG.debug("detected version: {}", version); + if (!filterPacketIns || EncodeConstants.OF_PACKETIN_MESSAGE_TYPE_VALUE != messageType) { ByteBuf messageBuffer = in.slice(); out.add(new VersionMessageWrapper(version, messageBuffer)); messageBuffer.retain(); } else { - LOGGER.debug("dropped packetin"); + LOG.debug("dropped packetin"); statisticsCounters.incrementCounter(CounterEventTypes.US_DROPPED_PACKET_IN); } } else { - LOGGER.warn("detected version: {} - currently not supported", version); + LOG.warn("detected version: {} - currently not supported", version); } in.skipBytes(in.readableBytes()); } + } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java index 51ac5482..88144d47 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java @@ -44,9 +44,9 @@ public enum PipelineHandlers { */ DELEGATING_INBOUND_HANDLER, /** - * Performs efficient flushing + * Performs configurable efficient flushing */ - CHANNEL_OUTBOUNF_QUEUE, + CHANNEL_OUTBOUND_QUEUE_MANAGER, /** * Decodes incoming messages into message frames * and filters them based on version supported diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java index f450c064..ec4ffd4a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java @@ -10,7 +10,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; - import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; @@ -28,6 +27,7 @@ public abstract class ProtocolChannelInitializer private SerializationFactory serializationFactory; private DeserializationFactory deserializationFactory; private TlsConfiguration tlsConfiguration; + private boolean useBarrier; /** * @param switchConnectionHandler the switchConnectionHandler to set @@ -60,7 +60,7 @@ public void setDeserializationFactory(final DeserializationFactory deserializati /** * @param tlsConfiguration */ - public void setTlsConfiguration(TlsConfiguration tlsConfiguration) { + public void setTlsConfiguration(final TlsConfiguration tlsConfiguration) { this.tlsConfiguration = tlsConfiguration; } @@ -98,4 +98,18 @@ public DeserializationFactory getDeserializationFactory() { public TlsConfiguration getTlsConfiguration() { return tlsConfiguration; } + + /** + * @param useBarrier + */ + public void setUseBarrier(final boolean useBarrier) { + this.useBarrier = useBarrier; + } + + /** + * @return useBarrrier + */ + public boolean useBarrier() { + return useBarrier; + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java index b2c5a199..dbaa2070 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java @@ -34,7 +34,7 @@ public class SslContextFactory { private static final String PROTOCOL = "TLS"; private TlsConfiguration tlsConfig; - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(SslContextFactory.class); /** @@ -72,16 +72,16 @@ public SSLContext getServerContext() { serverContext = SSLContext.getInstance(PROTOCOL); serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); } catch (IOException e) { - LOGGER.warn("IOException - Failed to load keystore / truststore." + LOG.warn("IOException - Failed to load keystore / truststore." + " Failed to initialize the server-side SSLContext", e); } catch (NoSuchAlgorithmException e) { - LOGGER.warn("NoSuchAlgorithmException - Unsupported algorithm." + LOG.warn("NoSuchAlgorithmException - Unsupported algorithm." + " Failed to initialize the server-side SSLContext", e); } catch (CertificateException e) { - LOGGER.warn("CertificateException - Unable to access certificate (check password)." + LOG.warn("CertificateException - Unable to access certificate (check password)." + " Failed to initialize the server-side SSLContext", e); } catch (Exception e) { - LOGGER.warn("Exception - Failed to initialize the server-side SSLContext", e); + LOG.warn("Exception - Failed to initialize the server-side SSLContext", e); } return serverContext; } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java index 589c23cd..e4efea9f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java @@ -24,7 +24,7 @@ */ public final class SslKeyStore { - private static final Logger LOGGER = LoggerFactory.getLogger(SslKeyStore.class); + private static final Logger LOG = LoggerFactory.getLogger(SslKeyStore.class); private SslKeyStore() { throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); @@ -48,7 +48,7 @@ public static InputStream asInputStream(String filename, PathType pathType) { } break; case PATH: - LOGGER.debug("Current dir using System:" + LOG.debug("Current dir using System:" + System.getProperty("user.dir")); File keystorefile = new File(filename); try { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java new file mode 100644 index 00000000..79ad2665 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.core; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Throwables; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProviderFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Threads; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Tls; + +/** + * Implementation of the SwitchConnectionProviderFactory interface. + * + * @author Thomas Pantelis + */ +public class SwitchConnectionProviderFactoryImpl implements SwitchConnectionProviderFactory { + + @Override + public SwitchConnectionProvider newInstance(SwitchConnectionConfig config) { + SwitchConnectionProviderImpl switchConnectionProviderImpl = new SwitchConnectionProviderImpl(); + switchConnectionProviderImpl.setConfiguration(new ConnectionConfigurationImpl(config)); + return switchConnectionProviderImpl; + } + + private static InetAddress extractIpAddressBin(final IpAddress address) throws UnknownHostException { + byte[] addressBin = null; + if (address != null) { + if (address.getIpv4Address() != null) { + addressBin = address2bin(address.getIpv4Address().getValue()); + } else if (address.getIpv6Address() != null) { + addressBin = address2bin(address.getIpv6Address().getValue()); + } + } + + if (addressBin == null) { + return null; + } else { + return InetAddress.getByAddress(addressBin); + } + } + + private static byte[] address2bin(final String value) { + //TODO: translate ipv4 or ipv6 into byte[] + return null; + } + + private static class ConnectionConfigurationImpl implements ConnectionConfiguration { + private final SwitchConnectionConfig config; + private InetAddress address; + + private ConnectionConfigurationImpl(SwitchConnectionConfig config) { + this.config = config; + + try { + address = extractIpAddressBin(config.getAddress()); + } catch(UnknownHostException e) { + Throwables.propagate(e); + } + } + + @Override + public InetAddress getAddress() { + return address; + } + + @Override + public int getPort() { + return config.getPort(); + } + + @Override + public Object getTransferProtocol() { + return config.getTransportProtocol(); + } + + @Override + public TlsConfiguration getTlsConfiguration() { + final Tls tlsConfig = config.getTls(); + if(tlsConfig == null || !(TransportProtocol.TLS.equals(getTransferProtocol()))) { + return null; + } + + return new TlsConfiguration() { + @Override + public KeystoreType getTlsTruststoreType() { + return MoreObjects.firstNonNull(tlsConfig.getTruststoreType(), null); + } + @Override + public String getTlsTruststore() { + return MoreObjects.firstNonNull(tlsConfig.getTruststore(), null); + } + @Override + public KeystoreType getTlsKeystoreType() { + return MoreObjects.firstNonNull(tlsConfig.getKeystoreType(), null); + } + @Override + public String getTlsKeystore() { + return MoreObjects.firstNonNull(tlsConfig.getKeystore(), null); + } + @Override + public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType getTlsKeystorePathType() { + return MoreObjects.firstNonNull(tlsConfig.getKeystorePathType(), null); + } + @Override + public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType getTlsTruststorePathType() { + return MoreObjects.firstNonNull(tlsConfig.getTruststorePathType(), null); + } + @Override + public String getKeystorePassword() { + return MoreObjects.firstNonNull(tlsConfig.getKeystorePassword(), null); + } + @Override + public String getCertificatePassword() { + return MoreObjects.firstNonNull(tlsConfig.getCertificatePassword(), null); + } + @Override + public String getTruststorePassword() { + return MoreObjects.firstNonNull(tlsConfig.getTruststorePassword(), null); + } + @Override + public List getCipherSuites() { + return tlsConfig.getCipherSuites(); + } + }; + } + + @Override + public long getSwitchIdleTimeout() { + return config.getSwitchIdleTimeout(); + } + + @Override + public Object getSslContext() { + return null; + } + + @Override + public ThreadConfiguration getThreadConfiguration() { + final Threads threads = config.getThreads(); + if(threads == null) { + return null; + } + + return new ThreadConfiguration() { + @Override + public int getWorkerThreadCount() { + return threads.getWorkerThreads(); + } + + @Override + public int getBossThreadCount() { + return threads.getBossThreads(); + } + }; + } + + @Override + public boolean useBarrier() { + return config.isUseBarrier(); + } + } +} 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 old mode 100644 new mode 100755 index 0217d1f2..612afcb7 --- 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 @@ -11,7 +11,8 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.Epoll; import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; @@ -24,6 +25,7 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterSerializerKey; @@ -36,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; @@ -57,15 +60,15 @@ */ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, ConnectionInitializer { - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(SwitchConnectionProviderImpl.class); private SwitchConnectionHandler switchConnectionHandler; private ServerFacade serverFacade; private ConnectionConfiguration connConfig; - private SerializationFactory serializationFactory; - private SerializerRegistry serializerRegistry; - private DeserializerRegistry deserializerRegistry; - private DeserializationFactory deserializationFactory; + private final SerializationFactory serializationFactory; + private final SerializerRegistry serializerRegistry; + private final DeserializerRegistry deserializerRegistry; + private final DeserializationFactory deserializationFactory; private TcpConnectionInitializer connectionInitializer; /** Constructor */ @@ -81,21 +84,21 @@ public SwitchConnectionProviderImpl() { } @Override - public void setConfiguration(ConnectionConfiguration connConfig) { + public void setConfiguration(final ConnectionConfiguration connConfig) { this.connConfig = connConfig; } @Override - public void setSwitchConnectionHandler(SwitchConnectionHandler switchConnectionHandler) { - LOGGER.debug("setSwitchConnectionHandler"); + public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) { + LOG.debug("setSwitchConnectionHandler"); this.switchConnectionHandler = switchConnectionHandler; } @Override public ListenableFuture shutdown() { - LOGGER.debug("Shutdown summoned"); + LOG.debug("Shutdown summoned"); if(serverFacade == null){ - LOGGER.warn("Can not shutdown - not configured or started"); + LOG.warn("Can not shutdown - not configured or started"); throw new IllegalStateException("SwitchConnectionProvider is not started or not configured."); } return serverFacade.shutdown(); @@ -103,7 +106,7 @@ public ListenableFuture shutdown() { @Override public ListenableFuture startup() { - LOGGER.debug("Startup summoned"); + LOG.debug("Startup summoned"); ListenableFuture result = null; try { serverFacade = createAndConfigureServer(); @@ -112,8 +115,8 @@ public ListenableFuture startup() { } new Thread(serverFacade).start(); result = serverFacade.getIsOnlineFuture(); - } catch (Exception e) { - SettableFuture exResult = SettableFuture.create(); + } catch (final Exception e) { + final SettableFuture exResult = SettableFuture.create(); exResult.setException(e); result = exResult; } @@ -124,27 +127,34 @@ public ListenableFuture startup() { * @return */ private ServerFacade createAndConfigureServer() { - LOGGER.debug("Configuring .."); + LOG.debug("Configuring .."); ServerFacade server = null; - ChannelInitializerFactory factory = new ChannelInitializerFactory(); + final ChannelInitializerFactory factory = new ChannelInitializerFactory(); factory.setSwitchConnectionHandler(switchConnectionHandler); factory.setSwitchIdleTimeout(connConfig.getSwitchIdleTimeout()); factory.setTlsConfig(connConfig.getTlsConfiguration()); factory.setSerializationFactory(serializationFactory); factory.setDeserializationFactory(deserializationFactory); - TransportProtocol transportProtocol = (TransportProtocol) connConfig.getTransferProtocol(); - if (transportProtocol.equals(TransportProtocol.TCP) || transportProtocol.equals(TransportProtocol.TLS)) { + factory.setUseBarrier(connConfig.useBarrier()); + final TransportProtocol transportProtocol = (TransportProtocol) connConfig.getTransferProtocol(); + + // Check if Epoll native transport is available. + // TODO : Add option to disable Epoll. + boolean isEpollEnabled = Epoll.isAvailable(); + + if ((TransportProtocol.TCP.equals(transportProtocol) || TransportProtocol.TLS.equals(transportProtocol))) { server = new TcpHandler(connConfig.getAddress(), connConfig.getPort()); - TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer(); + final TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer(); ((TcpHandler) server).setChannelInitializer(channelInitializer); - ((TcpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration()); + ((TcpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); - NioEventLoopGroup workerGroupFromTcpHandler = ((TcpHandler) server).getWorkerGroup(); - connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler); + final EventLoopGroup workerGroupFromTcpHandler = ((TcpHandler) server).getWorkerGroup(); + 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()); } else { throw new IllegalStateException("Unknown transport protocol received: " + transportProtocol); @@ -166,54 +176,54 @@ public void close() throws Exception { } @Override - public boolean unregisterSerializer(ExperimenterSerializerKey key) { + public boolean unregisterSerializer(final ExperimenterSerializerKey key) { return serializerRegistry.unregisterSerializer((MessageTypeKey) key); } @Override - public boolean unregisterDeserializer(ExperimenterDeserializerKey key) { + public boolean unregisterDeserializer(final ExperimenterDeserializerKey key) { return deserializerRegistry.unregisterDeserializer((MessageCodeKey) key); } @Override - public void registerActionSerializer(ActionSerializerKey key, - OFGeneralSerializer serializer) { + public void registerActionSerializer(final ActionSerializerKey key, + final OFGeneralSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerActionDeserializer(ExperimenterActionDeserializerKey key, - OFGeneralDeserializer deserializer) { + public void registerActionDeserializer(final ExperimenterActionDeserializerKey key, + final OFGeneralDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override - public void registerInstructionSerializer(InstructionSerializerKey key, - OFGeneralSerializer serializer) { + public void registerInstructionSerializer(final InstructionSerializerKey key, + final OFGeneralSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerInstructionDeserializer(ExperimenterInstructionDeserializerKey key, - OFGeneralDeserializer deserializer) { + public void registerInstructionDeserializer(final ExperimenterInstructionDeserializerKey key, + final OFGeneralDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override - public void registerMatchEntrySerializer(MatchEntrySerializerKey key, - OFGeneralSerializer serializer) { + public void registerMatchEntrySerializer(final MatchEntrySerializerKey key, + final OFGeneralSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerMatchEntryDeserializer(MatchEntryDeserializerKey key, - OFGeneralDeserializer deserializer) { + public void registerMatchEntryDeserializer(final MatchEntryDeserializerKey key, + final OFGeneralDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override - public void registerErrorDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer) { + public void registerErrorDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @@ -230,20 +240,20 @@ public void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializer } @Override - public void registerMultipartReplyTFDeserializer(ExperimenterIdDeserializerKey key, - OFGeneralDeserializer deserializer) { + public void registerMultipartReplyTFDeserializer(final ExperimenterIdDeserializerKey key, + final OFGeneralDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override - public void registerQueuePropertyDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer) { + public void registerQueuePropertyDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override - public void registerMeterBandDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer) { + public void registerMeterBandDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @@ -260,20 +270,55 @@ public void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, - OFGeneralSerializer serializer) { + public void registerMultipartRequestTFSerializer(final ExperimenterIdSerializerKey key, + final OFGeneralSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerMeterBandSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer) { + /** + * @deprecated Since we have used ExperimenterIdMeterSubTypeSerializerKey as MeterBandSerializer's key, in order to avoid + * the occurrence of an error, we should discard this function + */ + @Deprecated + public void registerMeterBandSerializer(final ExperimenterIdSerializerKey key, + final OFSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void initiateConnection(String host, int port) { + public void registerMeterBandSerializer(final ExperimenterIdMeterSubTypeSerializerKey key, + final OFSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void initiateConnection(final String host, final int port) { connectionInitializer.initiateConnection(host, port); } + @Override + 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/TcpChannelInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java index 3be9f96f..9540eeed 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java @@ -12,15 +12,13 @@ import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.socket.SocketChannel; import io.netty.handler.ssl.SslHandler; - +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; import java.net.InetAddress; import java.util.Iterator; +import java.util.List; import java.util.concurrent.TimeUnit; - import javax.net.ssl.SSLEngine; - -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory; import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactoryImpl; import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade; @@ -28,28 +26,26 @@ import org.slf4j.LoggerFactory; /** - * Initializes TCP / TLS channel + * Initializes TCP / TLS channel. * @author michal.polkorab */ public class TcpChannelInitializer extends ProtocolChannelInitializer { - private static final Logger LOGGER = LoggerFactory - .getLogger(TcpChannelInitializer.class); + private static final Logger LOG = LoggerFactory.getLogger(TcpChannelInitializer.class); private final DefaultChannelGroup allChannels; - private ConnectionAdapterFactory connectionAdapterFactory; + private final ConnectionAdapterFactory connectionAdapterFactory; /** - * default ctor + * Default constructor. */ public TcpChannelInitializer() { this( new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl() ); } /** - * Testing Constructor - * + * Testing constructor. */ - protected TcpChannelInitializer( DefaultChannelGroup channelGroup, ConnectionAdapterFactory connAdaptorFactory ) { + protected TcpChannelInitializer( final DefaultChannelGroup channelGroup, final ConnectionAdapterFactory connAdaptorFactory ) { allChannels = channelGroup ; connectionAdapterFactory = connAdaptorFactory ; } @@ -57,42 +53,50 @@ protected TcpChannelInitializer( DefaultChannelGroup channelGroup, ConnectionAda @Override protected void initChannel(final SocketChannel ch) { if (ch.remoteAddress() != null) { - InetAddress switchAddress = ch.remoteAddress().getAddress(); - int port = ch.localAddress().getPort(); - int remotePort = ch.remoteAddress().getPort(); - LOGGER.debug("Incoming connection from (remote address): {}:{} --> :{}", + final InetAddress switchAddress = ch.remoteAddress().getAddress(); + final int port = ch.localAddress().getPort(); + final int remotePort = ch.remoteAddress().getPort(); + LOG.debug("Incoming connection from (remote address): {}:{} --> :{}", switchAddress.toString(), remotePort, port); if (!getSwitchConnectionHandler().accept(switchAddress)) { ch.disconnect(); - LOGGER.debug("Incoming connection rejected"); + LOG.debug("Incoming connection rejected"); return; } } - LOGGER.debug("Incoming connection accepted - building pipeline"); + LOG.debug("Incoming connection accepted - building pipeline"); allChannels.add(ch); ConnectionFacade connectionFacade = null; - connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null); + connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null, useBarrier()); try { - LOGGER.debug("calling plugin: {}", getSwitchConnectionHandler()); + LOG.debug("Calling OF plugin: {}", getSwitchConnectionHandler()); getSwitchConnectionHandler().onSwitchConnected(connectionFacade); connectionFacade.checkListeners(); - ch.pipeline().addLast(PipelineHandlers.IDLE_HANDLER.name(), new IdleHandler(getSwitchIdleTimeout(), TimeUnit.MILLISECONDS)); + ch.pipeline().addLast(PipelineHandlers.IDLE_HANDLER.name(), + new IdleHandler(getSwitchIdleTimeout(), TimeUnit.MILLISECONDS)); boolean tlsPresent = false; // If this channel is configured to support SSL it will only support SSL if (getTlsConfiguration() != null) { tlsPresent = true; - SslContextFactory sslFactory = new SslContextFactory(getTlsConfiguration()); - SSLEngine engine = sslFactory.getServerContext().createSSLEngine(); + final SslContextFactory sslFactory = new SslContextFactory(getTlsConfiguration()); + final SSLEngine engine = sslFactory.getServerContext().createSSLEngine(); engine.setNeedClientAuth(true); engine.setUseClientMode(false); - SslHandler ssl = new SslHandler(engine); - Future handshakeFuture = ssl.handshakeFuture(); + List suitesList = getTlsConfiguration().getCipherSuites(); + if (suitesList != null && !suitesList.isEmpty()) { + LOG.debug("Requested Cipher Suites are: {}", suitesList); + String[] suites = suitesList.toArray(new String[suitesList.size()]); + engine.setEnabledCipherSuites(suites); + LOG.debug("Cipher suites enabled in SSLEngine are: {}", engine.getEnabledCipherSuites().toString()); + } + final SslHandler ssl = new SslHandler(engine); + final Future handshakeFuture = ssl.handshakeFuture(); final ConnectionFacade finalConnectionFacade = connectionFacade; handshakeFuture.addListener(new GenericFutureListener>() { @Override - public void operationComplete(Future future) throws Exception { + public void operationComplete(final Future future) throws Exception { finalConnectionFacade.fireConnectionReadyNotification(); } }); @@ -101,18 +105,19 @@ public void operationComplete(Future future) throws Exception { ch.pipeline().addLast(PipelineHandlers.OF_FRAME_DECODER.name(), new OFFrameDecoder(connectionFacade, tlsPresent)); ch.pipeline().addLast(PipelineHandlers.OF_VERSION_DETECTOR.name(), new OFVersionDetector()); - OFDecoder ofDecoder = new OFDecoder(); + final OFDecoder ofDecoder = new OFDecoder(); ofDecoder.setDeserializationFactory(getDeserializationFactory()); ch.pipeline().addLast(PipelineHandlers.OF_DECODER.name(), ofDecoder); - OFEncoder ofEncoder = new OFEncoder(); + final OFEncoder ofEncoder = new OFEncoder(); ofEncoder.setSerializationFactory(getSerializationFactory()); ch.pipeline().addLast(PipelineHandlers.OF_ENCODER.name(), ofEncoder); - ch.pipeline().addLast(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(), new DelegatingInboundHandler(connectionFacade)); + ch.pipeline().addLast(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(), + new DelegatingInboundHandler(connectionFacade)); if (!tlsPresent) { connectionFacade.fireConnectionReadyNotification(); } - } catch (Exception e) { - LOGGER.warn("Failed to initialize channel", e); + } catch (final Exception e) { + LOG.warn("Failed to initialize channel", e); ch.close(); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java index c4b0937e..d0a2fc63 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java @@ -1,10 +1,17 @@ +/* + * Copyright (c) 2015 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.core; import io.netty.bootstrap.Bootstrap; import io.netty.channel.EventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.epoll.EpollSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; - import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,28 +28,35 @@ public class TcpConnectionInitializer implements ServerFacade, ConnectionInitializer { - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(TcpConnectionInitializer.class); private EventLoopGroup workerGroup; private ThreadConfiguration threadConfig; private TcpChannelInitializer channelInitializer; private Bootstrap b; + private boolean isEpollEnabled; /** * Constructor * @param workerGroup - shared worker group */ - public TcpConnectionInitializer(NioEventLoopGroup workerGroup) { + public TcpConnectionInitializer(EventLoopGroup workerGroup, boolean isEpollEnabled) { Preconditions.checkNotNull(workerGroup, "WorkerGroup can't be null"); this.workerGroup = workerGroup; + this.isEpollEnabled = isEpollEnabled; } @Override public void run() { b = new Bootstrap(); - b.group(workerGroup).channel(NioSocketChannel.class) - .handler(channelInitializer); + if(isEpollEnabled) { + b.group(workerGroup).channel(EpollSocketChannel.class) + .handler(channelInitializer); + } else { + b.group(workerGroup).channel(NioSocketChannel.class) + .handler(channelInitializer); + } } @Override @@ -67,7 +81,7 @@ public void initiateConnection(String host, int port) { try { b.connect(host, port).sync(); } catch (InterruptedException e) { - LOGGER.error("Unable to initiate connection", e); + LOG.error("Unable to initiate connection", e); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java index ff4bc6a1..23914231 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java @@ -13,11 +13,17 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.util.concurrent.GenericFutureListener; +import io.netty.channel.epoll.Epoll; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.epoll.EpollServerSocketChannel; + import java.net.InetAddress; import java.net.InetSocketAddress; @@ -45,18 +51,20 @@ public class TcpHandler implements ServerFacade { */ private static final int DEFAULT_WRITE_SPIN_COUNT = 16; - private static final Logger LOGGER = LoggerFactory.getLogger(TcpHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(TcpHandler.class); private int port; private String address; private final InetAddress startupAddress; - private NioEventLoopGroup workerGroup; - private NioEventLoopGroup bossGroup; + private EventLoopGroup workerGroup; + private EventLoopGroup bossGroup; private final SettableFuture isOnlineFuture; private ThreadConfiguration threadConfig; private TcpChannelInitializer channelInitializer; + private Class socketChannelClass; + /** * Constructor of TCPHandler that listens on selected port. * @@ -90,13 +98,13 @@ public void run() { * Any other setting means netty will measure the time it spent selecting * and spend roughly proportional time executing tasks. */ - workerGroup.setIoRatio(100); + //workerGroup.setIoRatio(100); final ChannelFuture f; try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) - .channel(NioServerSocketChannel.class) + .channel(socketChannelClass) .handler(new LoggingHandler(LogLevel.DEBUG)) .childHandler(channelInitializer) .option(ChannelOption.SO_BACKLOG, 128) @@ -114,7 +122,7 @@ public void run() { f = b.bind(port).sync(); } } catch (InterruptedException e) { - LOGGER.error("Interrupted while binding port {}", port, e); + LOG.error("Interrupted while binding port {}", port, e); return; } @@ -125,12 +133,12 @@ public void run() { // Update port, as it may have been specified as 0 this.port = isa.getPort(); - LOGGER.debug("address from tcphandler: {}", address); + LOG.debug("address from tcphandler: {}", address); isOnlineFuture.set(true); - LOGGER.info("Switch listener started and ready to accept incoming tcp/tls connections on port: {}", port); + LOG.info("Switch listener started and ready to accept incoming tcp/tls connections on port: {}", port); f.channel().closeFuture().sync(); } catch (InterruptedException e) { - LOGGER.error("Interrupted while waiting for port {} shutdown", port, e); + LOG.error("Interrupted while waiting for port {} shutdown", port, e); } finally { shutdown(); } @@ -202,7 +210,21 @@ public void setThreadConfig(ThreadConfiguration threadConfig) { * Initiate event loop groups * @param threadConfiguration number of threads to be created, if not specified in threadConfig */ - public void initiateEventLoopGroups(ThreadConfiguration threadConfiguration) { + public void initiateEventLoopGroups(ThreadConfiguration threadConfiguration, boolean isEpollEnabled) { + + if(isEpollEnabled) { + initiateEpollEventLoopGroups(threadConfiguration); + } else { + initiateNioEventLoopGroups(threadConfiguration); + } + } + + /** + * Initiate Nio event loop groups + * @param threadConfiguration number of threads to be created, if not specified in threadConfig + */ + public void initiateNioEventLoopGroups(ThreadConfiguration threadConfiguration) { + socketChannelClass = NioServerSocketChannel.class; if (threadConfiguration != null) { bossGroup = new NioEventLoopGroup(threadConfiguration.getBossThreadCount()); workerGroup = new NioEventLoopGroup(threadConfiguration.getWorkerThreadCount()); @@ -210,12 +232,37 @@ public void initiateEventLoopGroups(ThreadConfiguration threadConfiguration) { bossGroup = new NioEventLoopGroup(); workerGroup = new NioEventLoopGroup(); } + ((NioEventLoopGroup)workerGroup).setIoRatio(100); + } + + /** + * Initiate Epoll event loop groups with Nio as fall back + * @param threadConfiguration + */ + protected void initiateEpollEventLoopGroups(ThreadConfiguration threadConfiguration) { + try { + socketChannelClass = EpollServerSocketChannel.class; + if (threadConfiguration != null) { + bossGroup = new EpollEventLoopGroup(threadConfiguration.getBossThreadCount()); + workerGroup = new EpollEventLoopGroup(threadConfiguration.getWorkerThreadCount()); + } else { + bossGroup = new EpollEventLoopGroup(); + workerGroup = new EpollEventLoopGroup(); + } + ((EpollEventLoopGroup)workerGroup).setIoRatio(100); + return; + } catch (Throwable ex) { + LOG.debug("Epoll initiation failed"); + } + + //Fallback mechanism + initiateNioEventLoopGroups(threadConfiguration); } /** * @return workerGroup */ - public NioEventLoopGroup getWorkerGroup() { + public EventLoopGroup getWorkerGroup() { return workerGroup; } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java index ba1650e5..ccb8b06c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java @@ -8,16 +8,16 @@ package org.opendaylight.openflowjava.protocol.impl.core; -import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.channel.socket.DatagramChannel; /** * @author michal.polkorab * */ -public class UdpChannelInitializer extends ProtocolChannelInitializer { +public class UdpChannelInitializer extends ProtocolChannelInitializer { @Override - protected void initChannel(NioDatagramChannel ch) throws Exception { + protected void initChannel(DatagramChannel ch) throws Exception { ch.pipeline().addLast(PipelineHandlers.OF_DATAGRAMPACKET_HANDLER.name(), new OFDatagramPacketHandler(getSwitchConnectionHandler())); OFDatagramPacketDecoder ofDatagramPacketDecoder = new OFDatagramPacketDecoder(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java index 3e6e384e..1dac7a59 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java @@ -12,7 +12,10 @@ import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.EpollDatagramChannel; +import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannel; import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.util.concurrent.GenericFutureListener; @@ -33,7 +36,7 @@ */ public final class UdpHandler implements ServerFacade { - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(UdpHandler.class); private int port; private EventLoopGroup group; @@ -41,6 +44,7 @@ public final class UdpHandler implements ServerFacade { private final SettableFuture isOnlineFuture; private UdpChannelInitializer channelInitializer; private ThreadConfiguration threadConfig; + private Class datagramChannelClass; /** * Constructor of UdpHandler that listens on selected port. @@ -64,16 +68,11 @@ public UdpHandler(final InetAddress address, final int port) { @Override public void run() { - if (threadConfig != null) { - group = new NioEventLoopGroup(threadConfig.getWorkerThreadCount()); - } else { - group = new NioEventLoopGroup(); - } final ChannelFuture f; try { Bootstrap b = new Bootstrap(); b.group(group) - .channel(NioDatagramChannel.class) + .channel(datagramChannelClass) .option(ChannelOption.SO_BROADCAST, false) .handler(channelInitializer); @@ -83,7 +82,7 @@ public void run() { f = b.bind(port).sync(); } } catch (InterruptedException e) { - LOGGER.error("Interrupted while binding port {}", port, e); + LOG.error("Interrupted while binding port {}", port, e); return; } @@ -94,12 +93,12 @@ public void run() { // Update port, as it may have been specified as 0 this.port = isa.getPort(); - LOGGER.debug("Address from udpHandler: {}", address); + LOG.debug("Address from udpHandler: {}", address); isOnlineFuture.set(true); - LOGGER.info("Switch listener started and ready to accept incoming udp connections on port: {}", port); + LOG.info("Switch listener started and ready to accept incoming udp connections on port: {}", port); f.channel().closeFuture().sync(); } catch (InterruptedException e) { - LOGGER.error("Interrupted while waiting for port {} shutdown", port, e); + LOG.error("Interrupted while waiting for port {} shutdown", port, e); } finally { shutdown(); } @@ -146,4 +145,51 @@ public void setChannelInitializer(UdpChannelInitializer channelInitializer) { public void setThreadConfig(ThreadConfiguration threadConfig) { this.threadConfig = threadConfig; } + + /** + * Initiate event loop groups + * @param threadConfiguration number of threads to be created, if not specified in threadConfig + */ + public void initiateEventLoopGroups(ThreadConfiguration threadConfiguration, boolean isEpollEnabled) { + + if(isEpollEnabled) { + initiateEpollEventLoopGroups(threadConfiguration); + } else { + initiateNioEventLoopGroups(threadConfiguration); + } + } + + /** + * Initiate Nio event loop groups + * @param threadConfiguration number of threads to be created, if not specified in threadConfig + */ + public void initiateNioEventLoopGroups(ThreadConfiguration threadConfiguration) { + datagramChannelClass = NioDatagramChannel.class; + if (threadConfiguration != null) { + group = new NioEventLoopGroup(threadConfiguration.getWorkerThreadCount()); + } else { + group = new NioEventLoopGroup(); + } + } + + /** + * Initiate Epoll event loop groups with Nio as fall back + * @param threadConfiguration + */ + protected void initiateEpollEventLoopGroups(ThreadConfiguration threadConfiguration) { + try { + datagramChannelClass = EpollDatagramChannel.class; + if (threadConfiguration != null) { + group = new EpollEventLoopGroup(threadConfiguration.getWorkerThreadCount()); + } else { + group = new EpollEventLoopGroup(); + } + return; + } catch (Throwable ex) { + LOG.debug("Epoll initiation failed"); + } + + //Fallback mechanism + initiateNioEventLoopGroups(threadConfiguration); + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java index c1625e5b..8f8d0641 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.core; import io.netty.buffer.ByteBuf; - import java.net.InetSocketAddress; /** @@ -18,15 +17,14 @@ * @author michal.polkorab */ public class VersionMessageUdpWrapper extends VersionMessageWrapper { - - private InetSocketAddress address; + private final InetSocketAddress address; /** * @param version Openflow wire version * @param messageBuffer ByteBuf containing binary message * @param address sender address */ - public VersionMessageUdpWrapper(short version, ByteBuf messageBuffer, InetSocketAddress address) { + public VersionMessageUdpWrapper(final short version, final ByteBuf messageBuffer, final InetSocketAddress address) { super(version, messageBuffer); this.address = address; } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java index a61298de..cdbe419c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java @@ -8,6 +8,7 @@ package org.opendaylight.openflowjava.protocol.impl.core; +import com.google.common.base.Preconditions; import io.netty.buffer.ByteBuf; /** @@ -15,18 +16,17 @@ * @author michal.polkorab */ public class VersionMessageWrapper { - - private short version; - private ByteBuf messageBuffer; + private final short version; + private final ByteBuf messageBuffer; /** * Constructor * @param version version decoded in {@link OFVersionDetector} * @param messageBuffer message received from {@link OFFrameDecoder} */ - public VersionMessageWrapper(short version, ByteBuf messageBuffer) { + public VersionMessageWrapper(final short version, final ByteBuf messageBuffer) { this.version = version; - this.messageBuffer = messageBuffer; + this.messageBuffer = Preconditions.checkNotNull(messageBuffer); } /** @@ -42,6 +42,4 @@ public short getVersion() { public ByteBuf getMessageBuffer() { return messageBuffer; } - - } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java new file mode 100644 index 00000000..57f1498c --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalCause; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.InetSocketAddress; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; +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.EchoInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link ConnectionAdapter} interface contains couple of OF message handling approaches. + * {@link AbstractConnectionAdapter} class contains direct RPC processing from OpenflowProtocolService + * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolService} + */ +abstract class AbstractConnectionAdapter implements ConnectionAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractConnectionAdapter.class); + + /** after this time, RPC future response objects will be thrown away (in minutes) */ + private static final int RPC_RESPONSE_EXPIRATION = 1; + + private static final Exception QUEUE_FULL_EXCEPTION = new RejectedExecutionException("Output queue is full"); + + /** + * Default depth of write queue, e.g. we allow these many messages + * to be queued up before blocking producers. + */ + private static final int DEFAULT_QUEUE_DEPTH = 1024; + + protected static final RemovalListener> REMOVAL_LISTENER = new RemovalListener>() { + @Override + public void onRemoval(final RemovalNotification> notification) { + if (!notification.getCause().equals(RemovalCause.EXPLICIT)) { + notification.getValue().discard(); + } + } + }; + + protected final Channel channel; + protected final InetSocketAddress address; + protected boolean disconnectOccured = false; + protected final ChannelOutboundQueue output; + + /** expiring cache for future rpcResponses */ + protected Cache> responseCache; + + + AbstractConnectionAdapter(@Nonnull final Channel channel, @Nullable final InetSocketAddress address) { + this.channel = Preconditions.checkNotNull(channel); + this.address = address; + + responseCache = CacheBuilder.newBuilder().concurrencyLevel(1) + .expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES).removalListener(REMOVAL_LISTENER).build(); + this.output = new ChannelOutboundQueue(channel, DEFAULT_QUEUE_DEPTH, address); + channel.pipeline().addLast(output); + } + + @Override + public Future disconnect() { + final ChannelFuture disconnectResult = channel.disconnect(); + responseCache.invalidateAll(); + disconnectOccured = true; + + return handleTransportChannelFuture(disconnectResult); + } + + @Override + public Future> barrier(final BarrierInput input) { + return sendToSwitchExpectRpcResultFuture(input, BarrierOutput.class, "barrier-input sending failed"); + } + + @Override + public Future> echo(final EchoInput input) { + return sendToSwitchExpectRpcResultFuture(input, EchoOutput.class, "echo-input sending failed"); + } + + @Override + public Future> echoReply(final EchoReplyInput input) { + return sendToSwitchFuture(input, "echo-reply sending failed"); + } + + @Override + public Future> experimenter(final ExperimenterInput input) { + return sendToSwitchFuture(input, "experimenter sending failed"); + } + + @Override + public Future> flowMod(final FlowModInput input) { + return sendToSwitchFuture(input, "flow-mod sending failed"); + } + + @Override + public Future> getConfig(final GetConfigInput input) { + return sendToSwitchExpectRpcResultFuture(input, GetConfigOutput.class, "get-config-input sending failed"); + } + + @Override + public Future> getFeatures(final GetFeaturesInput input) { + return sendToSwitchExpectRpcResultFuture(input, GetFeaturesOutput.class, "get-features-input sending failed"); + } + + @Override + public Future> getQueueConfig(final GetQueueConfigInput input) { + return sendToSwitchExpectRpcResultFuture(input, GetQueueConfigOutput.class, + "get-queue-config-input sending failed"); + } + + @Override + public Future> groupMod(final GroupModInput input) { + return sendToSwitchFuture(input, "group-mod-input sending failed"); + } + + @Override + public Future> hello(final HelloInput input) { + return sendToSwitchFuture(input, "hello-input sending failed"); + } + + @Override + public Future> meterMod(final MeterModInput input) { + return sendToSwitchFuture(input, "meter-mod-input sending failed"); + } + + @Override + public Future> packetOut(final PacketOutInput input) { + return sendToSwitchFuture(input, "packet-out-input sending failed"); + } + + @Override + public Future> multipartRequest(final MultipartRequestInput input) { + return sendToSwitchFuture(input, "multi-part-request sending failed"); + } + + @Override + public Future> portMod(final PortModInput input) { + return sendToSwitchFuture(input, "port-mod-input sending failed"); + } + + @Override + public Future> roleRequest(final RoleRequestInput input) { + return sendToSwitchExpectRpcResultFuture(input, RoleRequestOutput.class, + "role-request-config-input sending failed"); + } + + @Override + public Future> setConfig(final SetConfigInput input) { + return sendToSwitchFuture(input, "set-config-input sending failed"); + } + + @Override + public Future> tableMod(final TableModInput input) { + return sendToSwitchFuture(input, "table-mod-input sending failed"); + } + + @Override + public Future> getAsync(final GetAsyncInput input) { + return sendToSwitchExpectRpcResultFuture(input, GetAsyncOutput.class, "get-async-input sending failed"); + } + + @Override + public Future> setAsync(final SetAsyncInput input) { + return sendToSwitchFuture(input, "set-async-input sending failed"); + } + + @Override + public boolean isAlive() { + return channel.isOpen(); + } + + @Override + public boolean isAutoRead() { + return channel.config().isAutoRead(); + } + + @Override + public void setAutoRead(final boolean autoRead) { + channel.config().setAutoRead(autoRead); + } + + @Override + public InetSocketAddress getRemoteAddress() { + return (InetSocketAddress) channel.remoteAddress(); + } + + /** + * Used only for testing purposes + * @param cache replacement + */ + @VisibleForTesting + void setResponseCache(final Cache> cache) { + this.responseCache = cache; + } + + /** + * Return cached RpcListener or {@code null} if not cached + * @return + */ + protected ResponseExpectedRpcListener findRpcResponse(final RpcResponseKey key) { + return responseCache.getIfPresent(key); + } + + /** + * sends given message to switch, sending result or switch response will be reported via return value + * + * @param input message to send + * @param responseClazz type of response + * @param failureInfo describes, what type of message caused failure by sending + * @return future object, + *
    + *
  • if send fails, {@link RpcResult} will contain errors and failed status
  • + *
  • else {@link RpcResult} will be stored in responseCache and wait for particular timeout ( + * {@link ConnectionAdapterImpl#RPC_RESPONSE_EXPIRATION}), + *
      + *
    • either switch will manage to answer and then corresponding response message will be set into returned + * future
    • + *
    • or response in cache will expire and returned future will be cancelled
    • + *
    + *
  • + *
+ */ + protected ListenableFuture> sendToSwitchExpectRpcResultFuture( + final IN input, final Class responseClazz, final String failureInfo) { + final RpcResponseKey key = new RpcResponseKey(input.getXid(), responseClazz.getName()); + final ResponseExpectedRpcListener listener = new ResponseExpectedRpcListener<>(input, failureInfo, + responseCache, key); + return enqueueMessage(listener); + } + + /** + * sends given message to switch, sending result will be reported via return value + * + * @param input message to send + * @param failureInfo describes, what type of message caused failure by sending + * @return future object, + *
    + *
  • if send successful, {@link RpcResult} without errors and successful status will be returned,
  • + *
  • else {@link RpcResult} will contain errors and failed status
  • + *
+ */ + protected ListenableFuture> sendToSwitchFuture(final DataObject input, final String failureInfo) { + return enqueueMessage(new SimpleRpcListener(input, failureInfo)); + } + + private ListenableFuture> enqueueMessage(final AbstractRpcListener promise) { + LOG.debug("Submitting promise {}", promise); + + if (!output.enqueue(promise)) { + LOG.debug("Message queue is full, rejecting execution"); + promise.failedRpc(QUEUE_FULL_EXCEPTION); + } else { + LOG.debug("Promise enqueued successfully"); + } + + return promise.getResult(); + } + + /** + * @param resultFuture + * @param failureInfo + * @param errorSeverity + * @param message + * @return + */ + private static SettableFuture handleTransportChannelFuture(final ChannelFuture resultFuture) { + + final SettableFuture transportResult = SettableFuture.create(); + + resultFuture.addListener(new GenericFutureListener>() { + + @Override + public void operationComplete(final io.netty.util.concurrent.Future future) throws Exception { + transportResult.set(future.isSuccess()); + if (!future.isSuccess()) { + transportResult.setException(future.cause()); + } + } + }); + return transportResult; + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java new file mode 100644 index 00000000..730403b6 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +import com.google.common.util.concurrent.ListenableFuture; +import io.netty.channel.Channel; +import java.net.InetSocketAddress; +import java.util.concurrent.Future; +import org.opendaylight.openflowjava.statistics.CounterEventTypes; +import org.opendaylight.openflowjava.statistics.StatisticsCounters; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.common.RpcResult; + +/** + * Class is only wrapper for {@link AbstractConnectionAdapter} to provide statistics + * records for counting all needed RPC messages in Openflow Java. + */ +abstract class AbstractConnectionAdapterStatistics extends AbstractConnectionAdapter implements MessageConsumer { + + private final StatisticsCounters statisticsCounters; + + AbstractConnectionAdapterStatistics(final Channel channel, final InetSocketAddress address) { + super(channel, address); + statisticsCounters = StatisticsCounters.getInstance(); + } + + @Override + public Future> flowMod(final FlowModInput input) { + statisticsCounters.incrementCounter(CounterEventTypes.DS_FLOW_MODS_ENTERED); + return super.flowMod(input); + } + + @Override + protected ListenableFuture> sendToSwitchExpectRpcResultFuture( + final IN input, final Class responseClazz, final String failureInfo) { + statisticsCounters.incrementCounter(CounterEventTypes.DS_ENTERED_OFJAVA); + return super.sendToSwitchExpectRpcResultFuture(input, responseClazz, failureInfo); + } + + @Override + protected ListenableFuture> sendToSwitchFuture(final DataObject input, final String failureInfo) { + statisticsCounters.incrementCounter(CounterEventTypes.DS_ENTERED_OFJAVA); + return super.sendToSwitchFuture(input, failureInfo); + } + + @Override + public void consume(final DataObject message) { + if (Notification.class.isInstance(message)) { + if (!(DisconnectEvent.class.isInstance(message) || SwitchIdleEvent.class.isInstance(message))) { + statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); + } + } else if (OfHeader.class.isInstance(message)) { + statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); + } + consumeDeviceMessage(message); + } + + /** + * Method is equivalent to {@link MessageConsumer#consume(DataObject)} to prevent missing method + * in every children of {@link AbstractConnectionAdapterStatistics} class, because we overriding + * original method for {@link StatisticsCounters} + * + * @param message from device to processing + */ + protected abstract void consumeDeviceMessage(DataObject message); +} + diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java new file mode 100644 index 00000000..bec266bb --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +import com.google.common.base.Preconditions; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.InetSocketAddress; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.annotation.Nonnull; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class capsulate basic processing for stacking requests for netty channel + * and provide functionality for pairing request/response device message communication. + */ +abstract class AbstractOutboundQueueManager + extends ChannelInboundHandlerAdapter + implements AutoCloseable { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractOutboundQueueManager.class); + + private static enum PipelineState { + /** + * Netty thread is potentially idle, no assumptions + * can be made about its state. + */ + IDLE, + /** + * Netty thread is currently reading, once the read completes, + * if will flush the queue in the {@link #WRITING} state. + */ + READING, + /** + * Netty thread is currently performing a flush on the queue. + * It will then transition to {@link #IDLE} state. + */ + WRITING, + } + + /** + * Default low write watermark. Channel will become writable when number of outstanding + * bytes dips below this value. + */ + private static final int DEFAULT_LOW_WATERMARK = 128 * 1024; + + /** + * Default write high watermark. Channel will become un-writable when number of + * outstanding bytes hits this value. + */ + private static final int DEFAULT_HIGH_WATERMARK = DEFAULT_LOW_WATERMARK * 2; + + private final AtomicBoolean flushScheduled = new AtomicBoolean(); + protected final ConnectionAdapterImpl parent; + protected final InetSocketAddress address; + protected final O currentQueue; + private final T handler; + + // Accessed concurrently + private volatile PipelineState state = PipelineState.IDLE; + + // Updated from netty only + private boolean alreadyReading; + protected boolean shuttingDown; + + // Passed to executor to request triggering of flush + protected final Runnable flushRunnable = new Runnable() { + @Override + public void run() { + flush(); + } + }; + + AbstractOutboundQueueManager(final ConnectionAdapterImpl parent, final InetSocketAddress address, final T handler) { + this.parent = Preconditions.checkNotNull(parent); + this.handler = Preconditions.checkNotNull(handler); + this.address = address; + /* Note: don't wish to use reflection here */ + currentQueue = initializeStackedOutboudnqueue(); + LOG.debug("Queue manager instantiated with queue {}", currentQueue); + + handler.onConnectionQueueChanged(currentQueue); + } + + /** + * Method has to initialize some child of {@link AbstractStackedOutboundQueue} + * + * @return correct implementation of StacketOutboundqueue + */ + protected abstract O initializeStackedOutboudnqueue(); + + @Override + public void close() { + handler.onConnectionQueueChanged(null); + } + + @Override + public String toString() { + return String.format("Channel %s queue [flushing=%s]", parent.getChannel(), flushScheduled.get()); + } + + @Override + public void handlerAdded(final ChannelHandlerContext ctx) throws Exception { + /* + * Tune channel write buffering. We increase the writability window + * to ensure we can flush an entire queue segment in one go. We definitely + * want to keep the difference above 64k, as that will ensure we use jam-packed + * TCP packets. UDP will fragment as appropriate. + */ + ctx.channel().config().setWriteBufferHighWaterMark(DEFAULT_HIGH_WATERMARK); + ctx.channel().config().setWriteBufferLowWaterMark(DEFAULT_LOW_WATERMARK); + + super.handlerAdded(ctx); + } + + @Override + public void channelActive(final ChannelHandlerContext ctx) throws Exception { + super.channelActive(ctx); + conditionalFlush(); + } + + @Override + public void channelReadComplete(final ChannelHandlerContext ctx) throws Exception { + super.channelReadComplete(ctx); + + // Run flush regardless of writability. This is not strictly required, as + // there may be a scheduled flush. Instead of canceling it, which is expensive, + // we'll steal its work. Note that more work may accumulate in the time window + // between now and when the task will run, so it may not be a no-op after all. + // + // The reason for this is to fill the output buffer before we go into selection + // phase. This will make sure the pipe is full (in which case our next wake up + // will be the queue becoming writable). + writeAndFlush(); + alreadyReading = false; + } + + @Override + public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception { + super.channelWritabilityChanged(ctx); + + // The channel is writable again. There may be a flush task on the way, but let's + // steal its work, potentially decreasing latency. Since there is a window between + // now and when it will run, it may still pick up some more work to do. + LOG.debug("Channel {} writability changed, invoking flush", parent.getChannel()); + writeAndFlush(); + } + + @Override + public void channelInactive(final ChannelHandlerContext ctx) throws Exception { + // First of all, delegates disconnect event notification into ConnectionAdapter -> OF Plugin -> queue.close() + // -> queueHandler.onConnectionQueueChanged(null). The last call causes that no more entries are enqueued + // in the queue. + super.channelInactive(ctx); + + LOG.debug("Channel {} initiating shutdown...", ctx.channel()); + + // Then we start queue shutdown, start counting written messages (so that we don't keep sending messages + // indefinitely) and failing not completed entries. + shuttingDown = true; + final long entries = currentQueue.startShutdown(); + LOG.debug("Cleared {} queue entries from channel {}", entries, ctx.channel()); + + // Finally, we schedule flush task that will take care of unflushed entries. We also cover the case, + // when there is more than shutdownOffset messages enqueued in unflushed segments + // (AbstractStackedOutboundQueue#finishShutdown()). + scheduleFlush(); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception { + // Netty does not provide a 'start reading' callback, so this is our first + // (and repeated) chance to detect reading. Since this callback can be invoked + // multiple times, we keep a boolean we check. That prevents a volatile write + // on repeated invocations. It will be cleared in channelReadComplete(). + if (!alreadyReading) { + alreadyReading = true; + state = PipelineState.READING; + } + super.channelRead(ctx, msg); + } + + /** + * Invoked whenever a message comes in from the switch. Runs matching + * on all active queues in an attempt to complete a previous request. + * + * @param message Potential response message + * @return True if the message matched a previous request, false otherwise. + */ + boolean onMessage(final OfHeader message) { + LOG.trace("Attempting to pair message {} to a request", message); + + return currentQueue.pairRequest(message); + } + + T getHandler() { + return handler; + } + + void ensureFlushing() { + // If the channel is not writable, there's no point in waking up, + // once we become writable, we will run a full flush + if (!parent.getChannel().isWritable()) { + return; + } + + // We are currently reading something, just a quick sync to ensure we will in fact + // flush state. + final PipelineState localState = state; + LOG.debug("Synchronize on pipeline state {}", localState); + switch (localState) { + case READING: + // Netty thread is currently reading, it will flush the pipeline once it + // finishes reading. This is a no-op situation. + break; + case WRITING: + case IDLE: + default: + // We cannot rely on the change being flushed, schedule a request + scheduleFlush(); + } + } + + /** + * Method immediately response on Echo message. + * + * @param message incoming Echo message from device + */ + void onEchoRequest(final EchoRequestMessage message) { + final EchoReplyInput reply = new EchoReplyInputBuilder().setData(message.getData()) + .setVersion(message.getVersion()).setXid(message.getXid()).build(); + parent.getChannel().writeAndFlush(makeMessageListenerWrapper(reply)); + } + + /** + * Wraps outgoing message and includes listener attached to this message + * which is send to OFEncoder for serialization. Correct wrapper is + * selected by communication pipeline. + * + * @param message + * @param now + */ + void writeMessage(final OfHeader message, final long now) { + final Object wrapper = makeMessageListenerWrapper(message); + parent.getChannel().write(wrapper); + } + + /** + * Wraps outgoing message and includes listener attached to this message + * which is send to OFEncoder for serialization. Correct wrapper is + * selected by communication pipeline. + * + * @return + */ + protected Object makeMessageListenerWrapper(@Nonnull final OfHeader msg) { + Preconditions.checkArgument(msg != null); + + if (address == null) { + return new MessageListenerWrapper(msg, LOG_ENCODER_LISTENER); + } + return new UdpMessageListenerWrapper(msg, LOG_ENCODER_LISTENER, address); + } + + /* NPE are coming from {@link OFEncoder#encode} from catch block and we don't wish to lost it */ + private static final GenericFutureListener> LOG_ENCODER_LISTENER = new GenericFutureListener>() { + + private final Logger LOG = LoggerFactory.getLogger(GenericFutureListener.class); + + @Override + public void operationComplete(final Future future) throws Exception { + if (future.cause() != null) { + LOG.warn("Message encoding fail !", future.cause()); + } + } + }; + + /** + * Perform a single flush operation. We keep it here so we do not generate + * syntetic accessors for private fields. Otherwise it could be moved into {@link #flushRunnable}. + */ + protected void flush() { + // If the channel is gone, just flush whatever is not completed + if (!shuttingDown) { + LOG.trace("Dequeuing messages to channel {}", parent.getChannel()); + writeAndFlush(); + rescheduleFlush(); + } else { + close(); + if (currentQueue.finishShutdown(parent.getChannel())) { + LOG.debug("Channel {} shutdown complete", parent.getChannel()); + } else { + LOG.trace("Channel {} current queue not completely flushed yet", parent.getChannel()); + rescheduleFlush(); + } + } + } + + private void scheduleFlush() { + if (flushScheduled.compareAndSet(false, true)) { + LOG.trace("Scheduling flush task on channel {}", parent.getChannel()); + parent.getChannel().eventLoop().execute(flushRunnable); + } else { + LOG.trace("Flush task is already present on channel {}", parent.getChannel()); + } + } + + private void writeAndFlush() { + state = PipelineState.WRITING; + + final long start = System.nanoTime(); + + final int entries = currentQueue.writeEntries(parent.getChannel(), start); + if (entries > 0) { + LOG.trace("Flushing channel {}", parent.getChannel()); + parent.getChannel().flush(); + } + + if (LOG.isDebugEnabled()) { + final long stop = System.nanoTime(); + LOG.debug("Flushed {} messages to channel {} in {}us", entries, parent.getChannel(), + TimeUnit.NANOSECONDS.toMicros(stop - start)); + } + + state = PipelineState.IDLE; + } + + private void rescheduleFlush() { + /* + * We are almost ready to terminate. This is a bit tricky, because + * we do not want to have a race window where a message would be + * stuck on the queue without a flush being scheduled. + * So we mark ourselves as not running and then re-check if a + * flush out is needed. That will re-synchronized with other threads + * such that only one flush is scheduled at any given time. + */ + if (!flushScheduled.compareAndSet(true, false)) { + LOG.warn("Channel {} queue {} flusher found unscheduled", parent.getChannel(), this); + } + + conditionalFlush(); + } + + /** + * Schedule a queue flush if it is not empty and the channel is found + * to be writable. May only be called from Netty context. + */ + private void conditionalFlush() { + if (currentQueue.needsFlush()) { + if (shuttingDown || parent.getChannel().isWritable()) { + scheduleFlush(); + } else { + LOG.debug("Channel {} is not I/O ready, not scheduling a flush", parent.getChannel()); + } + } else { + LOG.trace("Queue is empty, no flush needed"); + } + } +} 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 new file mode 100644 index 00000000..b4356ee4 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +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"); + + @GuardedBy("unflushedSegments") + protected volatile StackedSegment firstSegment; + @GuardedBy("unflushedSegments") + protected final List unflushedSegments = new ArrayList<>(2); + @GuardedBy("unflushedSegments") + protected final List uncompletedSegments = new ArrayList<>(2); + + private volatile long lastXid = -1; + private volatile long allocatedXid = -1; + + @GuardedBy("unflushedSegments") + protected Integer shutdownOffset; + + // Accessed from Netty only + protected int flushOffset; + + protected final AbstractOutboundQueueManager manager; + + AbstractStackedOutboundQueue(final AbstractOutboundQueueManager manager) { + this.manager = Preconditions.checkNotNull(manager); + firstSegment = StackedSegment.create(0L); + uncompletedSegments.add(firstSegment); + 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; + LOG.debug("Queue {} slow offset {} maps to {} segments {}", this, offset, segmentOffset, unflushedSegments.size()); + + for (int i = unflushedSegments.size(); i <= segmentOffset; ++i) { + final StackedSegment newSegment = StackedSegment.create(first.getBaseXid() + (StackedSegment.SEGMENT_SIZE * i)); + LOG.debug("Adding segment {}", newSegment); + unflushedSegments.add(newSegment); + } + + allocatedXid = unflushedSegments.get(unflushedSegments.size() - 1).getEndXid(); + } + + /* + * This method is expected to be called from multiple threads concurrently. + */ + @Override + public Long reserveEntry() { + final long xid = LAST_XID_OFFSET_UPDATER.incrementAndGet(this); + final StackedSegment fastSegment = firstSegment; + + if (xid >= fastSegment.getBaseXid() + StackedSegment.SEGMENT_SIZE) { + if (xid >= allocatedXid) { + // Multiple segments, this a slow path + LOG.debug("Queue {} falling back to slow reservation for XID {}", this, xid); + + synchronized (unflushedSegments) { + LOG.debug("Queue {} executing slow reservation for XID {}", this, xid); + + // Shutdown was scheduled, need to fail the reservation + if (shutdownOffset != null) { + LOG.debug("Queue {} is being shutdown, failing reservation", this); + return null; + } + + // Ensure we have the appropriate segment for the specified XID + final StackedSegment slowSegment = firstSegment; + final int slowOffset = (int) (xid - slowSegment.getBaseXid()); + Verify.verify(slowOffset >= 0); + + // Now, we let's see if we need to allocate a new segment + ensureSegment(slowSegment, slowOffset); + + LOG.debug("Queue {} slow reservation finished", this); + } + } else { + LOG.debug("Queue {} XID {} is already backed", this, xid); + } + } + + LOG.trace("Queue {} allocated XID {}", this, xid); + return xid; + } + + /** + * Write some entries from the queue to the channel. Guaranteed to run + * in the corresponding EventLoop. + * + * @param channel Channel onto which we are writing + * @param now + * @return Number of entries written out + */ + int writeEntries(@Nonnull final Channel channel, final long now) { + // Local cache + StackedSegment segment = firstSegment; + int entries = 0; + + while (channel.isWritable()) { + final OutboundQueueEntry entry = segment.getEntry(flushOffset); + if (!entry.isCommitted()) { + LOG.debug("Queue {} XID {} segment {} offset {} not committed yet", this, segment.getBaseXid() + flushOffset, segment, flushOffset); + break; + } + + LOG.trace("Queue {} flushing entry at offset {}", this, flushOffset); + final OfHeader message = entry.takeMessage(); + flushOffset++; + entries++; + + if (message != null) { + manager.writeMessage(message, now); + } else { + entry.complete(null); + } + + if (flushOffset >= StackedSegment.SEGMENT_SIZE) { + /* + * Slow path: purge the current segment unless it's the last one. + * If it is, we leave it for replacement when a new reservation + * is run on it. + * + * This costs us two slow paths, but hey, this should be very rare, + * so let's keep things simple. + */ + synchronized (unflushedSegments) { + LOG.debug("Flush offset {} unflushed segments {}", flushOffset, unflushedSegments.size()); + + // We may have raced ahead of reservation code and need to allocate a segment + ensureSegment(segment, flushOffset); + + // Remove the segment, update the firstSegment and reset flushOffset + final StackedSegment oldSegment = unflushedSegments.remove(0); + if (oldSegment.isComplete()) { + uncompletedSegments.remove(oldSegment); + oldSegment.recycle(); + } + + // Reset the first segment and add it to the uncompleted list + segment = unflushedSegments.get(0); + uncompletedSegments.add(segment); + + // Update the shutdown offset + if (shutdownOffset != null) { + shutdownOffset -= StackedSegment.SEGMENT_SIZE; + } + + // Allow reservations back on the fast path by publishing the new first segment + firstSegment = segment; + + flushOffset = 0; + LOG.debug("Queue {} flush moved to segment {}", this, segment); + } + } + } + + return entries; + } + + boolean pairRequest(final OfHeader message) { + Iterator it = uncompletedSegments.iterator(); + while (it.hasNext()) { + final StackedSegment queue = it.next(); + final OutboundQueueEntry entry = queue.pairRequest(message); + if (entry == null) { + continue; + } + + LOG.trace("Queue {} accepted response {}", queue, message); + + // This has been a barrier request, we need to flush all + // previous queues + if (entry.isBarrier() && uncompletedSegments.size() > 1) { + LOG.trace("Queue {} indicated request was a barrier", queue); + + it = uncompletedSegments.iterator(); + while (it.hasNext()) { + final StackedSegment q = it.next(); + + // We want to complete all queues before the current one, we will + // complete the current queue below + if (!queue.equals(q)) { + LOG.trace("Queue {} is implied finished", q); + q.completeAll(); + it.remove(); + q.recycle(); + } else { + break; + } + } + } + + if (queue.isComplete()) { + LOG.trace("Queue {} is finished", queue); + it.remove(); + queue.recycle(); + } + + return true; + } + + LOG.debug("Failed to find completion for message {}", message); + return false; + } + + boolean needsFlush() { + // flushOffset always points to the first entry, which can be changed only + // from Netty, so we are fine here. + if (firstSegment.getBaseXid() + flushOffset > lastXid) { + return false; + } + + if (shutdownOffset != null && flushOffset >= shutdownOffset) { + return false; + } + + return firstSegment.getEntry(flushOffset).isCommitted(); + } + + long startShutdown() { + /* + * We are dealing with a multi-threaded shutdown, as the user may still + * be reserving entries in the queue. We are executing in a netty thread, + * so neither flush nor barrier can be running, which is good news. + * We will eat up all the slots in the queue here and mark the offset first + * reserved offset and free up all the cached queues. We then schedule + * the flush task, which will deal with the rest of the shutdown process. + */ + synchronized (unflushedSegments) { + // Increment the offset by the segment size, preventing fast path allocations, + // since we are holding the slow path lock, any reservations will see the queue + // in shutdown and fail accordingly. + final long xid = LAST_XID_OFFSET_UPDATER.addAndGet(this, StackedSegment.SEGMENT_SIZE); + shutdownOffset = (int) (xid - firstSegment.getBaseXid() - StackedSegment.SEGMENT_SIZE); + + // Fails all uncompleted entries, because they will never be completed due to disconnected channel. + return lockedFailSegments(uncompletedSegments.iterator()); + } + } + + /** + * Checks if the shutdown is in final phase -> all allowed entries (number of entries < shutdownOffset) are flushed + * and fails all not completed entries (if in final phase) + * @param channel netty channel + * @return true if in final phase, false if a flush is needed + */ + boolean finishShutdown(final Channel channel) { + boolean needsFlush; + synchronized (unflushedSegments) { + // Fails all entries, that were flushed in shutdownOffset (became uncompleted) + // - they will never be completed due to disconnected channel. + lockedFailSegments(uncompletedSegments.iterator()); + // If no further flush is needed or we are not able to write to channel anymore, then we fail all unflushed + // segments, so that each enqueued entry is reported as unsuccessful due to channel disconnection. + // No further entries should be enqueued by this time. + needsFlush = channel.isWritable() && needsFlush(); + if (!needsFlush) { + lockedFailSegments(unflushedSegments.iterator()); + } + } + return !needsFlush; + } + + protected OutboundQueueEntry getEntry(final Long xid) { + final StackedSegment fastSegment = firstSegment; + final long calcOffset = xid - fastSegment.getBaseXid(); + Preconditions.checkArgument(calcOffset >= 0, "Commit of XID %s does not match up with base XID %s", xid, fastSegment.getBaseXid()); + + Verify.verify(calcOffset <= Integer.MAX_VALUE); + final int fastOffset = (int) calcOffset; + + if (fastOffset >= StackedSegment.SEGMENT_SIZE) { + LOG.debug("Queue {} falling back to slow commit of XID {} at offset {}", this, xid, fastOffset); + + final StackedSegment segment; + final int slowOffset; + synchronized (unflushedSegments) { + final StackedSegment slowSegment = firstSegment; + final long slowCalcOffset = xid - slowSegment.getBaseXid(); + Verify.verify(slowCalcOffset >= 0 && slowCalcOffset <= Integer.MAX_VALUE); + slowOffset = (int) slowCalcOffset; + + LOG.debug("Queue {} recalculated offset of XID {} to {}", this, xid, slowOffset); + segment = unflushedSegments.get(slowOffset / StackedSegment.SEGMENT_SIZE); + } + + final int segOffset = slowOffset % StackedSegment.SEGMENT_SIZE; + LOG.debug("Queue {} slow commit of XID {} completed at offset {} (segment {} offset {})", this, xid, slowOffset, segment, segOffset); + return segment.getEntry(segOffset); + } + return fastSegment.getEntry(fastOffset); + } + + /** + * Fails not completed entries in segments and frees completed segments + * @param iterator list of segments to be failed + * @return number of failed entries + */ + @GuardedBy("unflushedSegments") + private long lockedFailSegments(Iterator iterator) { + long entries = 0; + + // Fail all queues + while (iterator.hasNext()) { + final StackedSegment segment = iterator.next(); + + entries += segment.failAll(OutboundQueueException.DEVICE_DISCONNECTED); + if (segment.isComplete()) { + LOG.trace("Cleared segment {}", segment); + iterator.remove(); + } + } + + return entries; + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java index a3ce3d5e..5845dff8 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java @@ -145,7 +145,7 @@ private void scheduleFlush(final EventExecutor executor) { */ private void conditionalFlush() { if (queue.isEmpty()) { - LOG.trace("Queue is empty, not flush needed"); + LOG.trace("Queue is empty, flush not needed"); return; } if (!channel.isWritable()) { diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java index 046e2917..1b0a83a7 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; -import java.net.InetSocketAddress; - import io.netty.channel.Channel; +import java.net.InetSocketAddress; /** * @author mirehak @@ -20,9 +19,11 @@ public interface ConnectionAdapterFactory { /** - * @param ch + * @param ch {@link Channel} channel + * @param address {@link InetSocketAddress} + * @param useBarrier * @return connection adapter tcp-implementation */ - ConnectionFacade createConnectionFacade(Channel ch, InetSocketAddress address) ; + ConnectionFacade createConnectionFacade(Channel ch, InetSocketAddress address, boolean useBarrier); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java index 5a67da8a..91871580 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; -import java.net.InetSocketAddress; - import io.netty.channel.Channel; +import java.net.InetSocketAddress; /** * @author mirehak @@ -24,8 +23,9 @@ public class ConnectionAdapterFactoryImpl implements ConnectionAdapterFactory { * @return connection adapter tcp-implementation */ @Override - public ConnectionFacade createConnectionFacade(Channel ch, InetSocketAddress address) { - return new ConnectionAdapterImpl(ch, address); + public ConnectionFacade createConnectionFacade(final Channel ch, final InetSocketAddress address, + final boolean useBarrier) { + return new ConnectionAdapterImpl(ch, address, useBarrier); } } 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 4a2d0b9d..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 @@ -10,267 +10,87 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; import com.google.common.base.Preconditions; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalCause; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.util.concurrent.GenericFutureListener; import java.net.InetSocketAddress; -import java.util.concurrent.Future; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; 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.openflowjava.statistics.CounterEventTypes; -import org.opendaylight.openflowjava.statistics.StatisticsCounters; -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.EchoInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.Notification; -import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * Handles messages (notifications + rpcs) and connections + * Handles messages (notifications + rpcs) and connections. * @author mirehak * @author michal.polkorab */ -public class ConnectionAdapterImpl implements ConnectionFacade { - /** after this time, RPC future response objects will be thrown away (in minutes) */ - public static final int RPC_RESPONSE_EXPIRATION = 1; +public class ConnectionAdapterImpl extends AbstractConnectionAdapterStatistics implements ConnectionFacade { - /** - * Default depth of write queue, e.g. we allow these many messages - * to be queued up before blocking producers. - */ - public static final int DEFAULT_QUEUE_DEPTH = 1024; - - private static final Logger LOG = LoggerFactory - .getLogger(ConnectionAdapterImpl.class); - private static final Exception QUEUE_FULL_EXCEPTION = - new RejectedExecutionException("Output queue is full"); - - private static final RemovalListener> REMOVAL_LISTENER = - new RemovalListener>() { - @Override - public void onRemoval( - final RemovalNotification> notification) { - if (! notification.getCause().equals(RemovalCause.EXPLICIT)) { - notification.getValue().discard(); - } - } - }; - - /** expiring cache for future rpcResponses */ - private Cache> responseCache; - - private final ChannelOutboundQueue output; - private final Channel channel; + private static final Logger LOG = LoggerFactory.getLogger(ConnectionAdapterImpl.class); private ConnectionReadyListener connectionReadyListener; private OpenflowProtocolListener messageListener; private SystemNotificationsListener systemListener; - private OutboundQueueManager outputManager; - private boolean disconnectOccured = false; - private final StatisticsCounters statisticsCounters; + private AlienMessageListener alienMessageListener; + private AbstractOutboundQueueManager outputManager; private OFVersionDetector versionDetector; - private final InetSocketAddress address; + + private final boolean useBarrier; /** - * default ctor + * Default constructor. * @param channel the channel to be set - used for communication * @param address client address (used only in case of UDP communication, - * as there is no need to store address over tcp (stable channel)) + * as there is no need to store address over tcp (stable channel)) + * @param useBarrier value is configurable by configSubsytem */ - public ConnectionAdapterImpl(final Channel channel, final InetSocketAddress address) { - responseCache = CacheBuilder.newBuilder() - .concurrencyLevel(1) - .expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) - .removalListener(REMOVAL_LISTENER).build(); - this.channel = Preconditions.checkNotNull(channel); - this.output = new ChannelOutboundQueue(channel, DEFAULT_QUEUE_DEPTH, address); - this.address = address; - channel.pipeline().addLast(output); - statisticsCounters = StatisticsCounters.getInstance(); - + public ConnectionAdapterImpl(final Channel channel, final InetSocketAddress address, final boolean useBarrier) { + super(channel, address); + this.useBarrier = useBarrier; LOG.debug("ConnectionAdapter created"); } @Override - public Future> barrier(final BarrierInput input) { - return sendToSwitchExpectRpcResultFuture( - input, BarrierOutput.class, "barrier-input sending failed"); - } - - @Override - public Future> echo(final EchoInput input) { - return sendToSwitchExpectRpcResultFuture( - input, EchoOutput.class, "echo-input sending failed"); - } - - @Override - public Future> echoReply(final EchoReplyInput input) { - return sendToSwitchFuture(input, "echo-reply sending failed"); - } - - @Override - public Future> experimenter(final ExperimenterInput input) { - return sendToSwitchFuture(input, "experimenter reply sending failed"); - } - - @Override - public Future> flowMod(final FlowModInput input) { - statisticsCounters.incrementCounter(CounterEventTypes.DS_FLOW_MODS_ENTERED); - return sendToSwitchFuture(input, "flow-mod sending failed"); - } - - @Override - public Future> getConfig(final GetConfigInput input) { - return sendToSwitchExpectRpcResultFuture( - input, GetConfigOutput.class, "get-config-input sending failed"); - } - - @Override - public Future> getFeatures( - final GetFeaturesInput input) { - return sendToSwitchExpectRpcResultFuture( - input, GetFeaturesOutput.class, "get-features-input sending failed"); - } - - @Override - public Future> getQueueConfig( - final GetQueueConfigInput input) { - return sendToSwitchExpectRpcResultFuture( - input, GetQueueConfigOutput.class, "get-queue-config-input sending failed"); - } - - @Override - public Future> groupMod(final GroupModInput input) { - return sendToSwitchFuture(input, "group-mod-input sending failed"); - } - - @Override - public Future> hello(final HelloInput input) { - return sendToSwitchFuture(input, "hello-input sending failed"); - } - - @Override - public Future> meterMod(final MeterModInput input) { - return sendToSwitchFuture(input, "meter-mod-input sending failed"); - } - - @Override - public Future> packetOut(final PacketOutInput input) { - return sendToSwitchFuture(input, "packet-out-input sending failed"); - } - - @Override - public Future> multipartRequest(final MultipartRequestInput input) { - return sendToSwitchFuture(input, "multi-part-request sending failed"); - } - - @Override - public Future> portMod(final PortModInput input) { - return sendToSwitchFuture(input, "port-mod-input sending failed"); - } - - @Override - public Future> roleRequest( - final RoleRequestInput input) { - return sendToSwitchExpectRpcResultFuture( - input, RoleRequestOutput.class, "role-request-config-input sending failed"); - } - - @Override - public Future> setConfig(final SetConfigInput input) { - return sendToSwitchFuture(input, "set-config-input sending failed"); - } - - @Override - public Future> tableMod(final TableModInput input) { - return sendToSwitchFuture(input, "table-mod-input sending failed"); - } - - @Override - public Future> getAsync(final GetAsyncInput input) { - return sendToSwitchExpectRpcResultFuture( - input, GetAsyncOutput.class, "get-async-input sending failed"); - } - - @Override - public Future> setAsync(final SetAsyncInput input) { - return sendToSwitchFuture(input, "set-async-input sending failed"); + public void setMessageListener(final OpenflowProtocolListener messageListener) { + this.messageListener = messageListener; } @Override - public Future disconnect() { - ChannelFuture disconnectResult = channel.disconnect(); - responseCache.invalidateAll(); - disconnectOccured = true; - - return handleTransportChannelFuture(disconnectResult); + public void setConnectionReadyListener(final ConnectionReadyListener connectionReadyListener) { + this.connectionReadyListener = connectionReadyListener; } @Override - public boolean isAlive() { - return channel.isOpen(); + public void setSystemListener(final SystemNotificationsListener systemListener) { + this.systemListener = systemListener; } @Override - public void setMessageListener(final OpenflowProtocolListener messageListener) { - this.messageListener = messageListener; + public void setAlienMessageListener(final AlienMessageListener alienMessageListener) { + this.alienMessageListener = alienMessageListener; } @Override - public void consume(final DataObject message) { + public void consumeDeviceMessage(final DataObject message) { LOG.debug("ConsumeIntern msg on {}", channel); - if (disconnectOccured ) { + if (disconnectOccured) { return; } if (message instanceof Notification) { @@ -282,169 +102,69 @@ public void consume(final DataObject message) { disconnectOccured = true; } else if (message instanceof SwitchIdleEvent) { systemListener.onSwitchIdleEvent((SwitchIdleEvent) message); - // OpenFlow messages + // OpenFlow messages } else if (message instanceof EchoRequestMessage) { if (outputManager != null) { outputManager.onEchoRequest((EchoRequestMessage) message); } else { messageListener.onEchoRequestMessage((EchoRequestMessage) message); } - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof ErrorMessage) { // Send only unmatched errors if (outputManager == null || !outputManager.onMessage((OfHeader) message)) { messageListener.onErrorMessage((ErrorMessage) message); } - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof ExperimenterMessage) { if (outputManager != null) { outputManager.onMessage((OfHeader) message); } messageListener.onExperimenterMessage((ExperimenterMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof FlowRemovedMessage) { messageListener.onFlowRemovedMessage((FlowRemovedMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof HelloMessage) { - LOG.info("Hello received / branch"); + LOG.info("Hello received"); messageListener.onHelloMessage((HelloMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof MultipartReplyMessage) { if (outputManager != null) { outputManager.onMessage((OfHeader) message); } messageListener.onMultipartReplyMessage((MultipartReplyMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof PacketInMessage) { messageListener.onPacketInMessage((PacketInMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else if (message instanceof PortStatusMessage) { messageListener.onPortStatusMessage((PortStatusMessage) message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); } else { LOG.warn("message listening not supported for type: {}", message.getClass()); } } else if (message instanceof OfHeader) { - LOG.debug("OFheader msg received"); + LOG.debug("OF header msg received"); + boolean found = false; if (outputManager == null || !outputManager.onMessage((OfHeader) message)) { - RpcResponseKey key = createRpcResponseKey((OfHeader) message); + final RpcResponseKey key = createRpcResponseKey((OfHeader) message); final ResponseExpectedRpcListener listener = findRpcResponse(key); if (listener != null) { - LOG.debug("corresponding rpcFuture found"); - listener.completed((OfHeader)message); - statisticsCounters.incrementCounter(CounterEventTypes.US_MESSAGE_PASS); - LOG.debug("after setting rpcFuture"); + found = true; + LOG.debug("Corresponding rpcFuture found"); + listener.completed((OfHeader) message); + LOG.debug("After setting rpcFuture"); responseCache.invalidate(key); - } else { - LOG.warn("received unexpected rpc response: {}", key); } } - } else { - LOG.warn("message listening not supported for type: {}", message.getClass()); - } - } - - private ListenableFuture> enqueueMessage(final AbstractRpcListener promise) { - LOG.debug("Submitting promise {}", promise); - if (!output.enqueue(promise)) { - LOG.debug("Message queue is full, rejecting execution"); - promise.failedRpc(QUEUE_FULL_EXCEPTION); + if (!found && alienMessageListener != null) { + LOG.debug("Alien message {} received", message.getImplementedInterface()); + alienMessageListener.onAlienMessage((OfHeader) message); + } } else { - LOG.debug("Promise enqueued successfully"); + LOG.warn("message listening not supported for type: {}", message.getClass()); } - - return promise.getResult(); - } - - /** - * sends given message to switch, sending result will be reported via return value - * @param input message to send - * @param failureInfo describes, what type of message caused failure by sending - * @return future object,
    - *
  • if send successful, {@link RpcResult} without errors and successful - * status will be returned,
  • - *
  • else {@link RpcResult} will contain errors and failed status
  • - *
- */ - private ListenableFuture> sendToSwitchFuture( - final DataObject input, final String failureInfo) { - statisticsCounters.incrementCounter(CounterEventTypes.DS_ENTERED_OFJAVA); - return enqueueMessage(new SimpleRpcListener(input, failureInfo)); - } - - /** - * sends given message to switch, sending result or switch response will be reported via return value - * @param input message to send - * @param responseClazz type of response - * @param failureInfo describes, what type of message caused failure by sending - * @return future object,
    - *
  • if send fails, {@link RpcResult} will contain errors and failed status
  • - *
  • else {@link RpcResult} will be stored in responseCache and wait for particular timeout - * ({@link ConnectionAdapterImpl#RPC_RESPONSE_EXPIRATION}), - *
    • either switch will manage to answer - * and then corresponding response message will be set into returned future
    • - *
    • or response in cache will expire and returned future will be cancelled
    - *
  • - *
- */ - private ListenableFuture> sendToSwitchExpectRpcResultFuture( - final IN input, final Class responseClazz, final String failureInfo) { - final RpcResponseKey key = new RpcResponseKey(input.getXid(), responseClazz.getName()); - final ResponseExpectedRpcListener listener = - new ResponseExpectedRpcListener<>(input, failureInfo, responseCache, key); - statisticsCounters.incrementCounter(CounterEventTypes.DS_ENTERED_OFJAVA); - return enqueueMessage(listener); - } - - /** - * @param resultFuture - * @param failureInfo - * @param errorSeverity - * @param message - * @return - */ - private static SettableFuture handleTransportChannelFuture( - final ChannelFuture resultFuture) { - - final SettableFuture transportResult = SettableFuture.create(); - - resultFuture.addListener(new GenericFutureListener>() { - - @Override - public void operationComplete( - final io.netty.util.concurrent.Future future) - throws Exception { - transportResult.set(future.isSuccess()); - if (!future.isSuccess()) { - transportResult.setException(future.cause()); - } - } - }); - return transportResult; } - /** - * @param message - * @return - */ private static RpcResponseKey createRpcResponseKey(final OfHeader message) { return new RpcResponseKey(message.getXid(), message.getImplementedInterface().getName()); } - /** - * @return - */ - private ResponseExpectedRpcListener findRpcResponse(final RpcResponseKey key) { - return responseCache.getIfPresent(key); - } - - @Override - public void setSystemListener(final SystemNotificationsListener systemListener) { - this.systemListener = systemListener; - } - @Override public void checkListeners() { final StringBuilder buffer = new StringBuilder(); @@ -474,43 +194,27 @@ public void run() { }).start(); } - @Override - public void setConnectionReadyListener( - final ConnectionReadyListener connectionReadyListener) { - this.connectionReadyListener = connectionReadyListener; - } - - @Override - public InetSocketAddress getRemoteAddress() { - return (InetSocketAddress) channel.remoteAddress(); - } - - /** - * Used only for testing purposes - * @param cache - */ - public void setResponseCache(final Cache> cache) { - this.responseCache = cache; - } - - @Override - public boolean isAutoRead() { - return channel.config().isAutoRead(); - } - - @Override - public void setAutoRead(final boolean autoRead) { - channel.config().setAutoRead(autoRead); - } - @Override public OutboundQueueHandlerRegistration registerOutboundQueueHandler( final T handler, final int maxQueueDepth, final long maxBarrierNanos) { Preconditions.checkState(outputManager == null, "Manager %s already registered", outputManager); - final OutboundQueueManager ret = new OutboundQueueManager<>(this, address, handler, maxQueueDepth, maxBarrierNanos); + final AbstractOutboundQueueManager ret; + if (useBarrier) { + ret = new OutboundQueueManager<>(this, address, handler, maxQueueDepth, maxBarrierNanos); + } else { + LOG.warn("OutboundQueueManager without barrier is started."); + ret = new OutboundQueueManagerNoBarrier<>(this, address, handler); + } + outputManager = ret; - channel.pipeline().addLast(outputManager); + /* we don't need it anymore */ + channel.pipeline().remove(output); + // OutboundQueueManager is put before DelegatingInboundHandler because otherwise channelInactive event would + // be first processed in OutboundQueueManager and then in ConnectionAdapter (and Openflowplugin). This might + // cause problems because we are shutting down the queue before Openflowplugin knows about it. + channel.pipeline().addBefore(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name(), + PipelineHandlers.CHANNEL_OUTBOUND_QUEUE_MANAGER.name(), outputManager); return new OutboundQueueHandlerRegistrationImpl(handler) { @Override 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 4b8820bd..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 @@ -7,30 +7,64 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +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) { - this.message = message; - this.callback = callback; - this.barrier = message instanceof BarrierInput; + commit(message, callback, DEFAULT_IS_COMPLETE); + } - // Volatile write, needs to be last - committed = true; + 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) { + callback.onFailure(lastException); + } + } else { + this.message = message; + this.callback = callback; + this.barrier = message instanceof BarrierInput; + this.isCompletedFunction = isCompletedFunction; + + // Volatile write, needs to be last + this.committed = true; + } } void reset() { @@ -57,22 +91,30 @@ boolean isCompleted() { OfHeader takeMessage() { final OfHeader ret = message; + if (!barrier) { + checkCompletionNeed(); + } message = null; return ret; } + private void checkCompletionNeed() { + if (callback == null || (message instanceof PacketOutInput)) { + completed = true; + if (callback != null) { + callback.onSuccess(null); + callback = null; + } + committed = false; + } + } + boolean complete(final OfHeader response) { Preconditions.checkState(!completed, "Attempted to complete a completed message with response %s", 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) { @@ -88,6 +130,7 @@ boolean complete(final OfHeader response) { void fail(final OutboundQueueException cause) { if (!completed) { + lastException = cause; completed = true; if (callback != null) { callback.onFailure(cause); @@ -97,4 +140,10 @@ void fail(final OutboundQueueException cause) { LOG.warn("Ignoring failure {} for completed message", cause); } } + + @VisibleForTesting + /** This method is only for testing to prove that after queue entry is completed there is not callback future */ + boolean hasCallback() { + return (callback != null); + } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java index ebf956f9..1769face 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java @@ -8,81 +8,25 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; import com.google.common.base.Preconditions; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.util.concurrent.Future; -import io.netty.util.concurrent.GenericFutureListener; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import javax.annotation.Nonnull; import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class OutboundQueueManager extends ChannelInboundHandlerAdapter implements AutoCloseable { - private static enum PipelineState { - /** - * Netty thread is potentially idle, no assumptions - * can be made about its state. - */ - IDLE, - /** - * Netty thread is currently reading, once the read completes, - * if will flush the queue in the {@link #FLUSHING} state. - */ - READING, - /** - * Netty thread is currently performing a flush on the queue. - * It will then transition to {@link #IDLE} state. - */ - WRITING, - } - +final class OutboundQueueManager extends + AbstractOutboundQueueManager { private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueManager.class); - /** - * Default low write watermark. Channel will become writable when number of outstanding - * bytes dips below this value. - */ - private static final int DEFAULT_LOW_WATERMARK = 128 * 1024; - - /** - * Default write high watermark. Channel will become un-writable when number of - * outstanding bytes hits this value. - */ - private static final int DEFAULT_HIGH_WATERMARK = DEFAULT_LOW_WATERMARK * 2; - - private final AtomicBoolean flushScheduled = new AtomicBoolean(); - private final StackedOutboundQueue currentQueue; - private final ConnectionAdapterImpl parent; - private final InetSocketAddress address; private final int maxNonBarrierMessages; private final long maxBarrierNanos; - private final T handler; - - // Accessed concurrently - private volatile PipelineState state = PipelineState.IDLE; // Updated from netty only - private boolean alreadyReading; private boolean barrierTimerEnabled; private long lastBarrierNanos = System.nanoTime(); private int nonBarrierMessages; - private boolean shuttingDown; - - // Passed to executor to request triggering of flush - private final Runnable flushRunnable = new Runnable() { - @Override - public void run() { - flush(); - } - }; // Passed to executor to request a periodic barrier check private final Runnable barrierRunnable = new Runnable() { @@ -94,26 +38,16 @@ public void run() { OutboundQueueManager(final ConnectionAdapterImpl parent, final InetSocketAddress address, final T handler, final int maxNonBarrierMessages, final long maxBarrierNanos) { - this.parent = Preconditions.checkNotNull(parent); - this.handler = Preconditions.checkNotNull(handler); + super(parent, address, handler); Preconditions.checkArgument(maxNonBarrierMessages > 0); this.maxNonBarrierMessages = maxNonBarrierMessages; Preconditions.checkArgument(maxBarrierNanos > 0); this.maxBarrierNanos = maxBarrierNanos; - this.address = address; - - currentQueue = new StackedOutboundQueue(this); - LOG.debug("Queue manager instantiated with queue {}", currentQueue); - handler.onConnectionQueueChanged(currentQueue); - } - - T getHandler() { - return handler; } @Override - public void close() { - handler.onConnectionQueueChanged(null); + protected StackedOutboundQueue initializeStackedOutboudnqueue() { + return new StackedOutboundQueue(this); } private void scheduleBarrierTimer(final long now) { @@ -136,33 +70,11 @@ private void scheduleBarrierMessage() { return; } - currentQueue.commitEntry(xid, handler.createBarrierRequest(xid), null); + currentQueue.commitEntry(xid, getHandler().createBarrierRequest(xid), null); LOG.trace("Barrier XID {} scheduled", xid); } - /** - * Invoked whenever a message comes in from the switch. Runs matching - * on all active queues in an attempt to complete a previous request. - * - * @param message Potential response message - * @return True if the message matched a previous request, false otherwise. - */ - boolean onMessage(final OfHeader message) { - LOG.trace("Attempting to pair message {} to a request", message); - - return currentQueue.pairRequest(message); - } - - private void scheduleFlush() { - if (flushScheduled.compareAndSet(false, true)) { - LOG.trace("Scheduling flush task on channel {}", parent.getChannel()); - parent.getChannel().eventLoop().execute(flushRunnable); - } else { - LOG.trace("Flush task is already present on channel {}", parent.getChannel()); - } - } - /** * Periodic barrier check. */ @@ -174,199 +86,14 @@ protected void barrier() { return; } - final long now = System.nanoTime(); - final long sinceLast = now - lastBarrierNanos; - if (sinceLast >= maxBarrierNanos) { - LOG.debug("Last barrier at {} now {}, elapsed {}", lastBarrierNanos, now, sinceLast); - // FIXME: we should be tracking requests/responses instead of this - if (nonBarrierMessages == 0) { - LOG.trace("No messages written since last barrier, not issuing one"); - } else { - scheduleBarrierMessage(); - } - } - } - - private void rescheduleFlush() { - /* - * We are almost ready to terminate. This is a bit tricky, because - * we do not want to have a race window where a message would be - * stuck on the queue without a flush being scheduled. - * - * So we mark ourselves as not running and then re-check if a - * flush out is needed. That will re-synchronized with other threads - * such that only one flush is scheduled at any given time. - */ - if (!flushScheduled.compareAndSet(true, false)) { - LOG.warn("Channel {} queue {} flusher found unscheduled", parent.getChannel(), this); - } - - conditionalFlush(); - } - - private void writeAndFlush() { - state = PipelineState.WRITING; - - final long start = System.nanoTime(); - - final int entries = currentQueue.writeEntries(parent.getChannel(), start); - if (entries > 0) { - LOG.trace("Flushing channel {}", parent.getChannel()); - parent.getChannel().flush(); - } - - if (LOG.isDebugEnabled()) { - final long stop = System.nanoTime(); - LOG.debug("Flushed {} messages to channel {} in {}us", entries, - parent.getChannel(), TimeUnit.NANOSECONDS.toMicros(stop - start)); - } - - state = PipelineState.IDLE; - } - - /** - * Perform a single flush operation. We keep it here so we do not generate - * syntetic accessors for private fields. Otherwise it could be moved into - * {@link #flushRunnable}. - */ - protected void flush() { - // If the channel is gone, just flush whatever is not completed - if (!shuttingDown) { - LOG.trace("Dequeuing messages to channel {}", parent.getChannel()); - writeAndFlush(); - rescheduleFlush(); - } else if (currentQueue.finishShutdown()) { - handler.onConnectionQueueChanged(null); - LOG.debug("Channel {} shutdown complete", parent.getChannel()); + if (currentQueue.isBarrierNeeded()) { + LOG.trace("Sending a barrier message"); + scheduleBarrierMessage(); } else { - LOG.trace("Channel {} current queue not completely flushed yet", parent.getChannel()); - rescheduleFlush(); + LOG.trace("Barrier not needed, not issuing one"); } } - /** - * Schedule a queue flush if it is not empty and the channel is found - * to be writable. May only be called from Netty context. - */ - private void conditionalFlush() { - if (currentQueue.needsFlush()) { - if (shuttingDown || parent.getChannel().isWritable()) { - scheduleFlush(); - } else { - LOG.debug("Channel {} is not I/O ready, not scheduling a flush", parent.getChannel()); - } - } else { - LOG.trace("Queue is empty, no flush needed"); - } - } - - @Override - public void channelActive(final ChannelHandlerContext ctx) throws Exception { - super.channelActive(ctx); - conditionalFlush(); - } - - @Override - public void handlerAdded(final ChannelHandlerContext ctx) throws Exception { - /* - * Tune channel write buffering. We increase the writability window - * to ensure we can flush an entire queue segment in one go. We definitely - * want to keep the difference above 64k, as that will ensure we use jam-packed - * TCP packets. UDP will fragment as appropriate. - */ - ctx.channel().config().setWriteBufferHighWaterMark(DEFAULT_HIGH_WATERMARK); - ctx.channel().config().setWriteBufferLowWaterMark(DEFAULT_LOW_WATERMARK); - - super.handlerAdded(ctx); - } - - @Override - public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception { - super.channelWritabilityChanged(ctx); - - // The channel is writable again. There may be a flush task on the way, but let's - // steal its work, potentially decreasing latency. Since there is a window between - // now and when it will run, it may still pick up some more work to do. - LOG.debug("Channel {} writability changed, invoking flush", parent.getChannel()); - writeAndFlush(); - } - - @Override - public void channelInactive(final ChannelHandlerContext ctx) throws Exception { - super.channelInactive(ctx); - - LOG.debug("Channel {} initiating shutdown...", ctx.channel()); - - shuttingDown = true; - final long entries = currentQueue.startShutdown(ctx.channel()); - LOG.debug("Cleared {} queue entries from channel {}", entries, ctx.channel()); - - scheduleFlush(); - } - - @Override - public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception { - // Netty does not provide a 'start reading' callback, so this is our first - // (and repeated) chance to detect reading. Since this callback can be invoked - // multiple times, we keep a boolean we check. That prevents a volatile write - // on repeated invocations. It will be cleared in channelReadComplete(). - if (!alreadyReading) { - alreadyReading = true; - state = PipelineState.READING; - } - super.channelRead(ctx, msg); - } - - @Override - public void channelReadComplete(final ChannelHandlerContext ctx) throws Exception { - super.channelReadComplete(ctx); - - // Run flush regardless of writability. This is not strictly required, as - // there may be a scheduled flush. Instead of canceling it, which is expensive, - // we'll steal its work. Note that more work may accumulate in the time window - // between now and when the task will run, so it may not be a no-op after all. - // - // The reason for this is to will the output buffer before we go into selection - // phase. This will make sure the pipe is full (in which case our next wake up - // will be the queue becoming writable). - writeAndFlush(); - } - - @Override - public String toString() { - return String.format("Channel %s queue [flushing=%s]", parent.getChannel(), flushScheduled.get()); - } - - void ensureFlushing() { - // If the channel is not writable, there's no point in waking up, - // once we become writable, we will run a full flush - if (!parent.getChannel().isWritable()) { - return; - } - - // We are currently reading something, just a quick sync to ensure we will in fact - // flush state. - final PipelineState localState = state; - LOG.debug("Synchronize on pipeline state {}", localState); - switch (localState) { - case READING: - // Netty thread is currently reading, it will flush the pipeline once it - // finishes reading. This is a no-op situation. - break; - case WRITING: - case IDLE: - default: - // We cannot rely on the change being flushed, schedule a request - scheduleFlush(); - } - } - - void onEchoRequest(final EchoRequestMessage message) { - final EchoReplyInput reply = new EchoReplyInputBuilder().setData(message.getData()) - .setVersion(message.getVersion()).setXid(message.getXid()).build(); - parent.getChannel().writeAndFlush(makeMessageListenerWrapper(reply)); - } - /** * Write a message into the underlying channel. * @@ -377,10 +104,9 @@ void onEchoRequest(final EchoRequestMessage message) { * measure System.nanoTime() for each barrier -- needlessly * adding overhead. */ + @Override void writeMessage(final OfHeader message, final long now) { - final Object wrapper = makeMessageListenerWrapper(message); - parent.getChannel().write(wrapper); - + super.writeMessage(message, now); if (message instanceof BarrierInput) { LOG.trace("Barrier message seen, resetting counters"); nonBarrierMessages = 0; @@ -395,33 +121,4 @@ void writeMessage(final OfHeader message, final long now) { } } } - - /** - * Wraps outgoing message and includes listener attached to this message - * which is send to OFEncoder for serialization. Correct wrapper is - * selected by communication pipeline. - * - * @return - */ - private Object makeMessageListenerWrapper(@Nonnull final OfHeader msg) { - Preconditions.checkArgument(msg != null); - - if (address == null) { - return new MessageListenerWrapper(msg, LOG_ENCODER_LISTENER); - } - return new UdpMessageListenerWrapper(msg, LOG_ENCODER_LISTENER, address); - } - - /* NPE are coming from {@link OFEncoder#encode} from catch block and we don't wish to lost it */ - private static final GenericFutureListener> LOG_ENCODER_LISTENER = new GenericFutureListener>() { - - private final Logger LOGGER = LoggerFactory.getLogger("LogEncoderListener"); - - @Override - public void operationComplete(final Future future) throws Exception { - if (future.cause() != null) { - LOGGER.warn("Message encoding fail !", future.cause()); - } - } - }; } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java new file mode 100644 index 00000000..1fc51473 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +import java.net.InetSocketAddress; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; + +/** + * + * @param + */ +public class OutboundQueueManagerNoBarrier extends + AbstractOutboundQueueManager { + + OutboundQueueManagerNoBarrier(final ConnectionAdapterImpl parent, final InetSocketAddress address, final T handler) { + super(parent, address, handler); + } + + @Override + protected StackedOutboundQueueNoBarrier initializeStackedOutboudnqueue() { + return new StackedOutboundQueueNoBarrier(this); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java index 9cd482b1..050f3cf7 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java @@ -68,6 +68,8 @@ public boolean equals(Object obj) { } } else if (!outputClazz.equals(other.outputClazz)) { return false; + } else if (xid != other.getXid()) { + return false; } return true; } 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 efe71aa7..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 @@ -7,143 +7,35 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; -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 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 java.util.function.Function; + import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class StackedOutboundQueue implements OutboundQueue { +final class StackedOutboundQueue extends AbstractStackedOutboundQueue { private static final Logger LOG = LoggerFactory.getLogger(StackedOutboundQueue.class); private static final AtomicLongFieldUpdater BARRIER_XID_UPDATER = AtomicLongFieldUpdater.newUpdater(StackedOutboundQueue.class, "barrierXid"); - private static final AtomicLongFieldUpdater LAST_XID_UPDATER = AtomicLongFieldUpdater.newUpdater(StackedOutboundQueue.class, "lastXid"); - @GuardedBy("unflushedSegments") - private volatile StackedSegment firstSegment; - @GuardedBy("unflushedSegments") - private final List unflushedSegments = new ArrayList<>(2); - @GuardedBy("unflushedSegments") - private final List uncompletedSegments = new ArrayList<>(2); - private final OutboundQueueManager manager; - - private volatile long allocatedXid = -1; private volatile long barrierXid = -1; - private volatile long lastXid = -1; - - @GuardedBy("unflushedSegments") - private Integer shutdownOffset; - - // Accessed from Netty only - private int flushOffset; - - StackedOutboundQueue(final OutboundQueueManager manager) { - this.manager = Preconditions.checkNotNull(manager); - firstSegment = StackedSegment.create(0L); - uncompletedSegments.add(firstSegment); - unflushedSegments.add(firstSegment); - } - - @GuardedBy("unflushedSegments") - private void ensureSegment(final StackedSegment first, final int offset) { - final int segmentOffset = offset / StackedSegment.SEGMENT_SIZE; - LOG.debug("Queue {} slow offset {} maps to {} segments {}", this, offset, segmentOffset, unflushedSegments.size()); - - for (int i = unflushedSegments.size(); i <= segmentOffset; ++i) { - final StackedSegment newSegment = StackedSegment.create(first.getBaseXid() + (StackedSegment.SEGMENT_SIZE * i)); - LOG.debug("Adding segment {}", newSegment); - unflushedSegments.add(newSegment); - } - - allocatedXid = uncompletedSegments.get(uncompletedSegments.size() - 1).getEndXid(); - } - - /* - * This method is expected to be called from multiple threads concurrently. - */ - @Override - public Long reserveEntry() { - final long xid = LAST_XID_UPDATER.incrementAndGet(this); - final StackedSegment fastSegment = firstSegment; - - if (xid >= fastSegment.getBaseXid() + StackedSegment.SEGMENT_SIZE) { - if (xid >= allocatedXid) { - // Multiple segments, this a slow path - LOG.debug("Queue {} falling back to slow reservation for XID {}", this, xid); - - synchronized (unflushedSegments) { - LOG.debug("Queue {} executing slow reservation for XID {}", this, xid); - - // Shutdown was scheduled, need to fail the reservation - if (shutdownOffset != null) { - LOG.debug("Queue {} is being shutdown, failing reservation", this); - return null; - } - - // Ensure we have the appropriate segment for the specified XID - final StackedSegment slowSegment = firstSegment; - final int slowOffset = (int) (xid - slowSegment.getBaseXid()); - Verify.verify(slowOffset >= 0); - - // Now, we let's see if we need to allocate a new segment - ensureSegment(slowSegment, slowOffset); - - LOG.debug("Queue {} slow reservation finished", this); - } - } else { - LOG.debug("Queue {} XID {} is already backed", this, xid); - } - } - LOG.trace("Queue {} allocated XID {}", this, xid); - return xid; + StackedOutboundQueue(final AbstractOutboundQueueManager manager) { + super(manager); } /* * This method is expected to be called from multiple threads concurrently */ @Override - public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback) { - final StackedSegment fastSegment = firstSegment; - final long calcOffset = xid - fastSegment.getBaseXid(); - Preconditions.checkArgument(calcOffset >= 0, "Commit of XID %s does not match up with base XID %s", xid, fastSegment.getBaseXid()); - - Verify.verify(calcOffset <= Integer.MAX_VALUE); - final int fastOffset = (int) calcOffset; - - final OutboundQueueEntry entry; - if (fastOffset >= StackedSegment.SEGMENT_SIZE) { - LOG.debug("Queue {} falling back to slow commit of XID {} at offset {}", this, xid, fastOffset); - - final StackedSegment segment; - final int slowOffset; - synchronized (unflushedSegments) { - final StackedSegment slowSegment = firstSegment; - final long slowCalcOffset = xid - slowSegment.getBaseXid(); - Verify.verify(slowCalcOffset >= 0 && slowCalcOffset <= Integer.MAX_VALUE); - slowOffset = (int) slowCalcOffset; + public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback, + final Function isCompletedFunction) { + final OutboundQueueEntry entry = getEntry(xid); - LOG.debug("Queue {} recalculated offset of XID {} to {}", this, xid, slowOffset); - segment = unflushedSegments.get(slowOffset / StackedSegment.SEGMENT_SIZE); - } - - final int segOffset = slowOffset % StackedSegment.SEGMENT_SIZE; - entry = segment.getEntry(segOffset); - LOG.debug("Queue {} slow commit of XID {} completed at offset {} (segment {} offset {})", this, xid, slowOffset, segment, segOffset); - } else { - entry = fastSegment.getEntry(fastOffset); - } - - entry.commit(message, callback); + entry.commit(message, callback, isCompletedFunction); if (entry.isBarrier()) { long my = xid; for (;;) { @@ -163,196 +55,25 @@ public void commitEntry(final Long xid, final OfHeader message, final FutureCall manager.ensureFlushing(); } - /** - * Write some entries from the queue to the channel. Guaranteed to run - * in the corresponding EventLoop. - * - * @param channel Channel onto which we are writing - * @param now - * @return Number of entries written out - */ - int writeEntries(@Nonnull final Channel channel, final long now) { - // Local cache - StackedSegment segment = firstSegment; - int entries = 0; - - while (channel.isWritable()) { - final OutboundQueueEntry entry = segment.getEntry(flushOffset); - if (!entry.isCommitted()) { - LOG.debug("Queue {} XID {} segment {} offset {} not committed yet", this, segment.getBaseXid() + flushOffset, segment, flushOffset); - break; - } - - LOG.trace("Queue {} flushing entry at offset {}", this, flushOffset); - final OfHeader message = entry.takeMessage(); - flushOffset++; - entries++; - - if (message != null) { - manager.writeMessage(message, now); - } else { - entry.complete(null); - } - - if (flushOffset >= StackedSegment.SEGMENT_SIZE) { - /* - * Slow path: purge the current segment unless it's the last one. - * If it is, we leave it for replacement when a new reservation - * is run on it. - * - * This costs us two slow paths, but hey, this should be very rare, - * so let's keep things simple. - */ - synchronized (unflushedSegments) { - LOG.debug("Flush offset {} unflushed segments {}", flushOffset, unflushedSegments.size()); - - // We may have raced ahead of reservation code and need to allocate a segment - ensureSegment(segment, flushOffset); - - // Remove the segment, update the firstSegment and reset flushOffset - final StackedSegment oldSegment = unflushedSegments.remove(0); - if (oldSegment.isComplete()) { - uncompletedSegments.remove(oldSegment); - oldSegment.recycle(); - } - - // Reset the first segment and add it to the uncompleted list - segment = unflushedSegments.get(0); - uncompletedSegments.add(segment); - - // Update the shutdown offset - if (shutdownOffset != null) { - shutdownOffset -= StackedSegment.SEGMENT_SIZE; - } - - // Allow reservations back on the fast path by publishing the new first segment - firstSegment = segment; - - flushOffset = 0; - LOG.debug("Queue {} flush moved to segment {}", this, segment); - } - } + Long reserveBarrierIfNeeded() { + if (isBarrierNeeded()) { + return reserveEntry(); } - - return entries; + return null; } - Long reserveBarrierIfNeeded() { + /** + * Checks if Barrier Request is the last message enqueued. If not, one needs + * to be scheduled in order to collect data about previous messages. + * @return true if last enqueued message is Barrier Request, false otherwise + */ + boolean isBarrierNeeded() { final long bXid = barrierXid; final long fXid = firstSegment.getBaseXid() + flushOffset; if (bXid >= fXid) { LOG.debug("Barrier found at XID {} (currently at {})", bXid, fXid); - return null; - } else { - return reserveEntry(); - } - } - - boolean pairRequest(final OfHeader message) { - Iterator it = uncompletedSegments.iterator(); - while (it.hasNext()) { - final StackedSegment queue = it.next(); - final OutboundQueueEntry entry = queue.pairRequest(message); - if (entry == null) { - continue; - } - - LOG.trace("Queue {} accepted response {}", queue, message); - - // This has been a barrier request, we need to flush all - // previous queues - if (entry.isBarrier() && uncompletedSegments.size() > 1) { - LOG.trace("Queue {} indicated request was a barrier", queue); - - it = uncompletedSegments.iterator(); - while (it.hasNext()) { - final StackedSegment q = it.next(); - - // We want to complete all queues before the current one, we will - // complete the current queue below - if (!queue.equals(q)) { - LOG.trace("Queue {} is implied finished", q); - q.completeAll(); - it.remove(); - q.recycle(); - } else { - break; - } - } - } - - if (queue.isComplete()) { - LOG.trace("Queue {} is finished", queue); - it.remove(); - queue.recycle(); - } - - return true; - } - - LOG.debug("Failed to find completion for message {}", message); - return false; - } - - long startShutdown(final Channel channel) { - /* - * We are dealing with a multi-threaded shutdown, as the user may still - * be reserving entries in the queue. We are executing in a netty thread, - * so neither flush nor barrier can be running, which is good news. - * - * We will eat up all the slots in the queue here and mark the offset first - * reserved offset and free up all the cached queues. We then schedule - * the flush task, which will deal with the rest of the shutdown process. - */ - synchronized (unflushedSegments) { - // Increment the offset by the segment size, preventing fast path allocations, - // since we are holding the slow path lock, any reservations will see the queue - // in shutdown and fail accordingly. - final long xid = LAST_XID_UPDATER.addAndGet(this, StackedSegment.SEGMENT_SIZE); - shutdownOffset = (int) (xid - firstSegment.getBaseXid() - StackedSegment.SEGMENT_SIZE); - - return lockedShutdownFlush(); - } - } - - @GuardedBy("unflushedSegments") - private long lockedShutdownFlush() { - long entries = 0; - - // Fail all queues - final Iterator it = uncompletedSegments.iterator(); - while (it.hasNext()) { - final StackedSegment segment = it.next(); - - entries += segment.failAll(OutboundQueueException.DEVICE_DISCONNECTED); - if (segment.isComplete()) { - LOG.trace("Cleared segment {}", segment); - it.remove(); - } - } - - return entries; - } - - boolean finishShutdown() { - synchronized (unflushedSegments) { - lockedShutdownFlush(); - } - - return !needsFlush(); - } - - boolean needsFlush() { - // flushOffset always points to the first entry, which can be changed only - // from Netty, so we are fine here. - if (firstSegment.getBaseXid() + flushOffset > lastXid) { return false; } - - if (shutdownOffset != null && flushOffset >= shutdownOffset) { - return false; - } - - return firstSegment.getEntry(flushOffset).isCommitted(); + return true; } } 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 new file mode 100644 index 00000000..76b1243a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.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; + +/** + * Class is designed for stacking Statistics and propagate immediate response for all + * another requests. + */ +public class StackedOutboundQueueNoBarrier extends AbstractStackedOutboundQueue { + + private static final Logger LOG = LoggerFactory.getLogger(StackedOutboundQueueNoBarrier.class); + + StackedOutboundQueueNoBarrier(final AbstractOutboundQueueManager manager) { + super(manager); + } + + /* + * This method is expected to be called from multiple threads concurrently + */ + @Override + 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, isCompletedFunction); + } else { + entry.commit(message, callback, isCompletedFunction); + } + + LOG.trace("Queue {} committed XID {}", this, xid); + manager.ensureFlushing(); + } + + @Override + int writeEntries(@Nonnull final Channel channel, final long now) { + // Local cache + StackedSegment segment = firstSegment; + int entries = 0; + + while (channel.isWritable()) { + final OutboundQueueEntry entry = segment.getEntry(flushOffset); + if (!entry.isCommitted()) { + LOG.debug("Queue {} XID {} segment {} offset {} not committed yet", this, segment.getBaseXid() + + flushOffset, segment, flushOffset); + break; + } + + LOG.trace("Queue {} flushing entry at offset {}", this, flushOffset); + final OfHeader message = entry.takeMessage(); + flushOffset++; + entries++; + + if (message != null) { + manager.writeMessage(message, now); + } else { + entry.complete(null); + } + + if (flushOffset >= StackedSegment.SEGMENT_SIZE) { + /* + * Slow path: purge the current segment unless it's the last one. + * If it is, we leave it for replacement when a new reservation + * is run on it. + * This costs us two slow paths, but hey, this should be very rare, + * so let's keep things simple. + */ + synchronized (unflushedSegments) { + LOG.debug("Flush offset {} unflushed segments {}", flushOffset, unflushedSegments.size()); + + // We may have raced ahead of reservation code and need to allocate a segment + ensureSegment(segment, flushOffset); + + // Remove the segment, update the firstSegment and reset flushOffset + final StackedSegment oldSegment = unflushedSegments.remove(0); + oldSegment.completeAll(); + uncompletedSegments.remove(oldSegment); + oldSegment.recycle(); + + // Reset the first segment and add it to the uncompleted list + segment = unflushedSegments.get(0); + uncompletedSegments.add(segment); + + // Update the shutdown offset + if (shutdownOffset != null) { + shutdownOffset -= StackedSegment.SEGMENT_SIZE; + } + + // Allow reservations back on the fast path by publishing the new first segment + firstSegment = segment; + + flushOffset = 0; + LOG.debug("Queue {} flush moved to segment {}", this, segment); + } + } + } + + return entries; + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java index b9030b81..43aa002a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java @@ -109,9 +109,17 @@ private static boolean completeEntry(final OutboundQueueEntry entry, final OfHea LOG.debug("Device-reported request XID {} failed {}:{}", response.getXid(), err.getTypeString(), err.getCodeString()); entry.fail(new DeviceRequestFailedException("Device-side failure", err)); return true; - } else { - return entry.complete(response); } + return entry.complete(response); + } + + OutboundQueueEntry findEntry(final long xid) { + if (! xidInRange(xid)) { + LOG.debug("Queue {} {}/{} ignoring XID {}", this, baseXid, entries.length, xid); + return null; + } + final int offset = (int)(xid - baseXid); + return entries[offset]; } OutboundQueueEntry pairRequest(final OfHeader response) { @@ -122,7 +130,7 @@ OutboundQueueEntry pairRequest(final OfHeader response) { return null; } - final int offset = (int)(xid - baseXid); + final int offset = (int) (xid - baseXid); final OutboundQueueEntry entry = entries[offset]; if (entry.isCompleted()) { LOG.debug("Entry {} already is completed, not accepting response {}", entry, response); @@ -172,6 +180,7 @@ int failAll(final OutboundQueueException cause) { if (!entry.isCompleted()) { entry.fail(cause); + completeCount++; ret++; } } @@ -184,7 +193,7 @@ boolean isComplete() { } void recycle() { - for (OutboundQueueEntry e : entries) { + for (final OutboundQueueEntry e : entries) { e.reset(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java new file mode 100644 index 00000000..33fc1ac1 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.FlowModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetAsyncRequestMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetFeaturesInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetQueueConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GroupModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.MeterModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.MultipartRequestInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10FeaturesRequestMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10FlowModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10GetQueueConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PacketOutInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PortModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10StatsRequestInputFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.PacketOutInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.PortModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.RoleRequestInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.SetAsyncInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.SetConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.TableModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.util.SimpleDeserializerRegistryHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; + +/** + * Util class for init registration of additional deserializers. + * @author giuseppex.petralia@intel.com + */ +public class AdditionalMessageDeserializerInitializer { + private AdditionalMessageDeserializerInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers additional message deserializers. + * @param registry registry to be filled with deserializers + */ + public static void registerMessageDeserializers(final DeserializerRegistry registry) { + SimpleDeserializerRegistryHelper helper; + + // register OF v1.0 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF10_VERSION_ID, registry); + helper.registerDeserializer(5, GetFeaturesInput.class, new OF10FeaturesRequestMessageFactory()); + helper.registerDeserializer(7, GetConfigInput.class, new GetConfigInputMessageFactory()); + helper.registerDeserializer(9, SetConfigInput.class, new SetConfigInputMessageFactory()); + helper.registerDeserializer(13, PacketOutInput.class, new OF10PacketOutInputMessageFactory()); + helper.registerDeserializer(14, FlowModInput.class, new OF10FlowModInputMessageFactory()); + helper.registerDeserializer(15, PortModInput.class, new OF10PortModInputMessageFactory()); + helper.registerDeserializer(16, MultipartRequestInput.class, new OF10StatsRequestInputFactory()); + helper.registerDeserializer(18, BarrierInput.class, new BarrierInputMessageFactory()); + helper.registerDeserializer(20, GetQueueConfigInput.class, new OF10GetQueueConfigInputMessageFactory()); + + // register OF v1.3 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF13_VERSION_ID, registry); + helper.registerDeserializer(5, GetFeaturesInput.class, new GetFeaturesInputMessageFactory()); + helper.registerDeserializer(7, GetConfigInput.class, new GetConfigInputMessageFactory()); + helper.registerDeserializer(9, SetConfigInput.class, new SetConfigInputMessageFactory()); + helper.registerDeserializer(13, PacketOutInput.class, new PacketOutInputMessageFactory()); + helper.registerDeserializer(14, FlowModInput.class, new FlowModInputMessageFactory()); + helper.registerDeserializer(15, GroupModInput.class, new GroupModInputMessageFactory()); + helper.registerDeserializer(16, PortModInput.class, new PortModInputMessageFactory()); + helper.registerDeserializer(17, TableModInput.class, new TableModInputMessageFactory()); + helper.registerDeserializer(18, MultipartRequestInput.class, new MultipartRequestInputMessageFactory()); + helper.registerDeserializer(20, BarrierInput.class, new BarrierInputMessageFactory()); + helper.registerDeserializer(22, GetQueueConfigInput.class, new GetQueueConfigInputMessageFactory()); + helper.registerDeserializer(24, RoleRequestInput.class, new RoleRequestInputMessageFactory()); + helper.registerDeserializer(26, GetAsyncInput.class, new GetAsyncRequestMessageFactory()); + helper.registerDeserializer(28, SetAsyncInput.class, new SetAsyncInputMessageFactory()); + helper.registerDeserializer(29, MeterModInput.class, new MeterModInputMessageFactory()); + + // register OF v1.4 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF14_VERSION_ID, registry); + helper.registerDeserializer(7, GetConfigInput.class, new GetConfigInputMessageFactory()); + helper.registerDeserializer(9, SetConfigInput.class, new SetConfigInputMessageFactory()); + helper.registerDeserializer(20, BarrierInput.class, new BarrierInputMessageFactory()); + + // register OF v1.5 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF15_VERSION_ID, registry); + helper.registerDeserializer(7, GetConfigInput.class, new GetConfigInputMessageFactory()); + helper.registerDeserializer(9, SetConfigInput.class, new SetConfigInputMessageFactory()); + helper.registerDeserializer(20, BarrierInput.class, new BarrierInputMessageFactory()); + } + +} 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 51e1ff6f..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,39 +8,42 @@ 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; /** * @author michal.polkorab * @author timotej.kubas + * @author giuseppex.petralia@intel.com */ 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); - messageClassMap = ImmutableMap.copyOf(temp); + TypeToClassMapInitializer.initializeTypeToClassMap(messageClassMap); + + // Register type to class map for additional deserializers + TypeToClassMapInitializer.initializeAdditionalTypeToClassMap(messageClassMap); } /** * Transforms ByteBuf into correct POJO message + * * @param rawMessage - * @param version version decoded from OpenFlow protocol message + * @param version + * version decoded from OpenFlow protocol message * @return correct POJO as DataObject */ public DataObject deserialize(final ByteBuf rawMessage, final short version) { @@ -48,12 +51,33 @@ public DataObject deserialize(final ByteBuf rawMessage, final short version) { int type = rawMessage.readUnsignedByte(); Class clazz = messageClassMap.get(new TypeToClassKey(version, type)); rawMessage.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); - OFDeserializer deserializer = registry.getDeserializer( - new MessageCodeKey(version, type, clazz)); + OFDeserializer deserializer = registry.getDeserializer(new MessageCodeKey(version, type, clazz)); dataObject = deserializer.deserialize(rawMessage); 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/DeserializerRegistryImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java index bbbb0681..7ba0f2c3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java @@ -24,11 +24,12 @@ /** * Stores and registers deserializers + * * @author michal.polkorab */ public class DeserializerRegistryImpl implements DeserializerRegistry { - private static final Logger LOGGER = LoggerFactory.getLogger(DeserializerRegistryImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(DeserializerRegistryImpl.class); private Map registry; /** @@ -37,14 +38,20 @@ public class DeserializerRegistryImpl implements DeserializerRegistry { @Override public void init() { registry = new HashMap<>(); + // register message deserializers MessageDeserializerInitializer.registerMessageDeserializers(this); + // register additional message deserializers + AdditionalMessageDeserializerInitializer.registerMessageDeserializers(this); + // register common structure deserializers - registerDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, - EncodeConstants.EMPTY_VALUE, MatchV10.class), new OF10MatchDeserializer()); - registerDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, - EncodeConstants.EMPTY_VALUE, Match.class), new MatchDeserializer()); + registerDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class), + new OF10MatchDeserializer()); + registerDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class), + new MatchDeserializer()); // register match entry deserializers MatchEntryDeserializerInitializer.registerMatchEntryDeserializers(this); @@ -56,8 +63,7 @@ public void init() { @Override @SuppressWarnings("unchecked") - public T getDeserializer( - MessageCodeKey key) { + public T getDeserializer(MessageCodeKey key) { OFGeneralDeserializer deserializer = registry.get(key); if (deserializer == null) { throw new IllegalStateException("Deserializer for key: " + key @@ -67,15 +73,14 @@ public T getDeserializer( } @Override - public void registerDeserializer(MessageCodeKey key, - OFGeneralDeserializer deserializer) { + public void registerDeserializer(MessageCodeKey key, OFGeneralDeserializer deserializer) { if ((key == null) || (deserializer == null)) { throw new IllegalArgumentException("MessageCodeKey or Deserializer is null"); } OFGeneralDeserializer desInRegistry = registry.put(key, deserializer); if (desInRegistry != null) { - LOGGER.debug("Deserializer for key {} overwritten. Old deserializer: {}, new deserializer: {}", - key, desInRegistry.getClass().getName(), deserializer.getClass().getName()); + LOG.debug("Deserializer for key {} overwritten. Old deserializer: {}, new deserializer: {}", key, + desInRegistry.getClass().getName(), deserializer.getClass().getName()); } if (deserializer instanceof DeserializerRegistryInjector) { ((DeserializerRegistryInjector) deserializer).injectDeserializerRegistry(this); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java index 21d9dcb1..98d1b34e 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java @@ -8,6 +8,8 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmArpOpDeserializer; import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmArpShaDeserializer; import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmArpSpaDeserializer; @@ -48,13 +50,12 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmUdpSrcDeserializer; import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmVlanPcpDeserializer; import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmVlanVidDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.ext.OnfOxmTcpFlagsDeserializer; import org.opendaylight.openflowjava.protocol.impl.util.MatchEntryDeserializerRegistryHelper; -import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; /** + * Util class for init registration of match entry deserializers. * @author michal.polkorab - * */ public final class MatchEntryDeserializerInitializer { @@ -63,7 +64,7 @@ private MatchEntryDeserializerInitializer() { } /** - * Registers match entry deserializers + * Registers match entry deserializers. * @param registry registry to be filled with deserializers */ public static void registerMatchEntryDeserializers(DeserializerRegistry registry) { @@ -111,5 +112,9 @@ public static void registerMatchEntryDeserializers(DeserializerRegistry registry helper.register(OxmMatchConstants.PBB_ISID, new OxmPbbIsidDeserializer()); helper.register(OxmMatchConstants.TUNNEL_ID, new OxmTunnelIdDeserializer()); helper.register(OxmMatchConstants.IPV6_EXTHDR, new OxmIpv6ExtHdrDeserializer()); + + // Register approved openflow match entry deserializers + helper.registerExperimenter(EncodeConstants.ONFOXM_ET_TCP_FLAGS, EncodeConstants.ONF_EXPERIMENTER_ID, + new OnfOxmTcpFlagsDeserializer()); } } 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 37f3a71f..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 @@ -20,13 +20,9 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetConfigReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.MultipartReplyMessageFactory; -import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10BarrierReplyMessageFactory; -import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10EchoReplyMessageFactory; -import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10EchoRequestMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10ErrorMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10FeaturesReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10FlowRemovedMessageFactory; -import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10GetConfigReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10HelloMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PacketInMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PortStatusMessageFactory; @@ -55,8 +51,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; /** + * Util class for init registration of deserializers. * @author michal.polkorab - * */ public final class MessageDeserializerInitializer { @@ -65,42 +61,60 @@ private MessageDeserializerInitializer() { } /** - * Registers message deserializers + * Registers message deserializers. * @param registry registry to be filled with deserializers */ - public static void registerMessageDeserializers(DeserializerRegistry registry) { + public static void registerMessageDeserializers(final DeserializerRegistry registry) { + SimpleDeserializerRegistryHelper helper; + // register OF v1.0 message deserializers - SimpleDeserializerRegistryHelper helper = - new SimpleDeserializerRegistryHelper(EncodeConstants.OF10_VERSION_ID, registry); - helper.registerDeserializer(0, null, HelloMessage.class, new OF10HelloMessageFactory()); - helper.registerDeserializer(1, null, ErrorMessage.class, new OF10ErrorMessageFactory()); - helper.registerDeserializer(2, null, EchoRequestMessage.class, new OF10EchoRequestMessageFactory()); - helper.registerDeserializer(3, null, EchoOutput.class, new OF10EchoReplyMessageFactory()); - helper.registerDeserializer(4, null, ExperimenterMessage.class, new VendorMessageFactory()); - helper.registerDeserializer(6, null, GetFeaturesOutput.class, new OF10FeaturesReplyMessageFactory()); - helper.registerDeserializer(8, null, GetConfigOutput.class, new OF10GetConfigReplyMessageFactory()); - helper.registerDeserializer(10, null, PacketInMessage.class, new OF10PacketInMessageFactory()); - helper.registerDeserializer(11, null, FlowRemovedMessage.class, new OF10FlowRemovedMessageFactory()); - helper.registerDeserializer(12, null, PortStatusMessage.class, new OF10PortStatusMessageFactory()); - helper.registerDeserializer(17, null, MultipartReplyMessage.class, new OF10StatsReplyMessageFactory()); - helper.registerDeserializer(19, null, BarrierOutput.class, new OF10BarrierReplyMessageFactory()); - helper.registerDeserializer(21, null, GetQueueConfigOutput.class, new OF10QueueGetConfigReplyMessageFactory()); - // register Of v1.3 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF10_VERSION_ID, registry); + helper.registerDeserializer(0, HelloMessage.class, new OF10HelloMessageFactory()); + helper.registerDeserializer(1, ErrorMessage.class, new OF10ErrorMessageFactory()); + helper.registerDeserializer(2, EchoRequestMessage.class, new EchoRequestMessageFactory()); + helper.registerDeserializer(3, EchoOutput.class, new EchoReplyMessageFactory()); + helper.registerDeserializer(4, ExperimenterMessage.class, new VendorMessageFactory()); + helper.registerDeserializer(6, GetFeaturesOutput.class, new OF10FeaturesReplyMessageFactory()); + helper.registerDeserializer(8, GetConfigOutput.class, new GetConfigReplyMessageFactory()); + helper.registerDeserializer(10, PacketInMessage.class, new OF10PacketInMessageFactory()); + helper.registerDeserializer(11, FlowRemovedMessage.class, new OF10FlowRemovedMessageFactory()); + helper.registerDeserializer(12, PortStatusMessage.class, new OF10PortStatusMessageFactory()); + helper.registerDeserializer(17, MultipartReplyMessage.class, new OF10StatsReplyMessageFactory()); + helper.registerDeserializer(19, BarrierOutput.class, new BarrierReplyMessageFactory()); + helper.registerDeserializer(21, GetQueueConfigOutput.class, new OF10QueueGetConfigReplyMessageFactory()); + + // register OF v1.3 message deserializers helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF13_VERSION_ID, registry); - helper.registerDeserializer(0, null, HelloMessage.class, new HelloMessageFactory()); - helper.registerDeserializer(1, null, ErrorMessage.class, new ErrorMessageFactory()); - helper.registerDeserializer(2, null, EchoRequestMessage.class, new EchoRequestMessageFactory()); - helper.registerDeserializer(3, null, EchoOutput.class, new EchoReplyMessageFactory()); - helper.registerDeserializer(4, null, ExperimenterMessage.class, new ExperimenterMessageFactory()); - helper.registerDeserializer(6, null, GetFeaturesOutput.class, new FeaturesReplyMessageFactory()); - helper.registerDeserializer(8, null, GetConfigOutput.class, new GetConfigReplyMessageFactory()); - helper.registerDeserializer(10, null, PacketInMessage.class, new PacketInMessageFactory()); - helper.registerDeserializer(11, null, FlowRemovedMessage.class, new FlowRemovedMessageFactory()); - helper.registerDeserializer(12, null, PortStatusMessage.class, new PortStatusMessageFactory()); - helper.registerDeserializer(19, null, MultipartReplyMessage.class, new MultipartReplyMessageFactory()); - helper.registerDeserializer(21, null, BarrierOutput.class, new BarrierReplyMessageFactory()); - helper.registerDeserializer(23, null, GetQueueConfigOutput.class, new QueueGetConfigReplyMessageFactory()); - helper.registerDeserializer(25, null, RoleRequestOutput.class, new RoleReplyMessageFactory()); - helper.registerDeserializer(27, null, GetAsyncOutput.class, new GetAsyncReplyMessageFactory()); + helper.registerDeserializer(0, HelloMessage.class, new HelloMessageFactory()); + helper.registerDeserializer(1, ErrorMessage.class, new ErrorMessageFactory()); + helper.registerDeserializer(2, EchoRequestMessage.class, new EchoRequestMessageFactory()); + helper.registerDeserializer(3, EchoOutput.class, new EchoReplyMessageFactory()); + helper.registerDeserializer(4, ExperimenterMessage.class, new ExperimenterMessageFactory()); + helper.registerDeserializer(6, GetFeaturesOutput.class, new FeaturesReplyMessageFactory()); + helper.registerDeserializer(8, GetConfigOutput.class, new GetConfigReplyMessageFactory()); + helper.registerDeserializer(10, PacketInMessage.class, new PacketInMessageFactory()); + helper.registerDeserializer(11, FlowRemovedMessage.class, new FlowRemovedMessageFactory()); + helper.registerDeserializer(12, PortStatusMessage.class, new PortStatusMessageFactory()); + helper.registerDeserializer(19, MultipartReplyMessage.class, new MultipartReplyMessageFactory()); + helper.registerDeserializer(21, BarrierOutput.class, new BarrierReplyMessageFactory()); + helper.registerDeserializer(23, GetQueueConfigOutput.class, new QueueGetConfigReplyMessageFactory()); + helper.registerDeserializer(25, RoleRequestOutput.class, new RoleReplyMessageFactory()); + helper.registerDeserializer(27, GetAsyncOutput.class, new GetAsyncReplyMessageFactory()); + + // register OF v1.4 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF14_VERSION_ID, registry); + helper.registerDeserializer(0, HelloMessage.class, new HelloMessageFactory()); + helper.registerDeserializer(2, EchoRequestMessage.class, new EchoRequestMessageFactory()); + helper.registerDeserializer(3, EchoOutput.class, new EchoReplyMessageFactory()); + helper.registerDeserializer(8, GetConfigOutput.class, new GetConfigReplyMessageFactory()); + helper.registerDeserializer(21, BarrierOutput.class, new BarrierReplyMessageFactory()); + + // register OF v1.5 message deserializers + helper = new SimpleDeserializerRegistryHelper(EncodeConstants.OF15_VERSION_ID, registry); + helper.registerDeserializer(0, HelloMessage.class, new HelloMessageFactory()); + helper.registerDeserializer(2, EchoRequestMessage.class, new EchoRequestMessageFactory()); + helper.registerDeserializer(3, EchoOutput.class, new EchoReplyMessageFactory()); + helper.registerDeserializer(8, GetConfigOutput.class, new GetConfigReplyMessageFactory()); + helper.registerDeserializer(21, BarrierOutput.class, new BarrierReplyMessageFactory()); } } 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 9ed52140..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 @@ -8,29 +8,44 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; /** + * Util class for init OF message type to class mapping. * @author michal.polkorab - * + * @author giuseppex.petralia@intel.com */ public final class TypeToClassMapInitializer { @@ -39,13 +54,14 @@ private TypeToClassMapInitializer() { } /** - * Initializes type to class map - * @param messageClassMap + * Initializes standard types mapping. + * @param messageClassMap type to class map */ - public static void initializeTypeToClassMap(Map> messageClassMap) { + public static void initializeTypeToClassMap(final Map> messageClassMap) { + TypeToClassInitHelper helper; + // init OF v1.0 mapping - TypeToClassInitHelper helper = - new TypeToClassInitHelper(EncodeConstants.OF10_VERSION_ID, messageClassMap); + helper = new TypeToClassInitHelper(EncodeConstants.OF10_VERSION_ID, messageClassMap); helper.registerTypeToClass((short) 0, HelloMessage.class); helper.registerTypeToClass((short) 1, ErrorMessage.class); helper.registerTypeToClass((short) 2, EchoRequestMessage.class); @@ -59,7 +75,8 @@ public static void initializeTypeToClassMap(Map> messag helper.registerTypeToClass((short) 17, MultipartReplyMessage.class); helper.registerTypeToClass((short) 19, BarrierOutput.class); helper.registerTypeToClass((short) 21, GetQueueConfigOutput.class); - // init OF v1.0 mapping + + // init OF v1.3 mapping helper = new TypeToClassInitHelper(EncodeConstants.OF13_VERSION_ID, messageClassMap); helper.registerTypeToClass((short) 0, HelloMessage.class); helper.registerTypeToClass((short) 1, ErrorMessage.class); @@ -76,5 +93,71 @@ public static void initializeTypeToClassMap(Map> messag helper.registerTypeToClass((short) 23, GetQueueConfigOutput.class); helper.registerTypeToClass((short) 25, RoleRequestOutput.class); helper.registerTypeToClass((short) 27, GetAsyncOutput.class); + + // init OF v1.4 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF14_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 0, HelloMessage.class); + helper.registerTypeToClass((short) 2, EchoRequestMessage.class); + helper.registerTypeToClass((short) 3, EchoOutput.class); + helper.registerTypeToClass((short) 8, GetConfigOutput.class); + helper.registerTypeToClass((short) 21, BarrierOutput.class); + + // init OF v1.5 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF15_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 0, HelloMessage.class); + helper.registerTypeToClass((short) 2, EchoRequestMessage.class); + helper.registerTypeToClass((short) 3, EchoOutput.class); + helper.registerTypeToClass((short) 8, GetConfigOutput.class); + helper.registerTypeToClass((short) 21, BarrierOutput.class); + } + + /** + * Initializes additional types mapping. + * @param messageClassMap type to class map + */ + public static void initializeAdditionalTypeToClassMap(final Map> messageClassMap) { + TypeToClassInitHelper helper; + + // init OF v1.0 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF10_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 5, GetFeaturesInput.class); + helper.registerTypeToClass((short) 7, GetConfigInput.class); + helper.registerTypeToClass((short) 9, SetConfigInput.class); + helper.registerTypeToClass((short) 13, PacketOutInput.class); + helper.registerTypeToClass((short) 14, FlowModInput.class); + helper.registerTypeToClass((short) 15, PortModInput.class); + helper.registerTypeToClass((short) 16, MultipartRequestInput.class); + helper.registerTypeToClass((short) 18, BarrierInput.class); + helper.registerTypeToClass((short) 20, GetQueueConfigInput.class); + + // init OF v1.3 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF13_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 5, GetFeaturesInput.class); + helper.registerTypeToClass((short) 7, GetConfigInput.class); + helper.registerTypeToClass((short) 9, SetConfigInput.class); + helper.registerTypeToClass((short) 13, PacketOutInput.class); + helper.registerTypeToClass((short) 14, FlowModInput.class); + helper.registerTypeToClass((short) 15, GroupModInput.class); + helper.registerTypeToClass((short) 16, PortModInput.class); + helper.registerTypeToClass((short) 17, TableModInput.class); + helper.registerTypeToClass((short) 18, MultipartRequestInput.class); + helper.registerTypeToClass((short) 20, BarrierInput.class); + helper.registerTypeToClass((short) 22, GetQueueConfigInput.class); + helper.registerTypeToClass((short) 24, RoleRequestInput.class); + helper.registerTypeToClass((short) 26, GetAsyncInput.class); + helper.registerTypeToClass((short) 28, SetAsyncInput.class); + helper.registerTypeToClass((short) 29, MeterModInput.class); + + // init OF v1.4 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF14_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 7, GetConfigInput.class); + helper.registerTypeToClass((short) 9, SetConfigInput.class); + helper.registerTypeToClass((short) 20, BarrierInput.class); + + // init OF v1.5 mapping + helper = new TypeToClassInitHelper(EncodeConstants.OF15_VERSION_ID, messageClassMap); + helper.registerTypeToClass((short) 7, GetConfigInput.class); + helper.registerTypeToClass((short) 9, SetConfigInput.class); + helper.registerTypeToClass((short) 20, BarrierInput.class); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java index 29f640f3..d212eee8 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java @@ -9,11 +9,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.dl.dst._case.SetDlDstActionBuilder; @@ -27,14 +25,12 @@ public class OF10SetDlDstActionDeserializer extends AbstractActionDeserializer { @Override - public Action deserialize(ByteBuf input) { + public Action deserialize(final ByteBuf input) { ActionBuilder builder = new ActionBuilder(); input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); SetDlDstCaseBuilder caseBuilder = new SetDlDstCaseBuilder(); SetDlDstActionBuilder actionBuilder = new SetDlDstActionBuilder(); - byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; - input.readBytes(address); - actionBuilder.setDlDstAddress(new MacAddress(ByteBufUtils.macAddressToString(address))); + actionBuilder.setDlDstAddress(ByteBufUtils.readIetfMacAddress(input)); caseBuilder.setSetDlDstAction(actionBuilder.build()); builder.setActionChoice(caseBuilder.build()); input.skipBytes(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java index 6e2428a4..9ca56a90 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java @@ -9,11 +9,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlSrcCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.dl.src._case.SetDlSrcActionBuilder; @@ -27,14 +25,12 @@ public class OF10SetDlSrcActionDeserializer extends AbstractActionDeserializer { @Override - public Action deserialize(ByteBuf input) { + public Action deserialize(final ByteBuf input) { ActionBuilder builder = new ActionBuilder(); input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); SetDlSrcCaseBuilder caseBuilder = new SetDlSrcCaseBuilder(); SetDlSrcActionBuilder actionBuilder = new SetDlSrcActionBuilder(); - byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; - input.readBytes(address); - actionBuilder.setDlSrcAddress(new MacAddress(ByteBufUtils.macAddressToString(address))); + actionBuilder.setDlSrcAddress(ByteBufUtils.readIetfMacAddress(input)); caseBuilder.setSetDlSrcAction(actionBuilder.build()); builder.setActionChoice(caseBuilder.build()); input.skipBytes(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java index 1bd01e86..14ea5fcc 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java @@ -9,10 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.dst._case.SetNwDstActionBuilder; @@ -31,7 +29,7 @@ public Action deserialize(final ByteBuf input) { input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); SetNwDstCaseBuilder caseBuilder = new SetNwDstCaseBuilder(); SetNwDstActionBuilder actionBuilder = new SetNwDstActionBuilder(); - actionBuilder.setIpAddress(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + actionBuilder.setIpAddress(ByteBufUtils.readIetfIpv4Address(input)); caseBuilder.setSetNwDstAction(actionBuilder.build()); builder.setActionChoice(caseBuilder.build()); return builder.build(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java index a5899c7a..9c982c21 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java @@ -9,10 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwSrcCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.src._case.SetNwSrcActionBuilder; @@ -31,7 +29,7 @@ public Action deserialize(final ByteBuf input) { input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); SetNwSrcCaseBuilder caseBuilder = new SetNwSrcCaseBuilder(); SetNwSrcActionBuilder actionBuilder = new SetNwSrcActionBuilder(); - actionBuilder.setIpAddress(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + actionBuilder.setIpAddress(ByteBufUtils.readIetfIpv4Address(input)); caseBuilder.setSetNwSrcAction(actionBuilder.build()); builder.setActionChoice(caseBuilder.build()); return builder.build(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java new file mode 100644 index 00000000..2af6be44 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; + +/** + * Translates BarrierRequest messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author giuseppex.petralia@intel.com + */ +public class BarrierInputMessageFactory extends VersionAssignableFactory implements OFDeserializer{ + + @Override + public BarrierInput deserialize(ByteBuf rawMessage) { + BarrierInputBuilder builder = new BarrierInputBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + return builder.build(); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java index 4c109ca6..4d5cf784 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java @@ -9,23 +9,23 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; /** - * Translates BarrierReply messages (both OpenFlow v1.0 and OpenFlow v1.3) + * Translates BarrierReply messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. * @author michal.polkorab * @author timotej.kubas */ -public class BarrierReplyMessageFactory implements OFDeserializer { +public class BarrierReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { @Override public BarrierOutput deserialize(ByteBuf rawMessage) { BarrierOutputBuilder builder = new BarrierOutputBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); return builder.build(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java index 8c8ba389..217071fb 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java @@ -9,27 +9,29 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder; /** - * Translates EchoReply messages (both OpenFlow v1.0 and OpenFlow v1.3) + * Translates EchoReply messages. + * OpenFlow protocol versions: 1.0, 1.3, 1.4, 1.5. * @author michal.polkorab * @author timotej.kubas */ -public class EchoReplyMessageFactory implements OFDeserializer { +public class EchoReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { @Override public EchoOutput deserialize(ByteBuf rawMessage) { EchoOutputBuilder builder = new EchoOutputBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); int remainingBytes = rawMessage.readableBytes(); if (remainingBytes > 0) { - builder.setData(rawMessage.readBytes(remainingBytes).array()); + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); } return builder.build(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java index 6e1e5597..a765a2d3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java @@ -9,25 +9,27 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; /** - * Translates EchoRequest messages (both OpenFlow v1.0 and OpenFlow v1.3) + * Translates EchoRequest messages. + * OpenFlow protocol versions: 1.0, 1.3, 1.4, 1.5. * @author michal.polkorab * @author timotej.kubas */ -public class EchoRequestMessageFactory implements OFDeserializer{ +public class EchoRequestMessageFactory extends VersionAssignableFactory implements OFDeserializer{ @Override public EchoRequestMessage deserialize(ByteBuf rawMessage) { EchoRequestMessageBuilder builder = new EchoRequestMessageBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); - builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array()); + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + builder.setData(data); return builder.build(); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java index daae3634..b11da58c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java @@ -63,8 +63,11 @@ public ErrorMessage deserialize(ByteBuf rawMessage) { } decodeType(builder, errorType, type); decodeCode(rawMessage, builder, errorType); - if (rawMessage.readableBytes() > 0) { - builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array()); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); } return builder.build(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java new file mode 100644 index 00000000..1531c8eb --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; + +/** + * Translates FlowModInput messages + */ +public class FlowModInputMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + + private static final byte PADDING = 2; + private DeserializerRegistry registry; + + @Override + public FlowModInput deserialize(ByteBuf rawMessage) { + FlowModInputBuilder builder = new FlowModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(cookie); + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookie_mask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(cookie_mask); + builder.setCookieMask(new BigInteger(1, cookie_mask)); + builder.setTableId(new TableId((long) rawMessage.readUnsignedByte())); + builder.setCommand(FlowModCommand.forValue(rawMessage.readUnsignedByte())); + builder.setIdleTimeout(rawMessage.readUnsignedShort()); + builder.setHardTimeout(rawMessage.readUnsignedShort()); + builder.setPriority(rawMessage.readUnsignedShort()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setOutPort(new PortNumber(rawMessage.readUnsignedInt())); + builder.setOutGroup(rawMessage.readUnsignedInt()); + builder.setFlags(createFlowModFlagsFromBitmap(rawMessage.readUnsignedShort())); + rawMessage.skipBytes(PADDING); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class)); + builder.setMatch(matchDeserializer.deserialize(rawMessage)); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List instructions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + rawMessage.readableBytes(), rawMessage, keyMaker, registry); + builder.setInstruction(instructions); + return builder.build(); + } + + private static FlowModFlags createFlowModFlagsFromBitmap(int input) { + final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0; + final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0; + final Boolean _oFPFFRESETCOUNTS = (input & (1 << 2)) > 0; + final Boolean _oFPFFNOPKTCOUNTS = (input & (1 << 3)) > 0; + final Boolean _oFPFFNOBYTCOUNTS = (input & (1 << 4)) > 0; + return new FlowModFlags(_oFPFFCHECKOVERLAP, _oFPFFNOBYTCOUNTS, _oFPFFNOPKTCOUNTS, _oFPFFRESETCOUNTS, + _oFPFFSENDFLOWREM); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java new file mode 100644 index 00000000..6a3485ec --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.protocol.rev130731.GetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetAsyncRequestMessageFactory implements OFDeserializer { + + @Override + public GetAsyncInput deserialize(ByteBuf rawMessage) { + GetAsyncInputBuilder builder = new GetAsyncInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + return builder.build(); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java new file mode 100644 index 00000000..84bb66fa --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInputBuilder; + +/** + * Translates GetConfigRequest messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author giuseppex.petralia@intel.com + */ +public class GetConfigInputMessageFactory extends VersionAssignableFactory implements OFDeserializer { + + @Override + public GetConfigInput deserialize(ByteBuf rawMessage) { + GetConfigInputBuilder builder = new GetConfigInputBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + return builder.build(); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java index dc6e11a0..c8c8071c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java @@ -9,24 +9,24 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutputBuilder; /** - * Translates GetConfigReply messages (both OpenFlow v1.0 and OpenFlow v1.3) + * Translates GetConfigReply messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. * @author michal.polkorab * @author timotej.kubas */ -public class GetConfigReplyMessageFactory implements OFDeserializer { +public class GetConfigReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { @Override public GetConfigOutput deserialize(ByteBuf rawMessage) { GetConfigOutputBuilder builder = new GetConfigOutputBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); builder.setFlags(SwitchConfigFlag.forValue(rawMessage.readUnsignedShort())); builder.setMissSendLen(rawMessage.readUnsignedShort()); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java similarity index 50% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactory.java rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java index ec45475e..4295644c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java @@ -1,37 +1,25 @@ /* - * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2015 NetIDE Consortium 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.factories; 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.protocol.rev130731.EchoOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; -/** - * Translates EchoReply messages (both OpenFlow v1.0 and OpenFlow v1.3) - * @author michal.polkorab - * @author timotej.kubas - */ -public class OF10EchoReplyMessageFactory implements OFDeserializer { +public class GetFeaturesInputMessageFactory implements OFDeserializer { @Override - public EchoOutput deserialize(ByteBuf rawMessage) { - EchoOutputBuilder builder = new EchoOutputBuilder(); - builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + public GetFeaturesInput deserialize(ByteBuf rawMessage) { + GetFeaturesInputBuilder builder = new GetFeaturesInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); builder.setXid(rawMessage.readUnsignedInt()); - int remainingBytes = rawMessage.readableBytes(); - if (remainingBytes > 0) { - builder.setData(rawMessage.readBytes(remainingBytes).array()); - } return builder.build(); } - -} +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java new file mode 100644 index 00000000..8b63dac5 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetQueueConfigInputMessageFactory implements OFDeserializer { + + @Override + public GetQueueConfigInput deserialize(ByteBuf rawMessage) { + GetQueueConfigInputBuilder builder = new GetQueueConfigInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setPort(new PortNumber(rawMessage.readUnsignedInt())); + return builder.build(); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java new file mode 100644 index 00000000..5d7de02b --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsListBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GroupModInputMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + + private DeserializerRegistry registry; + private static final byte PADDING = 1; + private static final byte PADDING_IN_BUCKETS_HEADER = 4; + private static final byte BUCKETS_HEADER_LENGTH = 16; + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } + + @Override + public GroupModInput deserialize(ByteBuf rawMessage) { + GroupModInputBuilder builder = new GroupModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setCommand(GroupModCommand.forValue(rawMessage.readUnsignedShort())); + builder.setType(GroupType.forValue(rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING); + builder.setGroupId(new GroupId(rawMessage.readUnsignedInt())); + List bucketsList = new ArrayList<>(); + while (rawMessage.readableBytes() > 0) { + BucketsListBuilder bucketsBuilder = new BucketsListBuilder(); + int bucketsLength = rawMessage.readUnsignedShort(); + bucketsBuilder.setWeight(rawMessage.readUnsignedShort()); + bucketsBuilder.setWatchPort(new PortNumber(rawMessage.readUnsignedInt())); + bucketsBuilder.setWatchGroup(rawMessage.readUnsignedInt()); + rawMessage.skipBytes(PADDING_IN_BUCKETS_HEADER); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + bucketsLength - BUCKETS_HEADER_LENGTH, rawMessage, keyMaker, registry); + bucketsBuilder.setAction(actions); + bucketsList.add(bucketsBuilder.build()); + } + builder.setBucketsList(bucketsList); + return builder.build(); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java index ca0a79c8..50cf33c1 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java @@ -9,12 +9,11 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import java.util.ArrayList; import java.util.List; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; @@ -22,17 +21,19 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.ElementsBuilder; /** - * Translates Hello messages + * Translates Hello messages. + * OF protocol versions: 1.3, 1.4, 1.5. * @author michal.polkorab * @author timotej.kubas */ -public class HelloMessageFactory implements OFDeserializer { +public class HelloMessageFactory extends VersionAssignableFactory implements OFDeserializer { private static final byte HELLO_ELEMENT_HEADER_SIZE = 4; + @Override public HelloMessage deserialize(ByteBuf rawMessage) { HelloMessageBuilder builder = new HelloMessageBuilder(); - builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); if (rawMessage.readableBytes() > 0) { builder.setElements(readElement(rawMessage)); @@ -70,7 +71,7 @@ private static List readVersionBitmap(int[] input){ for (int i = 0; i < input.length; i++) { int mask = input[i]; for (int j = 0; j < Integer.SIZE; j++) { - versionBitmapList.add((mask & (1<, DeserializerRegistryInjector { + + private DeserializerRegistry registry; + private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4; + private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3; + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } + + @Override + public MeterModInput deserialize(ByteBuf rawMessage) { + MeterModInputBuilder builder = new MeterModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setCommand(MeterModCommand.forValue(rawMessage.readUnsignedShort())); + builder.setFlags(createMeterFlags(rawMessage.readUnsignedShort())); + builder.setMeterId(new MeterId(rawMessage.readUnsignedInt())); + List bandsList = new ArrayList<>(); + while (rawMessage.readableBytes() > 0) { + BandsBuilder bandsBuilder = new BandsBuilder(); + int bandStartIndex = rawMessage.readerIndex(); + int bandType = rawMessage.readUnsignedShort(); + switch (bandType) { + case 1: + MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder(); + bandDropBuilder.setType(MeterBandType.forValue(bandType)); + rawMessage.readUnsignedShort(); + bandDropBuilder.setRate(rawMessage.readUnsignedInt()); + bandDropBuilder.setBurstSize(rawMessage.readUnsignedInt()); + rawMessage.skipBytes(PADDING_IN_METER_BAND_DROP_HEADER); + bandDropCaseBuilder.setMeterBandDrop(bandDropBuilder.build()); + bandsBuilder.setMeterBand(bandDropCaseBuilder.build()); + break; + case 2: + MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); + MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder(); + bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType)); + rawMessage.readUnsignedShort(); + bandDscpRemarkBuilder.setRate(rawMessage.readUnsignedInt()); + bandDscpRemarkBuilder.setBurstSize(rawMessage.readUnsignedInt()); + bandDscpRemarkBuilder.setPrecLevel(rawMessage.readUnsignedByte()); + rawMessage.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER); + bandDscpRemarkCaseBuilder.setMeterBandDscpRemark(bandDscpRemarkBuilder.build()); + bandsBuilder.setMeterBand(bandDscpRemarkCaseBuilder.build()); + break; + case 0xFFFF: + long expId = rawMessage + .getUnsignedInt(rawMessage.readerIndex() + 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES); + rawMessage.readerIndex(bandStartIndex); + OFDeserializer deserializer = registry + .getDeserializer(ExperimenterDeserializerKeyFactory + .createMeterBandDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId)); + bandsBuilder.setMeterBand(deserializer.deserialize(rawMessage)); + break; + } + bandsList.add(bandsBuilder.build()); + } + builder.setBands(bandsList); + return builder.build(); + } + + private static MeterFlags createMeterFlags(int input) { + final Boolean mfKBPS = (input & (1 << 0)) != 0; + final Boolean mfPKTPS = (input & (1 << 1)) != 0; + final Boolean mfBURST = (input & (1 << 2)) != 0; + final Boolean mfSTATS = (input & (1 << 3)) != 0; + return new MeterFlags(mfBURST, mfKBPS, mfPKTPS, mfSTATS); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java index 085a8565..62ebf38f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java @@ -22,7 +22,6 @@ import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty; @@ -182,7 +181,7 @@ public class MultipartReplyMessageFactory implements OFDeserializer flowStatsList = new ArrayList<>(); @@ -312,7 +311,7 @@ private MultipartReplyFlowCase setFlow(ByteBuf input) { return caseBuilder.build(); } - private static FlowModFlags createFlowModFlagsFromBitmap(int input) { + private static FlowModFlags createFlowModFlagsFromBitmap(final int input) { final Boolean fmfSENDFLOWREM = (input & (1 << 0)) != 0; final Boolean fmfCHECKOVERLAP = (input & (1 << 1)) != 0; final Boolean fmfRESETCOUNTS = (input & (1 << 2)) != 0; @@ -321,7 +320,7 @@ private static FlowModFlags createFlowModFlagsFromBitmap(int input) { return new FlowModFlags(fmfCHECKOVERLAP, fmfNOBYTCOUNTS, fmfNOPKTCOUNTS, fmfRESETCOUNTS, fmfSENDFLOWREM); } - private static MultipartReplyAggregateCase setAggregate(ByteBuf input) { + private static MultipartReplyAggregateCase setAggregate(final ByteBuf input) { MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder(); MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder(); byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; @@ -336,7 +335,7 @@ private static MultipartReplyAggregateCase setAggregate(ByteBuf input) { return caseBuilder.build(); } - private static MultipartReplyTableCase setTable(ByteBuf input) { + private static MultipartReplyTableCase setTable(final ByteBuf input) { MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder(); MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder(); List tableStatsList = new ArrayList<>(); @@ -358,7 +357,7 @@ private static MultipartReplyTableCase setTable(ByteBuf input) { return caseBuilder.build(); } - private MultipartReplyTableFeaturesCase setTableFeatures(ByteBuf input) { + private MultipartReplyTableFeaturesCase setTableFeatures(final ByteBuf input) { MultipartReplyTableFeaturesCaseBuilder caseBuilder = new MultipartReplyTableFeaturesCaseBuilder(); MultipartReplyTableFeaturesBuilder builder = new MultipartReplyTableFeaturesBuilder(); List features = new ArrayList<>(); @@ -385,12 +384,12 @@ private MultipartReplyTableFeaturesCase setTableFeatures(ByteBuf input) { return caseBuilder.build(); } - private static TableConfig createTableConfig(long input) { + private static TableConfig createTableConfig(final long input) { boolean deprecated = (input & 3) != 0; return new TableConfig(deprecated); } - private List createTableFeaturesProperties(ByteBuf input, int length) { + private List createTableFeaturesProperties(final ByteBuf input, final int length) { List properties = new ArrayList<>(); int tableFeaturesLength = length; while (tableFeaturesLength > 0) { @@ -465,7 +464,7 @@ private List createTableFeaturesProperties(ByteBuf input return properties; } - private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) { + private static MultipartReplyPortStatsCase setPortStats(final ByteBuf input) { MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder(); MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder(); List portStatsList = new ArrayList<>(); @@ -518,7 +517,7 @@ private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) { return caseBuilder.build(); } - private static MultipartReplyQueueCase setQueue(ByteBuf input) { + private static MultipartReplyQueueCase setQueue(final ByteBuf input) { MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder(); MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder(); List queueStatsList = new ArrayList<>(); @@ -544,7 +543,7 @@ private static MultipartReplyQueueCase setQueue(ByteBuf input) { return caseBuilder.build(); } - private static MultipartReplyGroupCase setGroup(ByteBuf input) { + private static MultipartReplyGroupCase setGroup(final ByteBuf input) { MultipartReplyGroupCaseBuilder caseBuilder = new MultipartReplyGroupCaseBuilder(); MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder(); List groupStatsList = new ArrayList<>(); @@ -584,7 +583,7 @@ private static MultipartReplyGroupCase setGroup(ByteBuf input) { return caseBuilder.build(); } - private static MultipartReplyMeterFeaturesCase setMeterFeatures(ByteBuf input) { + private static MultipartReplyMeterFeaturesCase setMeterFeatures(final ByteBuf input) { MultipartReplyMeterFeaturesCaseBuilder caseBuilder = new MultipartReplyMeterFeaturesCaseBuilder(); MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder(); builder.setMaxMeter(input.readUnsignedInt()); @@ -597,7 +596,7 @@ private static MultipartReplyMeterFeaturesCase setMeterFeatures(ByteBuf input) { return caseBuilder.build(); } - private static MeterFlags createMeterFlags(long input) { + private static MeterFlags createMeterFlags(final long input) { final Boolean mfKBPS = (input & (1 << 0)) != 0; final Boolean mfPKTPS = (input & (1 << 1)) != 0; final Boolean mfBURST = (input & (1 << 2)) != 0; @@ -605,13 +604,13 @@ private static MeterFlags createMeterFlags(long input) { return new MeterFlags(mfBURST, mfKBPS, mfPKTPS, mfSTATS); } - private static MeterBandTypeBitmap createMeterBandsBitmap(long input) { + private static MeterBandTypeBitmap createMeterBandsBitmap(final long input) { final Boolean mbtDROP = (input & (1 << 1)) != 0; final Boolean mbtDSCPREMARK = (input & (1 << 2)) != 0; return new MeterBandTypeBitmap(mbtDROP, mbtDSCPREMARK); } - private static MultipartReplyMeterCase setMeter(ByteBuf input) { + private static MultipartReplyMeterCase setMeter(final ByteBuf input) { MultipartReplyMeterCaseBuilder caseBuilder = new MultipartReplyMeterCaseBuilder(); MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder(); List meterStatsList = new ArrayList<>(); @@ -650,7 +649,7 @@ private static MultipartReplyMeterCase setMeter(ByteBuf input) { return caseBuilder.build(); } - private MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) { + private MultipartReplyMeterConfigCase setMeterConfig(final ByteBuf input) { MultipartReplyMeterConfigCaseBuilder caseBuilder = new MultipartReplyMeterConfigCaseBuilder(); MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder(); List meterConfigList = new ArrayList<>(); @@ -711,7 +710,7 @@ private MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) { return caseBuilder.build(); } - private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) { + private MultipartReplyExperimenterCase setExperimenter(final ByteBuf input) { final long expId = input.readUnsignedInt(); final long expType = input.readUnsignedInt(); @@ -728,7 +727,7 @@ private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) { return mpReplyExperimenterCaseBld.build(); } - private static MultipartReplyPortDescCase setPortDesc(ByteBuf input) { + private static MultipartReplyPortDescCase setPortDesc(final ByteBuf input) { MultipartReplyPortDescCaseBuilder caseBuilder = new MultipartReplyPortDescCaseBuilder(); MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder(); List portsList = new ArrayList<>(); @@ -736,9 +735,7 @@ private static MultipartReplyPortDescCase setPortDesc(ByteBuf input) { PortsBuilder portsBuilder = new PortsBuilder(); portsBuilder.setPortNo(input.readUnsignedInt()); input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01); - byte[] hwAddress = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; - input.readBytes(hwAddress); - portsBuilder.setHwAddr(new MacAddress(ByteBufUtils.macAddressToString(hwAddress))); + portsBuilder.setHwAddr(ByteBufUtils.readIetfMacAddress(input)); input.skipBytes(PADDING_IN_PORT_DESC_HEADER_02); portsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, EncodeConstants.MAX_PORT_NAME_LENGTH)); portsBuilder.setConfig(createPortConfig(input.readUnsignedInt())); @@ -756,7 +753,7 @@ private static MultipartReplyPortDescCase setPortDesc(ByteBuf input) { return caseBuilder.build(); } - private static PortConfig createPortConfig(long input) { + private static PortConfig createPortConfig(final long input) { final Boolean pcPortDown = ((input) & (1 << 0)) != 0; final Boolean pcNRecv = ((input) & (1 << 2)) != 0; final Boolean pcNFwd = ((input) & (1 << 5)) != 0; @@ -764,14 +761,14 @@ private static PortConfig createPortConfig(long input) { return new PortConfig(pcNFwd, pcNPacketIn, pcNRecv, pcPortDown); } - private static PortState createPortState(long input) { + private static PortState createPortState(final long input) { final Boolean psLinkDown = ((input) & (1 << 0)) != 0; final Boolean psBlocked = ((input) & (1 << 1)) != 0; final Boolean psLive = ((input) & (1 << 2)) != 0; return new PortState(psBlocked, psLinkDown, psLive); } - private static PortFeatures createPortFeatures(long input) { + private static PortFeatures createPortFeatures(final long input) { final Boolean pf10mbHd = ((input) & (1 << 0)) != 0; final Boolean pf10mbFd = ((input) & (1 << 1)) != 0; final Boolean pf100mbHd = ((input) & (1 << 2)) != 0; @@ -792,7 +789,7 @@ private static PortFeatures createPortFeatures(long input) { pf1gbHd, pf1tbFd, pf40gbFd, pfAutoneg, pfCopper, pfFiber, pfOther, pfPause, pfPauseAsym); } - private static MultipartReplyGroupFeaturesCase setGroupFeatures(ByteBuf rawMessage) { + private static MultipartReplyGroupFeaturesCase setGroupFeatures(final ByteBuf rawMessage) { MultipartReplyGroupFeaturesCaseBuilder caseBuilder = new MultipartReplyGroupFeaturesCaseBuilder(); MultipartReplyGroupFeaturesBuilder featuresBuilder = new MultipartReplyGroupFeaturesBuilder(); featuresBuilder.setTypes(createGroupType(rawMessage.readUnsignedInt())); @@ -811,7 +808,7 @@ private static MultipartReplyGroupFeaturesCase setGroupFeatures(ByteBuf rawMessa return caseBuilder.build(); } - private static ActionType createActionBitmap(long input) { + private static ActionType createActionBitmap(final long input) { final Boolean atOutput = ((input) & (1 << 0)) != 0; final Boolean atCopyTTLout = ((input) & (1 << 11)) != 0; final Boolean atCopyTTLin = ((input) & (1 << 12)) != 0; @@ -835,7 +832,7 @@ private static ActionType createActionBitmap(long input) { atSetField, atSetMplsTTL, atSetNWTTL, atSetQueue); } - private static GroupCapabilities createCapabilities(long input) { + private static GroupCapabilities createCapabilities(final long input) { final Boolean gcSelectWeight = ((input) & (1 << 0)) != 0; final Boolean gcSelectLiveness = ((input) & (1 << 1)) != 0; final Boolean gcChaining = ((input) & (1 << 2)) != 0; @@ -843,7 +840,7 @@ private static GroupCapabilities createCapabilities(long input) { return new GroupCapabilities(gcChaining, gcChainingChecks, gcSelectLiveness, gcSelectWeight); } - private static GroupTypes createGroupType(long input) { + private static GroupTypes createGroupType(final long input) { final Boolean gtAll = ((input) & (1 << 0)) != 0; final Boolean gtSelect = ((input) & (1 << 1)) != 0; final Boolean gtIndirect = ((input) & (1 << 2)) != 0; @@ -851,7 +848,7 @@ private static GroupTypes createGroupType(long input) { return new GroupTypes(gtAll, gtFF, gtIndirect, gtSelect); } - private MultipartReplyGroupDescCase setGroupDesc(ByteBuf input) { + private MultipartReplyGroupDescCase setGroupDesc(final ByteBuf input) { MultipartReplyGroupDescCaseBuilder caseBuilder = new MultipartReplyGroupDescCaseBuilder(); MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder(); List groupDescsList = new ArrayList<>(); @@ -887,7 +884,7 @@ private MultipartReplyGroupDescCase setGroupDesc(ByteBuf input) { @Override public void injectDeserializerRegistry( - DeserializerRegistry deserializerRegistry) { + final DeserializerRegistry deserializerRegistry) { registry = deserializerRegistry; } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java new file mode 100644 index 00000000..008b22c3 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestExperimenterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.desc._case.MultipartRequestGroupDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group.features._case.MultipartRequestGroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.features._case.MultipartRequestMeterFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.desc._case.MultipartRequestPortDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestInputMessageFactory + implements OFDeserializer, DeserializerRegistryInjector { + private DeserializerRegistry registry; + private static final byte PADDING = 4; + private static final byte FLOW_PADDING_1 = 3; + private static final byte FLOW_PADDING_2 = 4; + private static final byte AGGREGATE_PADDING_1 = 3; + private static final byte AGGREGATE_PADDING_2 = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES = 5; + private static final byte MAX_TABLE_NAME_LENGTH = 32; + private static final byte MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH = 64; + private static final byte COMMON_PROPERTY_LENGTH = 4; + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } + + @Override + public MultipartRequestInput deserialize(ByteBuf rawMessage) { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + builder.setType(getMultipartType(type)); + builder.setFlags(getMultipartRequestFlags(rawMessage.readUnsignedShort())); + rawMessage.skipBytes(PADDING); + switch (MultipartType.forValue(type)) { + case OFPMPDESC: + builder.setMultipartRequestBody(setDesc(rawMessage)); + break; + case OFPMPFLOW: + builder.setMultipartRequestBody(setFlow(rawMessage)); + break; + case OFPMPAGGREGATE: + builder.setMultipartRequestBody(setAggregate(rawMessage)); + break; + case OFPMPTABLE: + builder.setMultipartRequestBody(setTable(rawMessage)); + break; + case OFPMPTABLEFEATURES: + builder.setMultipartRequestBody(setTableFeatures(rawMessage)); + break; + case OFPMPPORTSTATS: + builder.setMultipartRequestBody(setPortStats(rawMessage)); + break; + case OFPMPPORTDESC: + builder.setMultipartRequestBody(setPortDesc(rawMessage)); + break; + case OFPMPQUEUE: + builder.setMultipartRequestBody(setQueue(rawMessage)); + break; + case OFPMPGROUP: + builder.setMultipartRequestBody(setGroup(rawMessage)); + break; + case OFPMPGROUPDESC: + builder.setMultipartRequestBody(setGroupDesc(rawMessage)); + break; + case OFPMPGROUPFEATURES: + builder.setMultipartRequestBody(setGroupFeatures(rawMessage)); + break; + case OFPMPMETER: + builder.setMultipartRequestBody(setMeter(rawMessage)); + break; + case OFPMPMETERCONFIG: + builder.setMultipartRequestBody(setMeterConfig(rawMessage)); + break; + case OFPMPMETERFEATURES: + builder.setMultipartRequestBody(setMeterFeatures(rawMessage)); + break; + case OFPMPEXPERIMENTER: + builder.setMultipartRequestBody(setExperimenter(rawMessage)); + break; + default: + break; + } + + return builder.build(); + } + + private static MultipartType getMultipartType(int input) { + return MultipartType.forValue(input); + } + + private static MultipartRequestFlags getMultipartRequestFlags(int input) { + final Boolean _oFPMPFREQMORE = (input & (1 << 0)) > 0; + MultipartRequestFlags flag = new MultipartRequestFlags(_oFPMPFREQMORE); + return flag; + } + + private MultipartRequestTableFeaturesCase setTableFeatures(ByteBuf input) { + MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + MultipartRequestTableFeaturesBuilder tableFeaturesBuilder = new MultipartRequestTableFeaturesBuilder(); + List features = new ArrayList<>(); + while (input.readableBytes() > 0) { + TableFeaturesBuilder featuresBuilder = new TableFeaturesBuilder(); + int length = input.readUnsignedShort(); + featuresBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES); + featuresBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH)); + byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataMatch); + featuresBuilder.setMetadataMatch(new BigInteger(1, metadataMatch)); + byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataWrite); + featuresBuilder.setMetadataWrite(new BigInteger(1, metadataWrite)); + featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt())); + featuresBuilder.setMaxEntries(input.readUnsignedInt()); + featuresBuilder.setTableFeatureProperties( + createTableFeaturesProperties(input, length - MULTIPART_REQUEST_TABLE_FEATURES_STRUCTURE_LENGTH)); + features.add(featuresBuilder.build()); + } + tableFeaturesBuilder.setTableFeatures(features); + caseBuilder.setMultipartRequestTableFeatures(tableFeaturesBuilder.build()); + return caseBuilder.build(); + } + + private List createTableFeaturesProperties(ByteBuf input, int length) { + List properties = new ArrayList<>(); + int tableFeaturesLength = length; + while (tableFeaturesLength > 0) { + int propStartIndex = input.readerIndex(); + TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder(); + TableFeaturesPropType type = TableFeaturesPropType.forValue(input.readUnsignedShort()); + builder.setType(type); + int propertyLength = input.readUnsignedShort(); + int paddingRemainder = propertyLength % EncodeConstants.PADDING; + tableFeaturesLength -= propertyLength; + if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS) + || type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) { + InstructionRelatedTableFeaturePropertyBuilder insBuilder = new InstructionRelatedTableFeaturePropertyBuilder(); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List instructions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry); + insBuilder.setInstruction(instructions); + builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insBuilder.build()); + } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES) + || type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) { + propertyLength -= COMMON_PROPERTY_LENGTH; + NextTableRelatedTableFeaturePropertyBuilder tableBuilder = new NextTableRelatedTableFeaturePropertyBuilder(); + List ids = new ArrayList<>(); + while (propertyLength > 0) { + NextTableIdsBuilder nextTableIdsBuilder = new NextTableIdsBuilder(); + nextTableIdsBuilder.setTableId(input.readUnsignedByte()); + ids.add(nextTableIdsBuilder.build()); + propertyLength--; + } + tableBuilder.setNextTableIds(ids); + builder.addAugmentation(NextTableRelatedTableFeatureProperty.class, tableBuilder.build()); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS) + || type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS) + || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS) + || type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) { + ActionRelatedTableFeaturePropertyBuilder actionBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry); + actionBuilder.setAction(actions); + builder.addAugmentation(ActionRelatedTableFeatureProperty.class, actionBuilder.build()); + } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH) + || type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS) + || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD) + || type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS) + || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD) + || type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) { + OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + List entries = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + propertyLength - COMMON_PROPERTY_LENGTH, input, keyMaker, registry); + oxmBuilder.setMatchEntry(entries); + builder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER) + || type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) { + long expId = input.readUnsignedInt(); + input.readerIndex(propStartIndex); + OFDeserializer propDeserializer = registry + .getDeserializer(ExperimenterDeserializerKeyFactory + .createMultipartReplyTFDeserializerKey(EncodeConstants.OF13_VERSION_ID, expId)); + TableFeatureProperties expProp = propDeserializer.deserialize(input); + properties.add(expProp); + continue; + } + if (paddingRemainder != 0) { + input.skipBytes(EncodeConstants.PADDING - paddingRemainder); + tableFeaturesLength -= EncodeConstants.PADDING - paddingRemainder; + } + properties.add(builder.build()); + } + return properties; + } + + private static TableConfig createTableConfig(long input) { + boolean deprecated = (input & 3) != 0; + return new TableConfig(deprecated); + } + + private MultipartRequestDescCase setDesc(ByteBuf input) { + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder(); + descBuilder.setEmpty(true); + caseBuilder.setMultipartRequestDesc(descBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestFlowCase setFlow(ByteBuf input) { + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder(); + flowBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(FLOW_PADDING_1); + flowBuilder.setOutPort(input.readUnsignedInt()); + flowBuilder.setOutGroup(input.readUnsignedInt()); + input.skipBytes(FLOW_PADDING_2); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(cookie); + flowBuilder.setCookie(new BigInteger(1, cookie)); + byte[] cookie_mask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(cookie_mask); + flowBuilder.setCookieMask(new BigInteger(1, cookie_mask)); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class)); + flowBuilder.setMatch(matchDeserializer.deserialize(input)); + caseBuilder.setMultipartRequestFlow(flowBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestAggregateCase setAggregate(ByteBuf input) { + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder aggregateBuilder = new MultipartRequestAggregateBuilder(); + aggregateBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(AGGREGATE_PADDING_1); + aggregateBuilder.setOutPort(input.readUnsignedInt()); + aggregateBuilder.setOutGroup(input.readUnsignedInt()); + input.skipBytes(AGGREGATE_PADDING_2); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(cookie); + aggregateBuilder.setCookie(new BigInteger(1, cookie)); + byte[] cookie_mask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(cookie_mask); + aggregateBuilder.setCookieMask(new BigInteger(1, cookie_mask)); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class)); + aggregateBuilder.setMatch(matchDeserializer.deserialize(input)); + caseBuilder.setMultipartRequestAggregate(aggregateBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestPortDescCase setPortDesc(ByteBuf input) { + MultipartRequestPortDescCaseBuilder caseBuilder = new MultipartRequestPortDescCaseBuilder(); + MultipartRequestPortDescBuilder portBuilder = new MultipartRequestPortDescBuilder(); + portBuilder.setEmpty(true); + caseBuilder.setMultipartRequestPortDesc(portBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestPortStatsCase setPortStats(ByteBuf input) { + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder(); + portBuilder.setPortNo(input.readUnsignedInt()); + caseBuilder.setMultipartRequestPortStats(portBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestQueueCase setQueue(ByteBuf input) { + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder(); + queueBuilder.setPortNo(input.readUnsignedInt()); + queueBuilder.setQueueId(input.readUnsignedInt()); + caseBuilder.setMultipartRequestQueue(queueBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestGroupCase setGroup(ByteBuf input) { + MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder(); + MultipartRequestGroupBuilder groupBuilder = new MultipartRequestGroupBuilder(); + groupBuilder.setGroupId(new GroupId(input.readUnsignedInt())); + caseBuilder.setMultipartRequestGroup(groupBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestGroupDescCase setGroupDesc(ByteBuf input) { + MultipartRequestGroupDescCaseBuilder caseBuilder = new MultipartRequestGroupDescCaseBuilder(); + MultipartRequestGroupDescBuilder groupBuilder = new MultipartRequestGroupDescBuilder(); + groupBuilder.setEmpty(true); + caseBuilder.setMultipartRequestGroupDesc(groupBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestGroupFeaturesCase setGroupFeatures(ByteBuf input) { + MultipartRequestGroupFeaturesCaseBuilder caseBuilder = new MultipartRequestGroupFeaturesCaseBuilder(); + MultipartRequestGroupFeaturesBuilder groupBuilder = new MultipartRequestGroupFeaturesBuilder(); + groupBuilder.setEmpty(true); + caseBuilder.setMultipartRequestGroupFeatures(groupBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestMeterCase setMeter(ByteBuf input) { + MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder(); + MultipartRequestMeterBuilder meterBuilder = new MultipartRequestMeterBuilder(); + meterBuilder.setMeterId(new MeterId(input.readUnsignedInt())); + caseBuilder.setMultipartRequestMeter(meterBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestMeterConfigCase setMeterConfig(ByteBuf input) { + MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder(); + MultipartRequestMeterConfigBuilder meterBuilder = new MultipartRequestMeterConfigBuilder(); + meterBuilder.setMeterId(new MeterId(input.readUnsignedInt())); + caseBuilder.setMultipartRequestMeterConfig(meterBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestMeterFeaturesCase setMeterFeatures(ByteBuf input) { + MultipartRequestMeterFeaturesCaseBuilder caseBuilder = new MultipartRequestMeterFeaturesCaseBuilder(); + MultipartRequestMeterFeaturesBuilder meterBuilder = new MultipartRequestMeterFeaturesBuilder(); + meterBuilder.setEmpty(true); + caseBuilder.setMultipartRequestMeterFeatures(meterBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestTableCase setTable(ByteBuf input) { + MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder(); + MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder(); + tableBuilder.setEmpty(true); + caseBuilder.setMultipartRequestTable(tableBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestExperimenterCase setExperimenter(ByteBuf input) { + MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); + MultipartRequestExperimenterBuilder experimenterBuilder = new MultipartRequestExperimenterBuilder(); + caseBuilder.setMultipartRequestExperimenter(experimenterBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java index db7376e6..aa8b9c8d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java @@ -40,8 +40,11 @@ public ErrorMessage deserialize(ByteBuf rawMessage) { ErrorTypeV10 errorType = ErrorTypeV10.forValue(type); decodeType(builder, errorType, type); decodeCode(rawMessage, builder, errorType); - if (rawMessage.readableBytes() > 0) { - builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array()); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); } return builder.build(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java index 469f920e..c94b0d11 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java @@ -9,16 +9,13 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import java.math.BigInteger; import java.util.ArrayList; import java.util.List; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.util.OpenflowUtils; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionTypeV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; @@ -35,7 +32,7 @@ public class OF10FeaturesReplyMessageFactory implements OFDeserializer { +public class OF10FeaturesRequestMessageFactory implements OFDeserializer { @Override - public BarrierOutput deserialize(ByteBuf rawMessage) { - BarrierOutputBuilder builder = new BarrierOutputBuilder(); + public GetFeaturesInput deserialize(ByteBuf rawMessage) { + GetFeaturesInputBuilder builder = new GetFeaturesInputBuilder(); builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); builder.setXid(rawMessage.readUnsignedInt()); return builder.build(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java new file mode 100644 index 00000000..3357995a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlagsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FlowModInputMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } + + @Override + public FlowModInput deserialize(ByteBuf rawMessage) { + FlowModInputBuilder builder = new FlowModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + builder.setMatchV10(matchDeserializer.deserialize(rawMessage)); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(cookie); + builder.setCookie(new BigInteger(1, cookie)); + builder.setCommand(FlowModCommand.forValue(rawMessage.readUnsignedShort())); + builder.setIdleTimeout(rawMessage.readUnsignedShort()); + builder.setHardTimeout(rawMessage.readUnsignedShort()); + builder.setPriority(rawMessage.readUnsignedShort()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setOutPort(new PortNumber((long) rawMessage.readUnsignedShort())); + builder.setFlagsV10(createFlowModFlagsFromBitmap(rawMessage.readUnsignedShort())); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF10_VERSION_ID); + + List actions = ListDeserializer.deserializeList(EncodeConstants.OF10_VERSION_ID, + rawMessage.readableBytes(), rawMessage, keyMaker, registry); + builder.setAction(actions); + return builder.build(); + } + + private static FlowModFlagsV10 createFlowModFlagsFromBitmap(int input) { + final Boolean _oFPFFSENDFLOWREM = (input & (1 << 0)) > 0; + final Boolean _oFPFFCHECKOVERLAP = (input & (1 << 1)) > 0; + final Boolean _oFPFFEMERG = (input & (1 << 2)) > 0; + return new FlowModFlagsV10(_oFPFFCHECKOVERLAP, _oFPFFEMERG, _oFPFFSENDFLOWREM); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java similarity index 52% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactory.java rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java index a63c255d..7584a734 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java @@ -1,33 +1,31 @@ /* - * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2015 NetIDE Consortium 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.factories; 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.protocol.rev130731.EchoRequestMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInputBuilder; /** - * Translates EchoRequest messages (both OpenFlow v1.0 and OpenFlow v1.3) - * @author michal.polkorab - * @author timotej.kubas + * @author giuseppex.petralia@intel.com + * */ -public class OF10EchoRequestMessageFactory implements OFDeserializer{ +public class OF10GetQueueConfigInputMessageFactory implements OFDeserializer { @Override - public EchoRequestMessage deserialize(ByteBuf rawMessage) { - EchoRequestMessageBuilder builder = new EchoRequestMessageBuilder(); + public GetQueueConfigInput deserialize(ByteBuf rawMessage) { + GetQueueConfigInputBuilder builder = new GetQueueConfigInputBuilder(); builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); - builder.setXid(rawMessage.readUnsignedInt()); - builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array()); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setPort(new PortNumber((long) rawMessage.readUnsignedShort())); return builder.build(); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java new file mode 100644 index 00000000..94cce9b1 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PacketOutInputMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } + + @Override + public PacketOutInput deserialize(ByteBuf rawMessage) { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setInPort(new PortNumber((long) rawMessage.readUnsignedShort())); + int actions_len = rawMessage.readShort(); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF10_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF10_VERSION_ID, actions_len, + rawMessage, keyMaker, registry); + builder.setAction(actions); + + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + + if (data != null) { + + builder.setData(data); + } + return builder.build(); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java new file mode 100644 index 00000000..025f7ba4 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PortModInputMessageFactory implements OFDeserializer { + + @Override + public PortModInput deserialize(final ByteBuf rawMessage) { + PortModInputBuilder builder = new PortModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setPortNo(new PortNumber((long) rawMessage.readUnsignedShort())); + builder.setHwAddress(ByteBufUtils.readIetfMacAddress(rawMessage)); + builder.setConfigV10(createPortConfig(rawMessage.readUnsignedInt())); + builder.setMaskV10(createPortConfig(rawMessage.readUnsignedInt())); + builder.setAdvertiseV10(createPortFeatures(rawMessage.readUnsignedInt())); + return builder.build(); + } + + private static PortConfigV10 createPortConfig(final long input) { + final Boolean _portDown = ((input) & (1 << 0)) > 0; + final Boolean _noStp = ((input) & (1 << 1)) > 0; + final Boolean _noRecv = ((input) & (1 << 2)) > 0; + final Boolean _noRecvStp = ((input) & (1 << 3)) > 0; + final Boolean _noFlood = ((input) & (1 << 4)) > 0; + final Boolean _noFwd = ((input) & (1 << 5)) > 0; + final Boolean _noPacketIn = ((input) & (1 << 6)) > 0; + return new PortConfigV10(_noFlood, _noFwd, _noPacketIn, _noRecv, _noRecvStp, _noStp, _portDown); + } + + private static PortFeaturesV10 createPortFeatures(final long input) { + final Boolean _10mbHd = ((input) & (1 << 0)) > 0; + final Boolean _10mbFd = ((input) & (1 << 1)) > 0; + final Boolean _100mbHd = ((input) & (1 << 2)) > 0; + final Boolean _100mbFd = ((input) & (1 << 3)) > 0; + final Boolean _1gbHd = ((input) & (1 << 4)) > 0; + final Boolean _1gbFd = ((input) & (1 << 5)) > 0; + final Boolean _10gbFd = ((input) & (1 << 6)) > 0; + final Boolean _copper = ((input) & (1 << 7)) > 0; + final Boolean _fiber = ((input) & (1 << 8)) > 0; + final Boolean _autoneg = ((input) & (1 << 9)) > 0; + final Boolean _pause = ((input) & (1 << 10)) > 0; + final Boolean _pauseAsym = ((input) & (1 << 11)) > 0; + return new PortFeaturesV10(_100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd, _1gbHd, _autoneg, _copper, + _fiber, _pause, _pauseAsym); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java index 9c3b72e7..2bab42b6 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java @@ -9,12 +9,10 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.util.OpenflowUtils; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder; @@ -28,7 +26,7 @@ public class OF10PortStatusMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + private DeserializerRegistry registry; + private static final byte FLOW_PADDING_1 = 1; + private static final byte AGGREGATE_PADDING_1 = 1; + + @Override + public MultipartRequestInput deserialize(ByteBuf rawMessage) { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + builder.setType(getMultipartType(type)); + builder.setFlags(getMultipartRequestFlags(rawMessage.readUnsignedShort())); + switch (getMultipartType(type)) { + case OFPMPDESC: + builder.setMultipartRequestBody(setDesc(rawMessage)); + break; + case OFPMPFLOW: + builder.setMultipartRequestBody(setFlow(rawMessage)); + break; + case OFPMPAGGREGATE: + builder.setMultipartRequestBody(setAggregate(rawMessage)); + break; + case OFPMPTABLE: + builder.setMultipartRequestBody(setTable(rawMessage)); + break; + case OFPMPPORTSTATS: + builder.setMultipartRequestBody(setPortStats(rawMessage)); + break; + case OFPMPQUEUE: + builder.setMultipartRequestBody(setQueue(rawMessage)); + break; + case OFPMPEXPERIMENTER: + builder.setMultipartRequestBody(setExperimenter(rawMessage)); + break; + default: + break; + } + return builder.build(); + } + + private MultipartRequestExperimenterCase setExperimenter(ByteBuf input) { + MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); + MultipartRequestExperimenterBuilder experimenterBuilder = new MultipartRequestExperimenterBuilder(); + caseBuilder.setMultipartRequestExperimenter(experimenterBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestQueueCase setQueue(ByteBuf input) { + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder(); + queueBuilder.setPortNo((long) input.readUnsignedShort()); + input.skipBytes(2); + queueBuilder.setQueueId(input.readUnsignedInt()); + caseBuilder.setMultipartRequestQueue(queueBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestPortStatsCase setPortStats(ByteBuf input) { + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder(); + portBuilder.setPortNo((long) input.readUnsignedShort()); + caseBuilder.setMultipartRequestPortStats(portBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestTableCase setTable(ByteBuf input) { + MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder(); + MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder(); + tableBuilder.setEmpty(true); + caseBuilder.setMultipartRequestTable(tableBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestAggregateCase setAggregate(ByteBuf input) { + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder aggregateBuilder = new MultipartRequestAggregateBuilder(); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + aggregateBuilder.setMatchV10(matchDeserializer.deserialize(input)); + aggregateBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(AGGREGATE_PADDING_1); + aggregateBuilder.setOutPort((long) input.readUnsignedShort()); + caseBuilder.setMultipartRequestAggregate(aggregateBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestFlowCase setFlow(ByteBuf input) { + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder(); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + flowBuilder.setMatchV10(matchDeserializer.deserialize(input)); + flowBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(FLOW_PADDING_1); + flowBuilder.setOutPort((long) input.readUnsignedShort()); + caseBuilder.setMultipartRequestFlow(flowBuilder.build()); + return caseBuilder.build(); + } + + private MultipartRequestDescCase setDesc(ByteBuf input) { + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder(); + descBuilder.setEmpty(true); + caseBuilder.setMultipartRequestDesc(descBuilder.build()); + return caseBuilder.build(); + } + + private static MultipartRequestFlags getMultipartRequestFlags(int input) { + final Boolean _oFPMPFREQMORE = (input & (1 << 0)) > 0; + MultipartRequestFlags flag = new MultipartRequestFlags(_oFPMPFREQMORE); + return flag; + } + + private static MultipartType getMultipartType(int input) { + return MultipartType.forValue(input); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java index 44679569..a69baeea 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java @@ -51,7 +51,9 @@ public PacketInMessage deserialize(final ByteBuf rawMessage) { OFDeserializer matchDeserializer = registry.getDeserializer(MATCH_KEY); builder.setMatch(matchDeserializer.deserialize(rawMessage)); rawMessage.skipBytes(PADDING_IN_PACKET_IN_HEADER); - builder.setData(rawMessage.readBytes(rawMessage.readableBytes()).array()); + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + builder.setData(data); return builder.build(); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java new file mode 100644 index 00000000..919a8e74 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.protocol.impl.util.CodeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.CodeKeyMakerFactory; +import org.opendaylight.openflowjava.protocol.impl.util.ListDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; + +public class PacketOutInputMessageFactory implements OFDeserializer, DeserializerRegistryInjector { + private DeserializerRegistry registry; + private final byte PADDING = 6; + + @Override + public PacketOutInput deserialize(ByteBuf rawMessage) { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setInPort(new PortNumber(rawMessage.readUnsignedInt())); + int actions_len = rawMessage.readShort(); + rawMessage.skipBytes(PADDING); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, actions_len, + rawMessage, keyMaker, registry); + builder.setAction(actions); + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + if (data != null) { + builder.setData(data); + } + return builder.build(); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java new file mode 100644 index 00000000..55209d5d --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PortModInputMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_PORT_MOD_MESSAGE_1 = 4; + private static final byte PADDING_IN_PORT_MOD_MESSAGE_2 = 2; + private static final byte PADDING_IN_PORT_MOD_MESSAGE_3 = 4; + + @Override + public PortModInput deserialize(final ByteBuf rawMessage) { + PortModInputBuilder builder = new PortModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setPortNo(new PortNumber(rawMessage.readUnsignedInt())); + rawMessage.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_1); + builder.setHwAddress(ByteBufUtils.readIetfMacAddress(rawMessage)); + rawMessage.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_2); + builder.setConfig(createPortConfig(rawMessage.readUnsignedInt())); + builder.setMask(createPortConfig(rawMessage.readUnsignedInt())); + builder.setAdvertise(createPortFeatures(rawMessage.readUnsignedInt())); + rawMessage.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_3); + return builder.build(); + } + + private static PortConfig createPortConfig(final long input) { + final Boolean pcPortDown = ((input) & (1 << 0)) != 0; + final Boolean pcNRecv = ((input) & (1 << 2)) != 0; + final Boolean pcNFwd = ((input) & (1 << 5)) != 0; + final Boolean pcNPacketIn = ((input) & (1 << 6)) != 0; + return new PortConfig(pcNFwd, pcNPacketIn, pcNRecv, pcPortDown); + } + + private static PortFeatures createPortFeatures(final long input) { + final Boolean pf10mbHd = ((input) & (1 << 0)) != 0; + final Boolean pf10mbFd = ((input) & (1 << 1)) != 0; + final Boolean pf100mbHd = ((input) & (1 << 2)) != 0; + final Boolean pf100mbFd = ((input) & (1 << 3)) != 0; + final Boolean pf1gbHd = ((input) & (1 << 4)) != 0; + final Boolean pf1gbFd = ((input) & (1 << 5)) != 0; + final Boolean pf10gbFd = ((input) & (1 << 6)) != 0; + final Boolean pf40gbFd = ((input) & (1 << 7)) != 0; + final Boolean pf100gbFd = ((input) & (1 << 8)) != 0; + final Boolean pf1tbFd = ((input) & (1 << 9)) != 0; + final Boolean pfOther = ((input) & (1 << 10)) != 0; + final Boolean pfCopper = ((input) & (1 << 11)) != 0; + final Boolean pfFiber = ((input) & (1 << 12)) != 0; + final Boolean pfAutoneg = ((input) & (1 << 13)) != 0; + final Boolean pfPause = ((input) & (1 << 14)) != 0; + final Boolean pfPauseAsym = ((input) & (1 << 15)) != 0; + return new PortFeatures(pf100gbFd, pf100mbFd, pf100mbHd, pf10gbFd, pf10mbFd, pf10mbHd, pf1gbFd, pf1gbHd, + pf1tbFd, pf40gbFd, pfAutoneg, pfCopper, pfFiber, pfOther, pfPause, pfPauseAsym); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java index fe3d7ac7..5310aa2f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java @@ -9,11 +9,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.openflowjava.util.ByteBufUtils; 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.PortReason; @@ -33,7 +31,7 @@ public class PortStatusMessageFactory implements OFDeserializer { + + private static final byte PADDING = 4; + + @Override + public RoleRequestInput deserialize(ByteBuf rawMessage) { + RoleRequestInputBuilder builder = new RoleRequestInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setRole(ControllerRole.forValue(rawMessage.readInt())); + rawMessage.skipBytes(PADDING); + byte[] generationId = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(generationId); + builder.setGenerationId(new BigInteger(1, generationId)); + return builder.build(); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java new file mode 100644 index 00000000..af18069e --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.List; +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.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMaskBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class SetAsyncInputMessageFactory implements OFDeserializer { + + private static final byte SEPARATE_ROLES = 2; + + @Override + public SetAsyncInput deserialize(ByteBuf rawMessage) { + SetAsyncInputBuilder builder = new SetAsyncInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setPacketInMask(decodePacketInMask(rawMessage)); + builder.setPortStatusMask(decodePortStatusMask(rawMessage)); + builder.setFlowRemovedMask(decodeFlowRemovedMask(rawMessage)); + return builder.build(); + } + + private static List decodePacketInMask(ByteBuf input) { + List inMasks = new ArrayList<>(); + PacketInMaskBuilder maskBuilder; + for (int i = 0; i < SEPARATE_ROLES; i++) { + maskBuilder = new PacketInMaskBuilder(); + maskBuilder.setMask(decodePacketInReasons(input.readUnsignedInt())); + inMasks.add(maskBuilder.build()); + } + return inMasks; + } + + private static List decodePacketInReasons(long input) { + List reasons = new ArrayList<>(); + if ((input & (1 << 0)) != 0) { + reasons.add(PacketInReason.OFPRNOMATCH); + } + if ((input & (1 << 1)) != 0) { + reasons.add(PacketInReason.OFPRACTION); + } + if ((input & (1 << 2)) != 0) { + reasons.add(PacketInReason.OFPRINVALIDTTL); + } + return reasons; + } + + private static List decodePortStatusMask(ByteBuf input) { + List inMasks = new ArrayList<>(); + PortStatusMaskBuilder maskBuilder; + for (int i = 0; i < SEPARATE_ROLES; i++) { + maskBuilder = new PortStatusMaskBuilder(); + maskBuilder.setMask(decodePortReasons(input.readUnsignedInt())); + inMasks.add(maskBuilder.build()); + } + return inMasks; + } + + private static List decodePortReasons(long input) { + List reasons = new ArrayList<>(); + if ((input & (1 << 0)) != 0) { + reasons.add(PortReason.OFPPRADD); + } + if ((input & (1 << 1)) != 0) { + reasons.add(PortReason.OFPPRDELETE); + } + if ((input & (1 << 2)) != 0) { + reasons.add(PortReason.OFPPRMODIFY); + } + return reasons; + } + + private static List decodeFlowRemovedMask(ByteBuf input) { + List inMasks = new ArrayList<>(); + FlowRemovedMaskBuilder maskBuilder; + for (int i = 0; i < SEPARATE_ROLES; i++) { + maskBuilder = new FlowRemovedMaskBuilder(); + maskBuilder.setMask(decodeFlowRemovedReasons(input.readUnsignedInt())); + inMasks.add(maskBuilder.build()); + } + return inMasks; + } + + private static List decodeFlowRemovedReasons(long input) { + List reasons = new ArrayList<>(); + if ((input & (1 << 0)) != 0) { + reasons.add(FlowRemovedReason.OFPRRIDLETIMEOUT); + } + if ((input & (1 << 1)) != 0) { + reasons.add(FlowRemovedReason.OFPRRHARDTIMEOUT); + } + if ((input & (1 << 2)) != 0) { + reasons.add(FlowRemovedReason.OFPRRDELETE); + } + if ((input & (1 << 3)) != 0) { + reasons.add(FlowRemovedReason.OFPRRGROUPDELETE); + } + return reasons; + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java similarity index 58% rename from openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactory.java rename to openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java index 4c247c6a..5dc4c9b5 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java @@ -1,35 +1,34 @@ /* - * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2015 NetIDE Consortium 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.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.VersionAssignableFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInputBuilder; /** - * Translates GetConfigReply messages (both OpenFlow v1.0 and OpenFlow v1.3) - * @author michal.polkorab - * @author timotej.kubas + * Translates SetConfig messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author giuseppex.petralia@intel.com */ -public class OF10GetConfigReplyMessageFactory implements OFDeserializer { +public class SetConfigInputMessageFactory extends VersionAssignableFactory implements OFDeserializer { @Override - public GetConfigOutput deserialize(ByteBuf rawMessage) { - GetConfigOutputBuilder builder = new GetConfigOutputBuilder(); - builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + public SetConfigInput deserialize(ByteBuf rawMessage) { + SetConfigInputBuilder builder = new SetConfigInputBuilder(); + builder.setVersion(getVersion()); builder.setXid(rawMessage.readUnsignedInt()); builder.setFlags(SwitchConfigFlag.forValue(rawMessage.readUnsignedShort())); builder.setMissSendLen(rawMessage.readUnsignedShort()); return builder.build(); } -} + +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java new file mode 100644 index 00000000..425bc579 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class TableModInputMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_TABLE_MOD_MESSAGE = 3; + + @Override + public TableModInput deserialize(ByteBuf rawMessage) { + TableModInputBuilder builder = new TableModInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setTableId(new TableId((long) rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING_IN_TABLE_MOD_MESSAGE); + builder.setConfig(createTableConfig(rawMessage.readUnsignedInt())); + return builder.build(); + } + + private static TableConfig createTableConfig(long input) { + boolean deprecated = (input & 3) != 0; + return new TableConfig(deprecated); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java index 149ebb0e..ea247098 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmArpSpaDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addArpSpaValue(input, builder); return builder.build(); } - private static void addArpSpaValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addArpSpaValue(final ByteBuf input, final MatchEntryBuilder builder) { ArpSpaCaseBuilder caseBuilder = new ArpSpaCaseBuilder(); ArpSpaBuilder arpBuilder = new ArpSpaBuilder(); - arpBuilder.setIpv4Address(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + arpBuilder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); if (builder.isHasMask()) { arpBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java index fdeaddc5..da5dfee6 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmArpTpaDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addArpTpaValue(input, builder); return builder.build(); } - private static void addArpTpaValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addArpTpaValue(final ByteBuf input, final MatchEntryBuilder builder) { ArpTpaCaseBuilder caseBuilder = new ArpTpaCaseBuilder(); ArpTpaBuilder arpBuilder = new ArpTpaBuilder(); - arpBuilder.setIpv4Address(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + arpBuilder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); if (builder.isHasMask()) { arpBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java index 1127faea..c28ba5c2 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java @@ -8,10 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; /** * @author michal.polkorab @@ -29,7 +28,7 @@ private OxmDeserializerHelper() { * @param matchEntryLength mask length * @return binary mask */ - public static byte[] convertMask(ByteBuf input, int matchEntryLength) { + public static byte[] convertMask(final ByteBuf input, final int matchEntryLength) { byte[] mask = new byte[matchEntryLength]; input.readBytes(mask); return mask; @@ -40,9 +39,9 @@ public static byte[] convertMask(ByteBuf input, int matchEntryLength) { * @param input input ByteBuf * @return mac address */ - public static MacAddress convertMacAddress(ByteBuf input) { + public static MacAddress convertMacAddress(final ByteBuf input) { byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; input.readBytes(address); - return new MacAddress(ByteBufUtils.macAddressToString(address)); + return IetfYangUtil.INSTANCE.macAddressFor(address); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java index b18a9de3..98c49af8 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpDscp; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java index d0e5fc1a..6664538d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Dst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmIpv4DstDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addIpv4DstValue(input, builder); return builder.build(); } - private static void addIpv4DstValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addIpv4DstValue(final ByteBuf input, final MatchEntryBuilder builder) { Ipv4DstCaseBuilder caseBuilder = new Ipv4DstCaseBuilder(); Ipv4DstBuilder ipv4Builder = new Ipv4DstBuilder(); - ipv4Builder.setIpv4Address(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + ipv4Builder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); if (builder.isHasMask()) { ipv4Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java index fdd020c6..5b0cc22d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmIpv4SrcDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addIpv4SrcValue(input, builder); return builder.build(); } - private static void addIpv4SrcValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addIpv4SrcValue(final ByteBuf input, final MatchEntryBuilder builder) { Ipv4SrcCaseBuilder caseBuilder = new Ipv4SrcCaseBuilder(); Ipv4SrcBuilder ipv4Builder = new Ipv4SrcBuilder(); - ipv4Builder.setIpv4Address(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + ipv4Builder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); if (builder.isHasMask()) { ipv4Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java index 364cbaef..4d88c269 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Dst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmIpv6DstDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addIpv6DstValue(input, builder); return builder.build(); } - private static void addIpv6DstValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addIpv6DstValue(final ByteBuf input, final MatchEntryBuilder builder) { Ipv6DstCaseBuilder caseBuilder = new Ipv6DstCaseBuilder(); Ipv6DstBuilder ipv6Builder = new Ipv6DstBuilder(); - ipv6Builder.setIpv6Address(new Ipv6Address(ByteBufUtils.readIpv6Address(input))); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); if (builder.isHasMask()) { ipv6Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java index 9016af5d..4ef1944a 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java @@ -11,7 +11,7 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java index 2afd9a50..99c52c95 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java @@ -8,10 +8,8 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTarget; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -29,16 +27,16 @@ public class OxmIpv6NdTargetDeserializer extends AbstractOxmMatchEntryDeserializ implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addIpv6NdTargetValue(input, builder); return builder.build(); } - private static void addIpv6NdTargetValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addIpv6NdTargetValue(final ByteBuf input, final MatchEntryBuilder builder) { Ipv6NdTargetCaseBuilder caseBuilder = new Ipv6NdTargetCaseBuilder(); Ipv6NdTargetBuilder ipv6Builder = new Ipv6NdTargetBuilder(); - ipv6Builder.setIpv6Address(new Ipv6Address(ByteBufUtils.readIpv6Address(input))); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); caseBuilder.setIpv6NdTarget(ipv6Builder.build()); builder.setMatchEntryValue(caseBuilder.build()); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java index 4b486f0b..22b9ccef 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java @@ -8,11 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; @@ -30,16 +28,16 @@ public class OxmIpv6SrcDeserializer extends AbstractOxmMatchEntryDeserializer implements OFDeserializer { @Override - public MatchEntry deserialize(ByteBuf input) { + public MatchEntry deserialize(final ByteBuf input) { MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); addIpv6SrcValue(input, builder); return builder.build(); } - private static void addIpv6SrcValue(ByteBuf input, MatchEntryBuilder builder) { + private static void addIpv6SrcValue(final ByteBuf input, final MatchEntryBuilder builder) { Ipv6SrcCaseBuilder caseBuilder = new Ipv6SrcCaseBuilder(); Ipv6SrcBuilder ipv6Builder = new Ipv6SrcBuilder(); - ipv6Builder.setIpv6Address(new Ipv6Address(ByteBufUtils.readIpv6Address(input))); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); if (builder.isHasMask()) { ipv6Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES)); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java index bbc137d5..cac4f806 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java index 4a46edfd..8dc17a59 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java index 55769578..7b3869b7 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java index 57f44d16..5e8a7596 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java index b631c815..9a978422 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java index 29c722d8..501e70c3 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java new file mode 100644 index 00000000..e9535d8e --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.deserialization.match.ext; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.AbstractOxmMatchEntryDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.experimenter.id._case.ExperimenterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; + +/** + * Created by Anil Vishnoi (avishnoi@Brocade.com) on 7/26/16. + */ +public abstract class AbstractOxmExperimenterMatchEntryDeserializer extends AbstractOxmMatchEntryDeserializer { + + protected ExperimenterIdCaseBuilder createExperimenterIdCase(MatchEntryBuilder entryBuilder, ByteBuf input) { + ExperimenterIdCaseBuilder expCaseBuilder = new ExperimenterIdCaseBuilder(); + ExperimenterBuilder expBuilder = new ExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(input.readUnsignedInt())); + expCaseBuilder.setExperimenter(expBuilder.build()); + return expCaseBuilder; + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java new file mode 100644 index 00000000..e03ed77a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.deserialization.match.ext; + +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.TcpFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.TcpFlagsContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.TcpFlagsContainerBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.oxm.container.match.entry.value.experimenter.id._case.TcpFlagsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +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.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; + +/** + * Created by Anil Vishnoi (avishnoi@Brocade.com) on 7/26/16. + */ +public class OnfOxmTcpFlagsDeserializer extends AbstractOxmExperimenterMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder(deserializeHeader(input)); + ExperimenterIdCaseBuilder expCaseBuilder = createExperimenterIdCase(matchEntryBuilder, input); + addTcpFlagsAugmentation(input, expCaseBuilder, matchEntryBuilder.isHasMask()); + matchEntryBuilder.setMatchEntryValue(expCaseBuilder.build()); + return matchEntryBuilder.build(); + + } + + private static void addTcpFlagsAugmentation(ByteBuf input, ExperimenterIdCaseBuilder expCaseBuilder, boolean hasMask) { + TcpFlagsContainerBuilder flagsContainerBuilder = new TcpFlagsContainerBuilder(); + TcpFlagsBuilder flagsBuilder = new TcpFlagsBuilder(); + flagsBuilder.setFlags(input.readUnsignedShort()); + if (hasMask) { + byte[] mask = new byte[EncodeConstants.SIZE_OF_SHORT_IN_BYTES]; + input.readBytes(mask); + flagsBuilder.setMask(mask); + } + flagsContainerBuilder.setTcpFlags(flagsBuilder.build()); + expCaseBuilder.addAugmentation(TcpFlagsContainer.class, flagsContainerBuilder.build()); + } + + /** + * @return oxm_field class + */ + @Override + protected Class getOxmField() { + return TcpFlags.class; + } + + /** + * @return oxm_class class + */ + @Override + protected Class getOxmClass() { + return ExperimenterClass.class; + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java new file mode 100644 index 00000000..85bcbda6 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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; + +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.BarrierReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoOutputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoRequestMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.ErrorMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.ExperimenterMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.FlowRemovedMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetAsyncReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetConfigReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetFeaturesOutputFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.HelloMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10BarrierReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10FeaturesReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10FlowRemovedMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10PacketInMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10PortStatusMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10QueueGetConfigReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10StatsReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.PacketInMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.PacketOutInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.PortStatusMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.QueueGetConfigReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.RoleReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.util.CommonMessageRegistryHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class AdditionalMessageFactoryInitializer { + private AdditionalMessageFactoryInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers message serializers implemented within NetIde project into + * provided registry + * + * @param serializerRegistry + * registry to be initialized with message serializers + */ + public static void registerMessageSerializers(SerializerRegistry serializerRegistry) { + // register OF v1.0 message serializers + short version = EncodeConstants.OF10_VERSION_ID; + CommonMessageRegistryHelper registryHelper = new CommonMessageRegistryHelper(version, serializerRegistry); + registryHelper.registerSerializer(ErrorMessage.class, new ErrorMessageFactory()); + registryHelper.registerSerializer(EchoRequestMessage.class, new EchoRequestMessageFactory()); + registryHelper.registerSerializer(EchoOutput.class, new EchoOutputMessageFactory()); + registryHelper.registerSerializer(GetFeaturesOutput.class, new OF10FeaturesReplyMessageFactory()); + registryHelper.registerSerializer(GetConfigOutput.class, new GetConfigReplyMessageFactory()); + registryHelper.registerSerializer(PacketInMessage.class, new OF10PacketInMessageFactory()); + registryHelper.registerSerializer(FlowRemovedMessage.class, new OF10FlowRemovedMessageFactory()); + registryHelper.registerSerializer(PortStatusMessage.class, new OF10PortStatusMessageFactory()); + registryHelper.registerSerializer(MultipartReplyMessage.class, new OF10StatsReplyMessageFactory()); + registryHelper.registerSerializer(BarrierOutput.class, new OF10BarrierReplyMessageFactory()); + registryHelper.registerSerializer(GetQueueConfigOutput.class, new OF10QueueGetConfigReplyMessageFactory()); + + // register OF v1.3 message serializers + version = EncodeConstants.OF13_VERSION_ID; + registryHelper = new CommonMessageRegistryHelper(version, serializerRegistry); + registryHelper.registerSerializer(EchoOutput.class, new EchoOutputMessageFactory()); + registryHelper.registerSerializer(PacketInMessage.class, new PacketInMessageFactory()); + registryHelper.registerSerializer(PacketOutInput.class, new PacketOutInputMessageFactory()); + registryHelper.registerSerializer(GetFeaturesOutput.class, new GetFeaturesOutputFactory()); + registryHelper.registerSerializer(EchoRequestMessage.class, new EchoRequestMessageFactory()); + registryHelper.registerSerializer(MultipartReplyMessage.class, new MultipartReplyMessageFactory()); + registryHelper.registerSerializer(HelloMessage.class, new HelloMessageFactory()); + registryHelper.registerSerializer(ErrorMessage.class, new ErrorMessageFactory()); + registryHelper.registerSerializer(ExperimenterMessage.class, new ExperimenterMessageFactory()); + registryHelper.registerSerializer(GetConfigOutput.class, new GetConfigReplyMessageFactory()); + registryHelper.registerSerializer(FlowRemovedMessage.class, new FlowRemovedMessageFactory()); + registryHelper.registerSerializer(PortStatusMessage.class, new PortStatusMessageFactory()); + registryHelper.registerSerializer(BarrierOutput.class, new BarrierReplyMessageFactory()); + registryHelper.registerSerializer(GetQueueConfigOutput.class, new QueueGetConfigReplyMessageFactory()); + registryHelper.registerSerializer(RoleRequestOutput.class, new RoleReplyMessageFactory()); + registryHelper.registerSerializer(GetAsyncOutput.class, new GetAsyncReplyMessageFactory()); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java index 55d92239..a7879788 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java @@ -49,7 +49,9 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmUdpSrcSerializer; import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmVlanPcpSerializer; import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmVlanVidSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.ext.OnfOxmTcpFlagsSerializer; import org.opendaylight.openflowjava.protocol.impl.util.MatchEntrySerializerRegistryHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.TcpFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpOp; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSha; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSpa; @@ -93,7 +95,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; /** - * Initializes serializer registry with match entry serializers + * Initializes serializer registry with match entry serializers. * @author michal.polkorab */ public final class MatchEntriesInitializer { @@ -103,7 +105,7 @@ private MatchEntriesInitializer() { } /** - * Registers match entry serializers into provided registry + * Registers match entry serializers into provided registry. * @param serializerRegistry registry to be initialized with match entry serializers */ public static void registerMatchEntrySerializers(SerializerRegistry serializerRegistry) { @@ -152,5 +154,9 @@ public static void registerMatchEntrySerializers(SerializerRegistry serializerRe helper.registerSerializer(PbbIsid.class, new OxmPbbIsidSerializer()); helper.registerSerializer(TunnelId.class, new OxmTunnelIdSerializer()); helper.registerSerializer(Ipv6Exthdr.class, new OxmIpv6ExtHdrSerializer()); + + // Register approved openflow match entry serializers + helper.registerExperimenterSerializer(TcpFlags.class, EncodeConstants.ONF_EXPERIMENTER_ID, + new OnfOxmTcpFlagsSerializer()); } } 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 95303409..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 @@ -58,8 +58,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; /** + * Util class for init registration of serializers. * @author michal.polkorab - * */ public final class MessageFactoryInitializer { @@ -68,13 +68,14 @@ private MessageFactoryInitializer() { } /** - * Registers message serializers into provided registry + * Registers message serializers into provided registry. * @param serializerRegistry registry to be initialized with message serializers */ public static void registerMessageSerializers(SerializerRegistry serializerRegistry) { + CommonMessageRegistryHelper registryHelper; + // register OF v1.0 message serializers - short version = EncodeConstants.OF10_VERSION_ID; - CommonMessageRegistryHelper registryHelper = new CommonMessageRegistryHelper(version, serializerRegistry); + registryHelper = new CommonMessageRegistryHelper(EncodeConstants.OF10_VERSION_ID, serializerRegistry); registryHelper.registerSerializer(BarrierInput.class, new OF10BarrierInputMessageFactory()); registryHelper.registerSerializer(EchoInput.class, new EchoInputMessageFactory()); registryHelper.registerSerializer(EchoReplyInput.class, new EchoReplyInputMessageFactory()); @@ -88,9 +89,9 @@ public static void registerMessageSerializers(SerializerRegistry serializerRegis registryHelper.registerSerializer(PacketOutInput.class, new OF10PacketOutInputMessageFactory()); registryHelper.registerSerializer(PortModInput.class, new OF10PortModInputMessageFactory()); registryHelper.registerSerializer(SetConfigInput.class, new SetConfigMessageFactory()); + // register OF v1.3 message serializers - version = EncodeConstants.OF13_VERSION_ID; - registryHelper = new CommonMessageRegistryHelper(version, serializerRegistry); + registryHelper = new CommonMessageRegistryHelper(EncodeConstants.OF13_VERSION_ID, serializerRegistry); registryHelper.registerSerializer(BarrierInput.class, new BarrierInputMessageFactory()); registryHelper.registerSerializer(EchoInput.class, new EchoInputMessageFactory()); registryHelper.registerSerializer(EchoReplyInput.class, new EchoReplyInputMessageFactory()); @@ -108,7 +109,7 @@ public static void registerMessageSerializers(SerializerRegistry serializerRegis registryHelper.registerSerializer(PortModInput.class, new PortModInputMessageFactory()); registryHelper.registerSerializer(RoleRequestInput.class, new RoleRequestInputMessageFactory()); registryHelper.registerSerializer(SetAsyncInput.class, new SetAsyncInputMessageFactory()); - registryHelper.registerSerializer( SetConfigInput.class, new SetConfigMessageFactory()); + registryHelper.registerSerializer(SetConfigInput.class, new SetConfigMessageFactory()); registryHelper.registerSerializer(TableModInput.class, new TableModInputMessageFactory()); } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java index 5756352c..93831878 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java @@ -10,7 +10,6 @@ import java.util.HashMap; import java.util.Map; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector; @@ -27,23 +26,28 @@ * Stores and handles serializers
* K - {@link MessageTypeKey} type
* S - returned serializer type + * * @author michal.polkorab * @author timotej.kubas + * @author giuseppex.petralia@intel.com + * */ public class SerializerRegistryImpl implements SerializerRegistry { - private static final Logger LOGGER = LoggerFactory.getLogger(SerializerRegistryImpl.class); + private static final Logger LOG = LoggerFactory.getLogger(SerializerRegistryImpl.class); private static final short OF10 = EncodeConstants.OF10_VERSION_ID; private static final short OF13 = EncodeConstants.OF13_VERSION_ID; private Map, OFGeneralSerializer> registry; - @Override public void init() { registry = new HashMap<>(); // Openflow message type serializers MessageFactoryInitializer.registerMessageSerializers(this); + // Register Additional serializers + AdditionalMessageFactoryInitializer.registerMessageSerializers(this); + // match structure serializers registerSerializer(new MessageTypeKey<>(OF10, MatchV10.class), new OF10MatchSerializer()); registerSerializer(new MessageTypeKey<>(OF13, Match.class), new OF13MatchSerializer()); @@ -62,8 +66,7 @@ public void init() { */ @Override @SuppressWarnings("unchecked") - public S getSerializer( - MessageTypeKey msgTypeKey) { + public S getSerializer(MessageTypeKey msgTypeKey) { OFGeneralSerializer serializer = registry.get(msgTypeKey); if (serializer == null) { throw new IllegalStateException("Serializer for key: " + msgTypeKey @@ -74,15 +77,14 @@ public S getSerializer( } @Override - public void registerSerializer( - MessageTypeKey msgTypeKey, OFGeneralSerializer serializer) { + public void registerSerializer(MessageTypeKey msgTypeKey, OFGeneralSerializer serializer) { if ((msgTypeKey == null) || (serializer == null)) { throw new IllegalArgumentException("MessageTypeKey or Serializer is null"); } OFGeneralSerializer serInRegistry = registry.put(msgTypeKey, serializer); if (serInRegistry != null) { - LOGGER.debug("Serializer for key {} overwritten. Old serializer: {}, new serializer: {}", - msgTypeKey, serInRegistry.getClass().getName(), serializer.getClass().getName()); + LOG.debug("Serializer for key {} overwritten. Old serializer: {}, new serializer: {}", msgTypeKey, + serInRegistry.getClass().getName(), serializer.getClass().getName()); } if (serializer instanceof SerializerRegistryInjector) { ((SerializerRegistryInjector) serializer).injectSerializerRegistry(this); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java index e654466a..f735a444 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlDstCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; @@ -22,10 +21,10 @@ public class OF10SetDlDstActionSerializer extends AbstractActionSerializer { @Override - public void serialize(Action action, ByteBuf outBuffer) { + public void serialize(final Action action, final ByteBuf outBuffer) { super.serialize(action, outBuffer); - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(((SetDlDstCase) action.getActionChoice()) - .getSetDlDstAction().getDlDstAddress().getValue())); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(((SetDlDstCase) action.getActionChoice()) + .getSetDlDstAction().getDlDstAddress())); outBuffer.writeZero(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java index 67db7d57..dae1b318 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlSrcCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; @@ -22,10 +21,10 @@ public class OF10SetDlSrcActionSerializer extends AbstractActionSerializer { @Override - public void serialize(Action action, ByteBuf outBuffer) { + public void serialize(final Action action, final ByteBuf outBuffer) { super.serialize(action, outBuffer); - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(((SetDlSrcCase) action.getActionChoice()) - .getSetDlSrcAction().getDlSrcAddress().getValue())); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(((SetDlSrcCase) action.getActionChoice()) + .getSetDlSrcAction().getDlSrcAddress())); outBuffer.writeZero(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java index 73ecd595..a0f9f53f 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwDstCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; @@ -24,12 +23,8 @@ public class OF10SetNwDstActionSerializer extends AbstractActionSerializer { @Override public void serialize(final Action action, final ByteBuf outBuffer) { super.serialize(action, outBuffer); - Iterable addressGroups = ByteBufUtils.DOT_SPLITTER - .split(((SetNwDstCase) action.getActionChoice()).getSetNwDstAction() - .getIpAddress().getValue()); - for (String group : addressGroups) { - outBuffer.writeByte(Short.parseShort(group)); - } + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes( + ((SetNwDstCase) action.getActionChoice()).getSetNwDstAction().getIpAddress())); } @Override @@ -41,5 +36,4 @@ protected int getType() { protected int getLength() { return ActionConstants.GENERAL_ACTION_LENGTH; } - } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java index d63bf9c4..77e2be3d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java @@ -9,9 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.action; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; -import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwSrcCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; @@ -24,12 +23,8 @@ public class OF10SetNwSrcActionSerializer extends AbstractActionSerializer { @Override public void serialize(final Action action, final ByteBuf outBuffer) { super.serialize(action, outBuffer); - Iterable addressGroups = ByteBufUtils.DOT_SPLITTER - .split(((SetNwSrcCase) action.getActionChoice()).getSetNwSrcAction() - .getIpAddress().getValue()); - for (String group : addressGroups) { - outBuffer.writeByte(Short.parseShort(group)); - } + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes( + ((SetNwSrcCase) action.getActionChoice()).getSetNwSrcAction().getIpAddress())); } @Override diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java new file mode 100644 index 00000000..3212f784 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.BarrierOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class BarrierReplyMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 21; + + @Override + public void serialize(BarrierOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java new file mode 100644 index 00000000..3a244db3 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.EchoOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class EchoOutputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 3; + + @Override + public void serialize(EchoOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + byte[] data = message.getData(); + + if (data != null) { + outBuffer.writeBytes(data); + } + + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java new file mode 100644 index 00000000..9f5076cd --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.EchoRequestMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class EchoRequestMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 2; + + @Override + public void serialize(EchoRequestMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + byte[] data = message.getData(); + + if (data != null) { + outBuffer.writeBytes(data); + } + + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java new file mode 100644 index 00000000..2eeaf76e --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.ErrorMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class ErrorMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 1; + + @Override + public void serialize(ErrorMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getType()); + outBuffer.writeShort(message.getCode()); + byte[] data = message.getData(); + + if (data != null) { + outBuffer.writeBytes(data); + } + + ByteBufUtils.updateOFHeaderLength(outBuffer); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java new file mode 100644 index 00000000..dc6e66c8 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.ExperimenterMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class ExperimenterMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 4; + + @Override + public void serialize(ExperimenterMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getExperimenter().getValue().intValue()); + outBuffer.writeInt(message.getExpType().intValue()); + // TODO: Serializer for data field is vendor specific. + byte[] data = null; + + if (data != null) { + outBuffer.writeBytes(data); + } + ByteBufUtils.updateOFHeaderLength(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 79f831ba..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 @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector; @@ -22,14 +21,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowMod; /** - * Translates FlowMod messages + * Translates FlowMod messages. + * OF protocol versions: 1.3. * @author timotej.kubas * @author michal.polkorab */ -public class FlowModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { +public class FlowModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { private static final byte MESSAGE_TYPE = 14; private static final byte PADDING_IN_FLOW_MOD_MESSAGE = 2; private static final TypeKeyMaker INSTRUCTION_KEY_MAKER = @@ -37,14 +37,15 @@ public class FlowModInputMessageFactory implements OFSerializer, S private SerializerRegistry registry; @Override - public void serialize(final FlowModInput message, final ByteBuf outBuffer) { + 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()); outBuffer.writeByte(message.getTableId().getValue().byteValue()); outBuffer.writeByte(message.getCommand().getIntValue()); - outBuffer.writeShort(message.getIdleTimeout().intValue()); - outBuffer.writeShort(message.getHardTimeout().intValue()); + outBuffer.writeShort(message.getIdleTimeout()); + outBuffer.writeShort(message.getHardTimeout()); outBuffer.writeShort(message.getPriority()); outBuffer.writeInt(message.getBufferId().intValue()); outBuffer.writeInt(message.getOutPort().getValue().intValue()); @@ -54,7 +55,7 @@ public void serialize(final FlowModInput 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 new file mode 100644 index 00000000..11c2948b --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class FlowRemovedMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 11; + private SerializerRegistry registry; + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = 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()); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeByte(message.getTableId().getValue().byteValue()); + outBuffer.writeInt(message.getDurationSec().intValue()); + outBuffer.writeInt(message.getDurationNsec().intValue()); + outBuffer.writeShort(message.getIdleTimeout()); + outBuffer.writeShort(message.getHardTimeout()); + outBuffer.writeLong(message.getPacketCount().longValue()); + outBuffer.writeLong(message.getByteCount().longValue()); + OFSerializer matchSerializer = registry + .> getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class)); + matchSerializer.serialize(message.getMatch(), outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java new file mode 100644 index 00000000..4ba876c4 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMask; + +/** + * @author giuseppex.petralia@intel.com + * + */ + +public class GetAsyncReplyMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 27; + + @Override + public void serialize(GetAsyncOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + serializePacketInMask(message.getPacketInMask(), outBuffer); + serializePortStatusMask(message.getPortStatusMask(), outBuffer); + serializeFlowRemovedMask(message.getFlowRemovedMask(), outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private static void serializePacketInMask(List packetInMask, ByteBuf outBuffer) { + if (packetInMask != null) { + for (PacketInMask currentPacketMask : packetInMask) { + List mask = currentPacketMask.getMask(); + if (mask != null) { + Map packetInReasonMap = new HashMap<>(); + for (PacketInReason packetInReason : mask) { + if (PacketInReason.OFPRNOMATCH.equals(packetInReason)) { + packetInReasonMap.put(PacketInReason.OFPRNOMATCH.getIntValue(), true); + } else if (PacketInReason.OFPRACTION.equals(packetInReason)) { + packetInReasonMap.put(PacketInReason.OFPRACTION.getIntValue(), true); + } else if (PacketInReason.OFPRINVALIDTTL.equals(packetInReason)) { + packetInReasonMap.put(PacketInReason.OFPRINVALIDTTL.getIntValue(), true); + } + } + outBuffer.writeInt(ByteBufUtils.fillBitMaskFromMap(packetInReasonMap)); + } + } + } + } + + private static void serializePortStatusMask(List portStatusMask, ByteBuf outBuffer) { + if (portStatusMask != null) { + for (PortStatusMask currentPortStatusMask : portStatusMask) { + List mask = currentPortStatusMask.getMask(); + if (mask != null) { + Map portStatusReasonMap = new HashMap<>(); + for (PortReason packetInReason : mask) { + if (PortReason.OFPPRADD.equals(packetInReason)) { + portStatusReasonMap.put(PortReason.OFPPRADD.getIntValue(), true); + } else if (PortReason.OFPPRDELETE.equals(packetInReason)) { + portStatusReasonMap.put(PortReason.OFPPRDELETE.getIntValue(), true); + } else if (PortReason.OFPPRMODIFY.equals(packetInReason)) { + portStatusReasonMap.put(PortReason.OFPPRMODIFY.getIntValue(), true); + } + } + outBuffer.writeInt(ByteBufUtils.fillBitMaskFromMap(portStatusReasonMap)); + } + } + } + } + + private static void serializeFlowRemovedMask(List flowRemovedMask, ByteBuf outBuffer) { + if (flowRemovedMask != null) { + for (FlowRemovedMask currentFlowRemovedMask : flowRemovedMask) { + List mask = currentFlowRemovedMask.getMask(); + if (mask != null) { + Map flowRemovedReasonMap = new HashMap<>(); + for (FlowRemovedReason packetInReason : mask) { + if (FlowRemovedReason.OFPRRIDLETIMEOUT.equals(packetInReason)) { + flowRemovedReasonMap.put(FlowRemovedReason.OFPRRIDLETIMEOUT.getIntValue(), true); + } else if (FlowRemovedReason.OFPRRHARDTIMEOUT.equals(packetInReason)) { + flowRemovedReasonMap.put(FlowRemovedReason.OFPRRHARDTIMEOUT.getIntValue(), true); + } else if (FlowRemovedReason.OFPRRDELETE.equals(packetInReason)) { + flowRemovedReasonMap.put(FlowRemovedReason.OFPRRDELETE.getIntValue(), true); + } else if (FlowRemovedReason.OFPRRGROUPDELETE.equals(packetInReason)) { + flowRemovedReasonMap.put(FlowRemovedReason.OFPRRGROUPDELETE.getIntValue(), true); + } + } + outBuffer.writeInt(ByteBufUtils.fillBitMaskFromMap(flowRemovedReasonMap)); + } + } + } + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java new file mode 100644 index 00000000..d711b864 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.GetConfigOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetConfigReplyMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 8; + + @Override + public void serialize(GetConfigOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getFlags().getIntValue()); + outBuffer.writeShort(message.getMissSendLen()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java new file mode 100644 index 00000000..2a2fdc2a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.HashMap; +import java.util.Map; +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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetFeaturesOutputFactory implements OFSerializer, SerializerRegistryInjector { + + @SuppressWarnings("unused") + private SerializerRegistry registry; + private static final byte MESSAGE_TYPE = 6; + private static final byte PADDING = 2; + + @Override + public void serialize(GetFeaturesOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeLong(message.getDatapathId().longValue()); + outBuffer.writeInt(message.getBuffers().intValue()); + outBuffer.writeByte(message.getTables().intValue()); + outBuffer.writeByte(message.getAuxiliaryId().intValue()); + outBuffer.writeZero(PADDING); + writeCapabilities(message.getCapabilities(), outBuffer); + outBuffer.writeInt(message.getReserved().intValue()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + + private static void writeCapabilities(Capabilities capabilities, ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, capabilities.isOFPCFLOWSTATS()); + map.put(1, capabilities.isOFPCTABLESTATS()); + map.put(2, capabilities.isOFPCPORTSTATS()); + map.put(3, capabilities.isOFPCGROUPSTATS()); + map.put(5, capabilities.isOFPCIPREASM()); + map.put(6, capabilities.isOFPCQUEUESTATS()); + map.put(8, capabilities.isOFPCPORTBLOCKED()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } +} 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 93e4c741..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 @@ -9,39 +9,39 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; 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.protocol.impl.util.TypeKeyMakerFactory; import org.opendaylight.openflowjava.protocol.impl.util.ListSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupMod; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; /** - * Translates GroupMod messages + * Translates GroupMod messages. + * OF protocol versions: 1.3. * @author timotej.kubas * @author michal.polkorab */ -public class GroupModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { +public class GroupModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { private static final byte MESSAGE_TYPE = 15; private static final byte PADDING_IN_GROUP_MOD_MESSAGE = 1; private static final byte PADDING_IN_BUCKET = 4; private SerializerRegistry registry; @Override - public void serialize(GroupModInput message, ByteBuf outBuffer) { + 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/HelloMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactory.java new file mode 100644 index 00000000..b3ccbbe7 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.HelloMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class HelloMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 0; + + @Override + public void serialize(HelloMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java old mode 100644 new mode 100755 index 770c0cfd..36eb64f5 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java @@ -9,9 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; 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; @@ -19,6 +16,7 @@ import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMeterBand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterMeterBandSubType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterBandCommons; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; @@ -30,6 +28,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemark; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.experimenter._case.MeterBandExperimenter; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.Bands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; /** * Translates MeterMod messages @@ -39,6 +41,8 @@ public class MeterModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { + private static final Logger LOG = LoggerFactory + .getLogger(MeterModInputMessageFactory.class); private static final byte MESSAGE_TYPE = 29; private static final short LENGTH_OF_METER_BANDS = 16; private static final short PADDING_IN_METER_BAND_DROP = 4; @@ -81,12 +85,20 @@ private void serializeBands(final List bands, final ByteBuf outBuffer) { } else if (meterBand instanceof MeterBandExperimenterCase) { MeterBandExperimenterCase experimenterBandCase = (MeterBandExperimenterCase) meterBand; MeterBandExperimenter experimenterBand = experimenterBandCase.getMeterBandExperimenter(); - long expId = experimenterBand.getAugmentation(ExperimenterIdMeterBand.class) - .getExperimenter().getValue(); - OFSerializer serializer = registry.getSerializer( - ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( - EncodeConstants.OF13_VERSION_ID, expId)); - serializer.serialize(experimenterBandCase, outBuffer); + ExperimenterIdMeterBand expIdMeterBand = experimenterBand.getAugmentation(ExperimenterIdMeterBand.class); + if (expIdMeterBand != null) { + long expId = expIdMeterBand.getExperimenter().getValue(); + Class meterBandSubType = expIdMeterBand.getSubType(); + try { + OFSerializer serializer = registry.getSerializer( + ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( + EncodeConstants.OF13_VERSION_ID, expId, meterBandSubType)); + serializer.serialize(experimenterBandCase, outBuffer); + } catch (final IllegalStateException e) { + LOG.warn("Serializer for key: {} wasn't found, exception {}", ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( + EncodeConstants.OF13_VERSION_ID, expId, meterBandSubType), e); + } + } } } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java new file mode 100644 index 00000000..4c5bd83a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java @@ -0,0 +1,790 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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.util.ListSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +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.PortState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterBandCommons; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.MeterBand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDrop; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemark; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.experimenter._case.MeterBandExperimenter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.Bands; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartReplyMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 19; + private SerializerRegistry registry; + private static final byte PADDING = 4; + private static final byte PORT_DESC_PADDING_1 = 4; + private static final byte PORT_DESC_PADDING_2 = 2; + private static final int FLOW_STATS_LENGTH_INDEX = 0; + private static final byte FLOW_STATS_PADDING_1 = 1; + private static final byte FLOW_STATS_PADDING_2 = 6; + private static final byte AGGREGATE_PADDING = 4; + private static final byte TABLE_PADDING = 3; + private static final byte PORT_STATS_PADDING = 4; + private static final byte GROUP_STATS_PADDING_1 = 2; + private static final byte GROUP_STATS_PADDING_2 = 4; + private static final int GROUP_STATS_LENGTH_INDEX = 0; + private static final int GROUP_DESC_LENGTH_INDEX = 0; + private static final int BUCKET_LENGTH_INDEX = 0; + private static final byte GROUP_DESC_PADDING = 1; + private static final byte BUCKET_PADDING = 4; + private static final int METER_LENGTH_INDEX = 4; + private static final byte METER_PADDING = 6; + private static final int METER_CONFIG_LENGTH_INDEX = 0; + private static final short LENGTH_OF_METER_BANDS = 16; + private static final byte METER_FEATURES_PADDING = 2; + private static final int TABLE_FEATURES_LENGTH_INDEX = 0; + private static final byte TABLE_FEATURES_PADDING = 5; + private static final byte INSTRUCTIONS_CODE = 0; + private static final byte INSTRUCTIONS_MISS_CODE = 1; + private static final byte NEXT_TABLE_CODE = 2; + private static final byte NEXT_TABLE_MISS_CODE = 3; + private static final byte WRITE_ACTIONS_CODE = 4; + private static final byte WRITE_ACTIONS_MISS_CODE = 5; + private static final byte APPLY_ACTIONS_CODE = 6; + private static final byte APPLY_ACTIONS_MISS_CODE = 7; + private static final byte MATCH_CODE = 8; + private static final byte WILDCARDS_CODE = 10; + private static final byte WRITE_SETFIELD_CODE = 12; + private static final byte WRITE_SETFIELD_MISS_CODE = 13; + private static final byte APPLY_SETFIELD_CODE = 14; + private static final byte APPLY_SETFIELD_MISS_CODE = 15; + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + + @Override + public void serialize(final MultipartReplyMessage message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getType().getIntValue()); + writeFlags(message.getFlags(), outBuffer); + outBuffer.writeZero(PADDING); + switch (message.getType()) { + case OFPMPDESC: + serializeDescBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPFLOW: + serializeFlowBody(message.getMultipartReplyBody(), outBuffer, message); + break; + case OFPMPAGGREGATE: + serializeAggregateBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPTABLE: + serializeTableBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPPORTSTATS: + serializePortStatsBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPQUEUE: + serializeQueueBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPGROUP: + serializeGroupBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPGROUPDESC: + serializeGroupDescBody(message.getMultipartReplyBody(), outBuffer, message); + break; + case OFPMPGROUPFEATURES: + serializeGroupFeaturesBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPMETER: + serializeMeterBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPMETERCONFIG: + serializeMeterConfigBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPMETERFEATURES: + serializeMeterFeaturesBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPTABLEFEATURES: + serializeTableFeaturesBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPPORTDESC: + serializePortDescBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPEXPERIMENTER: + serializeExperimenterBody(message.getMultipartReplyBody(), outBuffer); + break; + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void serializeExperimenterBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyExperimenterCase experimenterCase = (MultipartReplyExperimenterCase) body; + MultipartReplyExperimenter experimenterBody = experimenterCase.getMultipartReplyExperimenter(); + // TODO: experimenterBody does not have get methods + } + + private void writeFlags(final MultipartRequestFlags flags, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, flags.isOFPMPFREQMORE()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeShort(bitmap); + } + + private void serializeTableFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyTableFeaturesCase tableFeaturesCase = (MultipartReplyTableFeaturesCase) body; + MultipartReplyTableFeatures tableFeatures = tableFeaturesCase.getMultipartReplyTableFeatures(); + for (TableFeatures tableFeature : tableFeatures.getTableFeatures()) { + ByteBuf tableFeatureBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + tableFeatureBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + tableFeatureBuff.writeByte(tableFeature.getTableId()); + tableFeatureBuff.writeZero(TABLE_FEATURES_PADDING); + write32String(tableFeature.getName(), tableFeatureBuff); + tableFeatureBuff.writeBytes(tableFeature.getMetadataMatch()); + tableFeatureBuff.writeZero(64 - tableFeature.getMetadataMatch().length); + tableFeatureBuff.writeBytes(tableFeature.getMetadataWrite()); + tableFeatureBuff.writeZero(64 - tableFeature.getMetadataWrite().length); + writeTableConfig(tableFeature.getConfig(), tableFeatureBuff); + tableFeatureBuff.writeInt(tableFeature.getMaxEntries().intValue()); + for (TableFeatureProperties tableFeatureProp : tableFeature.getTableFeatureProperties()) { + switch (tableFeatureProp.getType()) { + case OFPTFPTINSTRUCTIONS: + writeInstructionRelatedTableProperty(tableFeatureBuff, tableFeatureProp, INSTRUCTIONS_CODE); + break; + case OFPTFPTINSTRUCTIONSMISS: + writeInstructionRelatedTableProperty(tableFeatureBuff, tableFeatureProp, INSTRUCTIONS_MISS_CODE); + break; + case OFPTFPTNEXTTABLES: + writeNextTableRelatedTableProperty(tableFeatureBuff, tableFeatureProp, NEXT_TABLE_CODE); + break; + case OFPTFPTNEXTTABLESMISS: + writeNextTableRelatedTableProperty(tableFeatureBuff, tableFeatureProp, NEXT_TABLE_MISS_CODE); + break; + case OFPTFPTWRITEACTIONS: + writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_ACTIONS_CODE); + break; + case OFPTFPTWRITEACTIONSMISS: + writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_ACTIONS_MISS_CODE); + break; + case OFPTFPTAPPLYACTIONS: + writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_ACTIONS_CODE); + break; + case OFPTFPTAPPLYACTIONSMISS: + writeActionsRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_ACTIONS_MISS_CODE); + break; + case OFPTFPTMATCH: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, MATCH_CODE); + break; + case OFPTFPTWILDCARDS: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WILDCARDS_CODE); + break; + case OFPTFPTWRITESETFIELD: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_SETFIELD_CODE); + break; + case OFPTFPTWRITESETFIELDMISS: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, WRITE_SETFIELD_MISS_CODE); + break; + case OFPTFPTAPPLYSETFIELD: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_SETFIELD_CODE); + break; + case OFPTFPTAPPLYSETFIELDMISS: + writeOxmRelatedTableProperty(tableFeatureBuff, tableFeatureProp, APPLY_SETFIELD_MISS_CODE); + break; + case OFPTFPTEXPERIMENTER: + writeExperimenterRelatedTableProperty(tableFeatureBuff, tableFeatureProp); + break; + case OFPTFPTEXPERIMENTERMISS: + writeExperimenterRelatedTableProperty(tableFeatureBuff, tableFeatureProp); + break; + } + } + tableFeatureBuff.setShort(TABLE_FEATURES_LENGTH_INDEX, tableFeatureBuff.readableBytes()); + outBuffer.writeBytes(tableFeatureBuff); + } + } + + private void writeExperimenterRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property) { + long expId = property.getAugmentation(ExperimenterIdTableFeatureProperty.class).getExperimenter().getValue(); + OFSerializer serializer = registry.getSerializer(ExperimenterSerializerKeyFactory + .createMultipartRequestTFSerializerKey(EncodeConstants.OF13_VERSION_ID, expId)); + serializer.serialize(property, output); + } + + private void writeOxmRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property, + final byte code) { + int startIndex = output.writerIndex(); + output.writeShort(code); + int lengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + List entries = property.getAugmentation(OxmRelatedTableFeatureProperty.class).getMatchEntry(); + if (entries != null) { + TypeKeyMaker keyMaker = TypeKeyMakerFactory + .createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + ListSerializer.serializeHeaderList(entries, keyMaker, registry, output); + } + int length = output.writerIndex() - startIndex; + output.setShort(lengthIndex, length); + output.writeZero(paddingNeeded(length)); + } + + private void writeActionsRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property, + final byte code) { + int startIndex = output.writerIndex(); + output.writeShort(code); + int lengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + List actions = property.getAugmentation(ActionRelatedTableFeatureProperty.class).getAction(); + if (actions != null) { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID); + ListSerializer.serializeHeaderList(actions, keyMaker, registry, output); + } + int length = output.writerIndex() - startIndex; + output.setShort(lengthIndex, length); + output.writeZero(paddingNeeded(length)); + } + + private static void writeNextTableRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property, + final byte code) { + int startIndex = output.writerIndex(); + output.writeShort(code); + int lengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + List nextTableIds = property.getAugmentation(NextTableRelatedTableFeatureProperty.class) + .getNextTableIds(); + if (nextTableIds != null) { + for (NextTableIds next : nextTableIds) { + output.writeByte(next.getTableId()); + } + } + int length = output.writerIndex() - startIndex; + output.setShort(lengthIndex, length); + output.writeZero(paddingNeeded(length)); + } + + private void writeInstructionRelatedTableProperty(final ByteBuf output, final TableFeatureProperties property, + final byte code) { + int startIndex = output.writerIndex(); + output.writeShort(code); + int lengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + List instructions = property.getAugmentation(InstructionRelatedTableFeatureProperty.class) + .getInstruction(); + if (instructions != null) { + TypeKeyMaker keyMaker = TypeKeyMakerFactory + .createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID); + ListSerializer.serializeHeaderList(instructions, keyMaker, registry, output); + } + int length = output.writerIndex() - startIndex; + output.setShort(lengthIndex, length); + output.writeZero(paddingNeeded(length)); + } + + private static int paddingNeeded(final int length) { + int paddingRemainder = length % EncodeConstants.PADDING; + int result = 0; + if (paddingRemainder != 0) { + result = EncodeConstants.PADDING - paddingRemainder; + } + return result; + } + + private void writeTableConfig(final TableConfig tableConfig, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, tableConfig.isOFPTCDEPRECATEDMASK()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void serializeMeterFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyMeterFeaturesCase meterFeaturesCase = (MultipartReplyMeterFeaturesCase) body; + MultipartReplyMeterFeatures meterFeatures = meterFeaturesCase.getMultipartReplyMeterFeatures(); + outBuffer.writeInt(meterFeatures.getMaxMeter().intValue()); + writeBandTypes(meterFeatures.getBandTypes(), outBuffer); + writeMeterFlags(meterFeatures.getCapabilities(), outBuffer); + outBuffer.writeByte(meterFeatures.getMaxBands()); + outBuffer.writeByte(meterFeatures.getMaxColor()); + outBuffer.writeZero(METER_FEATURES_PADDING); + } + + private void writeBandTypes(final MeterBandTypeBitmap bandTypes, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, bandTypes.isOFPMBTDROP()); + map.put(1, bandTypes.isOFPMBTDSCPREMARK()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void serializeMeterConfigBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyMeterConfigCase meterConfigCase = (MultipartReplyMeterConfigCase) body; + MultipartReplyMeterConfig meter = meterConfigCase.getMultipartReplyMeterConfig(); + for (MeterConfig meterConfig : meter.getMeterConfig()) { + ByteBuf meterConfigBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + meterConfigBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + writeMeterFlags(meterConfig.getFlags(), meterConfigBuff); + meterConfigBuff.writeInt(meterConfig.getMeterId().getValue().intValue()); + for (Bands currentBand : meterConfig.getBands()) { + MeterBand meterBand = currentBand.getMeterBand(); + if (meterBand instanceof MeterBandDropCase) { + MeterBandDropCase dropBandCase = (MeterBandDropCase) meterBand; + MeterBandDrop dropBand = dropBandCase.getMeterBandDrop(); + writeBandCommonFields(dropBand, meterConfigBuff); + } else if (meterBand instanceof MeterBandDscpRemarkCase) { + MeterBandDscpRemarkCase dscpRemarkBandCase = (MeterBandDscpRemarkCase) meterBand; + MeterBandDscpRemark dscpRemarkBand = dscpRemarkBandCase.getMeterBandDscpRemark(); + writeBandCommonFields(dscpRemarkBand, meterConfigBuff); + } else if (meterBand instanceof MeterBandExperimenterCase) { + MeterBandExperimenterCase experimenterBandCase = (MeterBandExperimenterCase) meterBand; + MeterBandExperimenter experimenterBand = experimenterBandCase.getMeterBandExperimenter(); + writeBandCommonFields(experimenterBand, meterConfigBuff); + } + } + meterConfigBuff.setShort(METER_CONFIG_LENGTH_INDEX, meterConfigBuff.readableBytes()); + outBuffer.writeBytes(meterConfigBuff); + } + } + + private static void writeBandCommonFields(final MeterBandCommons meterBand, final ByteBuf outBuffer) { + outBuffer.writeShort(meterBand.getType().getIntValue()); + outBuffer.writeShort(LENGTH_OF_METER_BANDS); + outBuffer.writeInt(meterBand.getRate().intValue()); + outBuffer.writeInt(meterBand.getBurstSize().intValue()); + } + + private void writeMeterFlags(final MeterFlags flags, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, flags.isOFPMFKBPS()); + map.put(1, flags.isOFPMFPKTPS()); + map.put(2, flags.isOFPMFBURST()); + map.put(3, flags.isOFPMFSTATS()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeShort(bitmap); + } + + private void serializeMeterBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyMeterCase meterCase = (MultipartReplyMeterCase) body; + MultipartReplyMeter meter = meterCase.getMultipartReplyMeter(); + for (MeterStats meterStats : meter.getMeterStats()) { + ByteBuf meterStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + meterStatsBuff.writeInt(meterStats.getMeterId().getValue().intValue()); + meterStatsBuff.writeInt(EncodeConstants.EMPTY_LENGTH); + meterStatsBuff.writeZero(METER_PADDING); + meterStatsBuff.writeInt(meterStats.getFlowCount().intValue()); + meterStatsBuff.writeLong(meterStats.getPacketInCount().longValue()); + meterStatsBuff.writeLong(meterStats.getByteInCount().longValue()); + meterStatsBuff.writeInt(meterStats.getDurationSec().intValue()); + meterStatsBuff.writeInt(meterStats.getDurationNsec().intValue()); + for (MeterBandStats meterBandStats : meterStats.getMeterBandStats()) { + meterStatsBuff.writeLong(meterBandStats.getPacketBandCount().longValue()); + meterStatsBuff.writeLong(meterBandStats.getByteBandCount().longValue()); + } + meterStatsBuff.setInt(METER_LENGTH_INDEX, meterStatsBuff.readableBytes()); + outBuffer.writeBytes(meterStatsBuff); + } + } + + private void serializeGroupFeaturesBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyGroupFeaturesCase groupFeaturesCase = (MultipartReplyGroupFeaturesCase) body; + MultipartReplyGroupFeatures groupFeatures = groupFeaturesCase.getMultipartReplyGroupFeatures(); + writeGroupTypes(groupFeatures.getTypes(), outBuffer); + writeGroupCapabilities(groupFeatures.getCapabilities(), outBuffer); + for (Long maxGroups : groupFeatures.getMaxGroups()) { + outBuffer.writeInt(maxGroups.intValue()); + } + for (ActionType action : groupFeatures.getActionsBitmap()) { + writeActionType(action, outBuffer); + } + } + + private void writeActionType(final ActionType action, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, action.isOFPATOUTPUT()); + map.put(1, action.isOFPATCOPYTTLOUT()); + map.put(2, action.isOFPATCOPYTTLIN()); + map.put(3, action.isOFPATSETMPLSTTL()); + map.put(4, action.isOFPATDECMPLSTTL()); + map.put(5, action.isOFPATPUSHVLAN()); + map.put(6, action.isOFPATPOPVLAN()); + map.put(7, action.isOFPATPUSHMPLS()); + map.put(8, action.isOFPATPOPMPLS()); + map.put(9, action.isOFPATSETQUEUE()); + map.put(10, action.isOFPATGROUP()); + map.put(11, action.isOFPATSETNWTTL()); + map.put(12, action.isOFPATDECNWTTL()); + map.put(13, action.isOFPATSETFIELD()); + map.put(14, action.isOFPATPUSHPBB()); + map.put(15, action.isOFPATPOPPBB()); + map.put(16, action.isOFPATEXPERIMENTER()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writeGroupCapabilities(final GroupCapabilities capabilities, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, capabilities.isOFPGFCSELECTWEIGHT()); + map.put(1, capabilities.isOFPGFCSELECTLIVENESS()); + map.put(2, capabilities.isOFPGFCCHAINING()); + map.put(3, capabilities.isOFPGFCCHAININGCHECKS()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writeGroupTypes(final GroupTypes types, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, types.isOFPGTALL()); + map.put(1, types.isOFPGTSELECT()); + map.put(2, types.isOFPGTINDIRECT()); + map.put(3, types.isOFPGTFF()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void serializeGroupDescBody(final MultipartReplyBody body, final ByteBuf outBuffer, final MultipartReplyMessage message) { + MultipartReplyGroupDescCase groupDescCase = (MultipartReplyGroupDescCase) body; + MultipartReplyGroupDesc group = groupDescCase.getMultipartReplyGroupDesc(); + for (GroupDesc groupDesc : group.getGroupDesc()) { + ByteBuf groupDescBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + groupDescBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + groupDescBuff.writeByte(groupDesc.getType().getIntValue()); + groupDescBuff.writeZero(GROUP_DESC_PADDING); + groupDescBuff.writeInt(groupDesc.getGroupId().getValue().intValue()); + for (BucketsList bucket : groupDesc.getBucketsList()) { + ByteBuf bucketBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + bucketBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + bucketBuff.writeShort(bucket.getWeight()); + bucketBuff.writeInt(bucket.getWatchPort().getValue().intValue()); + bucketBuff.writeInt(bucket.getWatchGroup().intValue()); + bucketBuff.writeZero(BUCKET_PADDING); + ListSerializer.serializeList(bucket.getAction(), + TypeKeyMakerFactory.createActionKeyMaker(message.getVersion()), registry, bucketBuff); + bucketBuff.setShort(BUCKET_LENGTH_INDEX, bucketBuff.readableBytes()); + groupDescBuff.writeBytes(bucketBuff); + } + groupDescBuff.setShort(GROUP_DESC_LENGTH_INDEX, groupDescBuff.readableBytes()); + outBuffer.writeBytes(groupDescBuff); + } + } + + private void serializeGroupBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyGroupCase groupCase = (MultipartReplyGroupCase) body; + MultipartReplyGroup group = groupCase.getMultipartReplyGroup(); + for (GroupStats groupStats : group.getGroupStats()) { + ByteBuf groupStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + groupStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + groupStatsBuff.writeZero(GROUP_STATS_PADDING_1); + groupStatsBuff.writeInt(groupStats.getGroupId().getValue().intValue()); + groupStatsBuff.writeInt(groupStats.getRefCount().intValue()); + groupStatsBuff.writeZero(GROUP_STATS_PADDING_2); + groupStatsBuff.writeLong(groupStats.getPacketCount().longValue()); + groupStatsBuff.writeLong(groupStats.getByteCount().longValue()); + groupStatsBuff.writeInt(groupStats.getDurationSec().intValue()); + groupStatsBuff.writeInt(groupStats.getDurationNsec().intValue()); + for (BucketStats bucketStats : groupStats.getBucketStats()) { + groupStatsBuff.writeLong(bucketStats.getPacketCount().longValue()); + groupStatsBuff.writeLong(bucketStats.getByteCount().longValue()); + } + groupStatsBuff.setShort(GROUP_STATS_LENGTH_INDEX, groupStatsBuff.readableBytes()); + outBuffer.writeBytes(groupStatsBuff); + } + } + + private void serializeQueueBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyQueueCase queueCase = (MultipartReplyQueueCase) body; + MultipartReplyQueue queue = queueCase.getMultipartReplyQueue(); + for (QueueStats queueStats : queue.getQueueStats()) { + outBuffer.writeInt(queueStats.getPortNo().intValue()); + outBuffer.writeInt(queueStats.getQueueId().intValue()); + outBuffer.writeLong(queueStats.getTxBytes().longValue()); + outBuffer.writeLong(queueStats.getTxPackets().longValue()); + outBuffer.writeLong(queueStats.getTxErrors().longValue()); + outBuffer.writeInt(queueStats.getDurationSec().intValue()); + outBuffer.writeInt(queueStats.getDurationNsec().intValue()); + } + } + + private void serializePortStatsBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyPortStatsCase portStatsCase = (MultipartReplyPortStatsCase) body; + MultipartReplyPortStats portStats = portStatsCase.getMultipartReplyPortStats(); + for (PortStats portStat : portStats.getPortStats()) { + outBuffer.writeInt(portStat.getPortNo().intValue()); + outBuffer.writeZero(PORT_STATS_PADDING); + outBuffer.writeLong(portStat.getRxPackets().longValue()); + outBuffer.writeLong(portStat.getTxPackets().longValue()); + outBuffer.writeLong(portStat.getRxBytes().longValue()); + outBuffer.writeLong(portStat.getTxBytes().longValue()); + outBuffer.writeLong(portStat.getRxDropped().longValue()); + outBuffer.writeLong(portStat.getTxDropped().longValue()); + outBuffer.writeLong(portStat.getRxErrors().longValue()); + outBuffer.writeLong(portStat.getTxErrors().longValue()); + outBuffer.writeLong(portStat.getRxFrameErr().longValue()); + outBuffer.writeLong(portStat.getRxOverErr().longValue()); + outBuffer.writeLong(portStat.getRxCrcErr().longValue()); + outBuffer.writeLong(portStat.getCollisions().longValue()); + outBuffer.writeInt(portStat.getDurationSec().intValue()); + outBuffer.writeInt(portStat.getDurationNsec().intValue()); + } + } + + private void serializeTableBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyTableCase tableCase = (MultipartReplyTableCase) body; + MultipartReplyTable table = tableCase.getMultipartReplyTable(); + for (TableStats tableStats : table.getTableStats()) { + outBuffer.writeByte(tableStats.getTableId()); + outBuffer.writeZero(TABLE_PADDING); + outBuffer.writeInt(tableStats.getActiveCount().intValue()); + outBuffer.writeLong(tableStats.getLookupCount().longValue()); + outBuffer.writeLong(tableStats.getMatchedCount().longValue()); + } + } + + private void serializeAggregateBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyAggregateCase aggregateCase = (MultipartReplyAggregateCase) body; + MultipartReplyAggregate aggregate = aggregateCase.getMultipartReplyAggregate(); + outBuffer.writeLong(aggregate.getPacketCount().longValue()); + outBuffer.writeLong(aggregate.getByteCount().longValue()); + outBuffer.writeInt(aggregate.getFlowCount().intValue()); + outBuffer.writeZero(AGGREGATE_PADDING); + } + + private void serializeFlowBody(final MultipartReplyBody body, final ByteBuf outBuffer, final MultipartReplyMessage message) { + MultipartReplyFlowCase flowCase = (MultipartReplyFlowCase) body; + MultipartReplyFlow flow = flowCase.getMultipartReplyFlow(); + for (FlowStats flowStats : flow.getFlowStats()) { + ByteBuf flowStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + flowStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + flowStatsBuff.writeByte(new Long(flowStats.getTableId()).byteValue()); + flowStatsBuff.writeZero(FLOW_STATS_PADDING_1); + flowStatsBuff.writeInt(flowStats.getDurationSec().intValue()); + flowStatsBuff.writeInt(flowStats.getDurationNsec().intValue()); + flowStatsBuff.writeShort(flowStats.getPriority()); + flowStatsBuff.writeShort(flowStats.getIdleTimeout()); + flowStatsBuff.writeShort(flowStats.getHardTimeout()); + flowStatsBuff.writeZero(FLOW_STATS_PADDING_2); + flowStatsBuff.writeLong(flowStats.getCookie().longValue()); + flowStatsBuff.writeLong(flowStats.getPacketCount().longValue()); + flowStatsBuff.writeLong(flowStats.getByteCount().longValue()); + OFSerializer matchSerializer = registry.> getSerializer( + new MessageTypeKey<>(message.getVersion(), Match.class)); + matchSerializer.serialize(flowStats.getMatch(), flowStatsBuff); + ListSerializer.serializeList(flowStats.getInstruction(), + TypeKeyMakerFactory.createInstructionKeyMaker(message.getVersion()), registry, flowStatsBuff); + + flowStatsBuff.setShort(FLOW_STATS_LENGTH_INDEX, flowStatsBuff.readableBytes()); + outBuffer.writeBytes(flowStatsBuff); + } + } + + private void serializeDescBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyDescCase descCase = (MultipartReplyDescCase) body; + MultipartReplyDesc desc = descCase.getMultipartReplyDesc(); + write256String(desc.getMfrDesc(), outBuffer); + write256String(desc.getHwDesc(), outBuffer); + write256String(desc.getSwDesc(), outBuffer); + write32String(desc.getSerialNum(), outBuffer); + write256String(desc.getDpDesc(), outBuffer); + } + + private void write256String(final String toWrite, final ByteBuf outBuffer) { + byte[] nameBytes = toWrite.getBytes(); + if (nameBytes.length < 256) { + byte[] nameBytesPadding = new byte[256]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 256; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } + + private void write32String(final String toWrite, final ByteBuf outBuffer) { + byte[] nameBytes = toWrite.getBytes(); + if (nameBytes.length < 32) { + byte[] nameBytesPadding = new byte[32]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 32; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } + + private void serializePortDescBody(final MultipartReplyBody body, final ByteBuf outBuffer) { + MultipartReplyPortDescCase portCase = (MultipartReplyPortDescCase) body; + MultipartReplyPortDesc portDesc = portCase.getMultipartReplyPortDesc(); + for (Ports port : portDesc.getPorts()) { + outBuffer.writeInt(port.getPortNo().intValue()); // Assuming PortNo + // = PortId + outBuffer.writeZero(PORT_DESC_PADDING_1); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(port.getHwAddr())); + outBuffer.writeZero(PORT_DESC_PADDING_2); + writeName(port.getName(), outBuffer); + writePortConfig(port.getConfig(), outBuffer); + writePortState(port.getState(), outBuffer); + writePortFeatures(port.getCurrentFeatures(), outBuffer); + writePortFeatures(port.getAdvertisedFeatures(), outBuffer); + writePortFeatures(port.getSupportedFeatures(), outBuffer); + writePortFeatures(port.getPeerFeatures(), outBuffer); + outBuffer.writeInt(port.getCurrSpeed().intValue()); + outBuffer.writeInt(port.getMaxSpeed().intValue()); + } + } + + private void writeName(final String name, final ByteBuf outBuffer) { + byte[] nameBytes = name.getBytes(); + if (nameBytes.length < 16) { + byte[] nameBytesPadding = new byte[16]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 16; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + + } + + private void writePortConfig(final PortConfig config, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, config.isPortDown()); + map.put(2, config.isNoRecv()); + map.put(5, config.isNoFwd()); + map.put(6, config.isNoPacketIn()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortState(final PortState state, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, state.isLinkDown()); + map.put(1, state.isBlocked()); + map.put(2, state.isLive()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortFeatures(final PortFeatures features, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, features.is_10mbHd()); + map.put(1, features.is_10mbFd()); + map.put(2, features.is_100mbHd()); + map.put(3, features.is_100mbFd()); + map.put(4, features.is_1gbHd()); + map.put(5, features.is_1gbFd()); + map.put(6, features.is_10gbFd()); + map.put(7, features.is_40gbFd()); + map.put(8, features.is_100gbFd()); + map.put(9, features.is_1tbFd()); + map.put(10, features.isOther()); + map.put(11, features.isCopper()); + map.put(12, features.isFiber()); + map.put(13, features.isAutoneg()); + map.put(14, features.isPause()); + map.put(15, features.isPauseAsym()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java index 2287a64a..d4f7ab54 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java @@ -64,7 +64,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; /** - * Translates MultipartRequest messages + * Translates MultipartRequest messages. * @author timotej.kubas * @author michal.polkorab */ @@ -160,50 +160,26 @@ private static int createMultipartRequestFlagsBitmask(final MultipartRequestFlag return ByteBufUtils.fillBitMask(0, flags.isOFPMPFREQMORE()); } - /** - * @param multipartRequestBody - * @param output - */ private void serializeDescBody() { // The body of MultiPartRequestDesc is empty } - /** - * @param multipartRequestBody - * @param out - */ private void serializeTableBody() { // The body of MultiPartTable is empty } - /** - * @param multipartRequestBody - * @param out - */ private void serializeGroupDescBody() { // The body of MultiPartRequestGroupDesc is empty } - /** - * @param multipartRequestBody - * @param out - */ private void serializeGroupFeaturesBody() { // The body of MultiPartRequestGroupFeatures is empty } - /** - * @param multipartRequestBody - * @param out - */ private void serializeMeterFeaturesBody() { // The body of MultiPartMeterFeatures is empty } - /** - * @param multipartRequestBody - * @param out - */ private void serializePortDescBody() { // The body of MultiPartPortDesc is empty } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java new file mode 100644 index 00000000..2e317a1d --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.BarrierOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10BarrierReplyMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 19; + + @Override + public void serialize(BarrierOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java new file mode 100644 index 00000000..0df774df --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.HashMap; +import java.util.Map; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionTypeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FeaturesReplyMessageFactory implements OFSerializer { + + private static final byte PADDING = 3; + private static final byte MESSAGE_TYPE = 6; + + @Override + public void serialize(final GetFeaturesOutput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeLong(message.getDatapathId().longValue()); + outBuffer.writeInt(message.getBuffers().intValue()); + outBuffer.writeByte(message.getTables().intValue()); + outBuffer.writeZero(PADDING); + outBuffer.writeInt(createCapabilities(message.getCapabilitiesV10())); + outBuffer.writeInt(createActionsV10(message.getActionsV10())); + for (PhyPort port : message.getPhyPort()) { + outBuffer.writeShort(port.getPortNo().intValue()); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(port.getHwAddr())); + writeName(port.getName(), outBuffer); + writePortConfig(port.getConfigV10(), outBuffer); + writePortState(port.getStateV10(), outBuffer); + writePortFeature(port.getCurrentFeaturesV10(), outBuffer); + writePortFeature(port.getAdvertisedFeaturesV10(), outBuffer); + writePortFeature(port.getSupportedFeaturesV10(), outBuffer); + writePortFeature(port.getPeerFeaturesV10(), outBuffer); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void writePortFeature(final PortFeaturesV10 feature, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, feature.is_10mbHd()); + map.put(1, feature.is_10mbFd()); + map.put(2, feature.is_100mbHd()); + map.put(3, feature.is_100mbFd()); + map.put(4, feature.is_1gbHd()); + map.put(5, feature.is_1gbFd()); + map.put(6, feature.is_10gbFd()); + map.put(7, feature.isCopper()); + map.put(8, feature.isFiber()); + map.put(9, feature.isAutoneg()); + map.put(10, feature.isPause()); + map.put(11, feature.isPauseAsym()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortState(final PortStateV10 state, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, state.isLinkDown()); + map.put(1, state.isBlocked()); + map.put(2, state.isLive()); + map.put(3, state.isStpListen()); + map.put(4, state.isStpLearn()); + map.put(5, state.isStpForward()); + map.put(6, state.isStpBlock()); + map.put(7, state.isStpMask()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortConfig(final PortConfigV10 config, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, config.isPortDown()); + map.put(1, config.isNoStp()); + map.put(2, config.isNoRecv()); + map.put(3, config.isNoRecvStp()); + map.put(4, config.isNoFlood()); + map.put(5, config.isNoFwd()); + map.put(6, config.isNoPacketIn()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private static int createCapabilities(final CapabilitiesV10 capabilities) { + Map map = new HashMap<>(); + map.put(0, capabilities.isOFPCFLOWSTATS()); + map.put(1, capabilities.isOFPCTABLESTATS()); + map.put(2, capabilities.isOFPCPORTSTATS()); + map.put(3, capabilities.isOFPCSTP()); + map.put(4, capabilities.isOFPCRESERVED()); + map.put(5, capabilities.isOFPCIPREASM()); + map.put(6, capabilities.isOFPCQUEUESTATS()); + map.put(7, capabilities.isOFPCARPMATCHIP()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + return bitmap; + } + + private static int createActionsV10(final ActionTypeV10 action) { + return ByteBufUtils.fillBitMask(0, action.isOFPATOUTPUT(), action.isOFPATSETVLANVID(), + action.isOFPATSETVLANPCP(), action.isOFPATSTRIPVLAN(), action.isOFPATSETDLSRC(), + action.isOFPATSETDLDST(), action.isOFPATSETNWSRC(), action.isOFPATSETNWDST(), action.isOFPATSETNWTOS(), + action.isOFPATSETTPSRC(), action.isOFPATSETTPDST(), action.isOFPATENQUEUE(), action.isOFPATVENDOR()); + + } + + private void writeName(final String name, final ByteBuf outBuffer) { + byte[] nameBytes = name.getBytes(); + if (nameBytes.length < 16) { + byte[] nameBytesPadding = new byte[16]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 16; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java new file mode 100644 index 00000000..71b5a28b --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FlowRemovedMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 11; + private SerializerRegistry registry; + private static final byte PADDING = 1; + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + registry = serializerRegistry; + } + + @Override + public void serialize(FlowRemovedMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + + OFSerializer matchSerializer = registry + .getSerializer(new MessageTypeKey<>(message.getVersion(), MatchV10.class)); + + matchSerializer.serialize(message.getMatchV10(), outBuffer); + + outBuffer.writeLong(message.getCookie().longValue()); + outBuffer.writeShort(message.getPriority()); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeZero(PADDING); + outBuffer.writeInt(message.getDurationSec().intValue()); + outBuffer.writeInt(message.getDurationNsec().intValue()); + outBuffer.writeShort(message.getIdleTimeout()); + outBuffer.writeZero(PADDING); + outBuffer.writeZero(PADDING); + outBuffer.writeLong(message.getPacketCount().longValue()); + outBuffer.writeLong(message.getByteCount().longValue()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java new file mode 100644 index 00000000..d2a1812f --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.PacketInMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PacketInMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 10; + private static final byte PADDING = 1; + + @Override + public void serialize(PacketInMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeShort(message.getTotalLen().intValue()); + outBuffer.writeShort(message.getInPort()); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeZero(PADDING); + byte[] data = message.getData(); + + if (data != null) { + outBuffer.writeBytes(data); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java index 4002b8fc..e4822a26 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java @@ -9,10 +9,10 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; @@ -30,7 +30,7 @@ public class OF10PortModInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 12; + private static final byte PADDING = 7; + + @Override + public void serialize(final PortStatusMessage message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeZero(PADDING); + outBuffer.writeShort(message.getPortNo().intValue()); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(message.getHwAddr())); + writeName(message.getName(), outBuffer); + writePortConfig(message.getConfigV10(), outBuffer); + writePortState(message.getStateV10(), outBuffer); + writePortFeature(message.getCurrentFeaturesV10(), outBuffer); + writePortFeature(message.getAdvertisedFeaturesV10(), outBuffer); + writePortFeature(message.getSupportedFeaturesV10(), outBuffer); + writePortFeature(message.getPeerFeaturesV10(), outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void writePortFeature(final PortFeaturesV10 feature, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, feature.is_10mbHd()); + map.put(1, feature.is_10mbFd()); + map.put(2, feature.is_100mbHd()); + map.put(3, feature.is_100mbFd()); + map.put(4, feature.is_1gbHd()); + map.put(5, feature.is_1gbFd()); + map.put(6, feature.is_10gbFd()); + map.put(7, feature.isCopper()); + map.put(8, feature.isFiber()); + map.put(9, feature.isAutoneg()); + map.put(10, feature.isPause()); + map.put(11, feature.isPauseAsym()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortState(final PortStateV10 state, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, state.isLinkDown()); + map.put(1, state.isBlocked()); + map.put(2, state.isLive()); + map.put(3, state.isStpListen()); + map.put(4, state.isStpLearn()); + map.put(5, state.isStpForward()); + map.put(6, state.isStpBlock()); + map.put(7, state.isStpMask()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortConfig(final PortConfigV10 config, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, config.isPortDown()); + map.put(1, config.isNoStp()); + map.put(2, config.isNoRecv()); + map.put(3, config.isNoRecvStp()); + map.put(4, config.isNoFlood()); + map.put(5, config.isNoFwd()); + map.put(6, config.isNoPacketIn()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writeName(final String name, final ByteBuf outBuffer) { + byte[] nameBytes = name.getBytes(); + if (nameBytes.length < 16) { + byte[] nameBytesPadding = new byte[16]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 16; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java new file mode 100644 index 00000000..85044479 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10QueueGetConfigReplyMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 21; + private static final byte PADDING = 6; + private static final int QUEUE_LENGTH_INDEX = 4; + private static final byte QUEUE_PADDING = 2; + private static final byte QUEUE_PROPERTY_PADDING = 6; + private static final int QUEUE_PROPERTY_LENGTH_INDEX = 2; + + @Override + public void serialize(GetQueueConfigOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getPort().getValue().intValue()); + outBuffer.writeZero(PADDING); + for (Queues queue : message.getQueues()) { + ByteBuf queueBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + queueBuff.writeInt(queue.getQueueId().getValue().intValue()); + queueBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + queueBuff.writeZero(QUEUE_PADDING); + for (QueueProperty queueProperty : queue.getQueueProperty()) { + ByteBuf queuePropertyBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + queuePropertyBuff.writeShort(queueProperty.getProperty().getIntValue()); + queuePropertyBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + queuePropertyBuff.writeZero(4); + if (queueProperty.getProperty() == QueueProperties.OFPQTMINRATE) { + RateQueueProperty body = queueProperty.getAugmentation(RateQueueProperty.class); + queuePropertyBuff.writeShort(body.getRate().intValue()); + queuePropertyBuff.writeZero(QUEUE_PROPERTY_PADDING); + } + queuePropertyBuff.setShort(QUEUE_PROPERTY_LENGTH_INDEX, queuePropertyBuff.readableBytes()); + queueBuff.writeBytes(queuePropertyBuff); + } + queueBuff.setShort(QUEUE_LENGTH_INDEX, queueBuff.readableBytes()); + outBuffer.writeBytes(queueBuff); + } + + ByteBufUtils.updateOFHeaderLength(outBuffer); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java new file mode 100644 index 00000000..268f7f06 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.util.HashMap; +import java.util.Map; +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.util.ListSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMaker; +import org.opendaylight.openflowjava.protocol.impl.util.TypeKeyMakerFactory; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.experimenter._case.MultipartReplyExperimenter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsReplyMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private SerializerRegistry registry; + private static final byte MESSAGE_TYPE = 17; + private static final byte FLOW_STATS_PADDING_1 = 1; + private static final byte FLOW_STATS_PADDING_2 = 6; + private static final TypeKeyMaker ACTION_KEY_MAKER = TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF10_VERSION_ID); + private static final int FLOW_STATS_LENGTH_INDEX = 0; + private static final int QUEUE_STATS_LENGTH_INDEX = 0; + private static final byte AGGREGATE_PADDING = 4; + private static final byte TABLE_PADDING = 3; + private static final byte QUEUE_PADDING = 2; + private static final byte PORT_STATS_PADDING = 6; + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + registry = serializerRegistry; + } + + @Override + public void serialize(MultipartReplyMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getType().getIntValue()); + writeFlags(message.getFlags(), outBuffer); + switch (message.getType()) { + case OFPMPDESC: + serializeDescBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPFLOW: + serializeFlowBody(message.getMultipartReplyBody(), outBuffer, message); + break; + case OFPMPAGGREGATE: + serializeAggregateBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPTABLE: + serializeTableBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPPORTSTATS: + serializePortStatsBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPQUEUE: + serializeQueueBody(message.getMultipartReplyBody(), outBuffer); + break; + case OFPMPEXPERIMENTER: + serializeExperimenterBody(message.getMultipartReplyBody(), outBuffer); + break; + default: + break; + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void serializeExperimenterBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyExperimenterCase experimenterCase = (MultipartReplyExperimenterCase) body; + MultipartReplyExperimenter experimenterBody = experimenterCase.getMultipartReplyExperimenter(); + // TODO: experimenterBody does not have get methods + } + + private void serializeQueueBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyQueueCase queueCase = (MultipartReplyQueueCase) body; + MultipartReplyQueue queue = queueCase.getMultipartReplyQueue(); + for (QueueStats queueStats : queue.getQueueStats()) { + ByteBuf queueStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + queueStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + queueStatsBuff.writeZero(QUEUE_PADDING); + queueStatsBuff.writeInt(queueStats.getQueueId().intValue()); + queueStatsBuff.writeLong(queueStats.getTxBytes().longValue()); + queueStatsBuff.writeLong(queueStats.getTxPackets().longValue()); + queueStatsBuff.writeLong(queueStats.getTxErrors().longValue()); + queueStatsBuff.setShort(QUEUE_STATS_LENGTH_INDEX, queueStatsBuff.readableBytes()); + outBuffer.writeBytes(queueStatsBuff); + } + } + + private void serializePortStatsBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyPortStatsCase portStatsCase = (MultipartReplyPortStatsCase) body; + MultipartReplyPortStats portStats = portStatsCase.getMultipartReplyPortStats(); + for (PortStats portStat : portStats.getPortStats()) { + outBuffer.writeInt(portStat.getPortNo().intValue()); + outBuffer.writeZero(PORT_STATS_PADDING); + outBuffer.writeLong(portStat.getRxPackets().longValue()); + outBuffer.writeLong(portStat.getTxPackets().longValue()); + outBuffer.writeLong(portStat.getRxBytes().longValue()); + outBuffer.writeLong(portStat.getTxBytes().longValue()); + outBuffer.writeLong(portStat.getRxDropped().longValue()); + outBuffer.writeLong(portStat.getTxDropped().longValue()); + outBuffer.writeLong(portStat.getRxErrors().longValue()); + outBuffer.writeLong(portStat.getTxErrors().longValue()); + outBuffer.writeLong(portStat.getRxFrameErr().longValue()); + outBuffer.writeLong(portStat.getRxOverErr().longValue()); + outBuffer.writeLong(portStat.getRxCrcErr().longValue()); + outBuffer.writeLong(portStat.getCollisions().longValue()); + } + } + + private void serializeTableBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyTableCase tableCase = (MultipartReplyTableCase) body; + MultipartReplyTable table = tableCase.getMultipartReplyTable(); + for (TableStats tableStats : table.getTableStats()) { + outBuffer.writeByte(tableStats.getTableId()); + outBuffer.writeZero(TABLE_PADDING); + write16String(tableStats.getName(), outBuffer); + writeFlowWildcardsV10(tableStats.getWildcards(), outBuffer); + outBuffer.writeInt(tableStats.getMaxEntries().intValue()); + outBuffer.writeInt(tableStats.getActiveCount().intValue()); + outBuffer.writeLong(tableStats.getLookupCount().longValue()); + outBuffer.writeLong(tableStats.getMatchedCount().longValue()); + } + } + + private void writeFlowWildcardsV10(FlowWildcardsV10 feature, ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, feature.isINPORT()); + map.put(1, feature.isDLVLAN()); + map.put(2, feature.isDLSRC()); + map.put(3, feature.isDLDST()); + map.put(4, feature.isDLTYPE()); + map.put(5, feature.isNWPROTO()); + map.put(6, feature.isTPSRC()); + map.put(7, feature.isTPDST()); + map.put(20, feature.isDLVLANPCP()); + map.put(21, feature.isNWTOS()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void serializeAggregateBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyAggregateCase aggregateCase = (MultipartReplyAggregateCase) body; + MultipartReplyAggregate aggregate = aggregateCase.getMultipartReplyAggregate(); + outBuffer.writeLong(aggregate.getPacketCount().longValue()); + outBuffer.writeLong(aggregate.getByteCount().longValue()); + outBuffer.writeInt(aggregate.getFlowCount().intValue()); + outBuffer.writeZero(AGGREGATE_PADDING); + } + + private void serializeFlowBody(MultipartReplyBody body, ByteBuf outBuffer, MultipartReplyMessage message) { + MultipartReplyFlowCase flowCase = (MultipartReplyFlowCase) body; + MultipartReplyFlow flow = flowCase.getMultipartReplyFlow(); + for (FlowStats flowStats : flow.getFlowStats()) { + ByteBuf flowStatsBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + flowStatsBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + flowStatsBuff.writeByte(new Long(flowStats.getTableId()).byteValue()); + flowStatsBuff.writeZero(FLOW_STATS_PADDING_1); + OFSerializer matchSerializer = registry + .getSerializer(new MessageTypeKey<>(message.getVersion(), MatchV10.class)); + matchSerializer.serialize(flowStats.getMatchV10(), flowStatsBuff); + flowStatsBuff.writeInt(flowStats.getDurationSec().intValue()); + flowStatsBuff.writeInt(flowStats.getDurationNsec().intValue()); + flowStatsBuff.writeShort(flowStats.getPriority()); + flowStatsBuff.writeShort(flowStats.getIdleTimeout()); + flowStatsBuff.writeShort(flowStats.getHardTimeout()); + flowStatsBuff.writeZero(FLOW_STATS_PADDING_2); + flowStatsBuff.writeLong(flowStats.getCookie().longValue()); + flowStatsBuff.writeLong(flowStats.getPacketCount().longValue()); + flowStatsBuff.writeLong(flowStats.getByteCount().longValue()); + ListSerializer.serializeList(flowStats.getAction(), ACTION_KEY_MAKER, registry, flowStatsBuff); + flowStatsBuff.setShort(FLOW_STATS_LENGTH_INDEX, flowStatsBuff.readableBytes()); + outBuffer.writeBytes(flowStatsBuff); + } + } + + private void writeFlags(MultipartRequestFlags flags, ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, flags.isOFPMPFREQMORE()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeShort(bitmap); + } + + private void serializeDescBody(MultipartReplyBody body, ByteBuf outBuffer) { + MultipartReplyDescCase descCase = (MultipartReplyDescCase) body; + MultipartReplyDesc desc = descCase.getMultipartReplyDesc(); + write256String(desc.getMfrDesc(), outBuffer); + write256String(desc.getHwDesc(), outBuffer); + write256String(desc.getSwDesc(), outBuffer); + write32String(desc.getSerialNum(), outBuffer); + write256String(desc.getDpDesc(), outBuffer); + } + + private void write256String(String toWrite, ByteBuf outBuffer) { + byte[] nameBytes = toWrite.getBytes(); + if (nameBytes.length < 256) { + byte[] nameBytesPadding = new byte[256]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 256; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } + + private void write16String(String toWrite, ByteBuf outBuffer) { + byte[] nameBytes = toWrite.getBytes(); + if (nameBytes.length < 16) { + byte[] nameBytesPadding = new byte[16]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 16; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } + + private void write32String(String toWrite, ByteBuf outBuffer) { + byte[] nameBytes = toWrite.getBytes(); + if (nameBytes.length < 32) { + byte[] nameBytesPadding = new byte[32]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 32; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java new file mode 100644 index 00000000..713e8eda --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; + +/** + * Translates PacketIn messages + */ +public class PacketInMessageFactory implements OFSerializer, SerializerRegistryInjector { + private static final byte PADDING = 2; + private static final byte MESSAGE_TYPE = 10; + private SerializerRegistry registry; + + @Override + public void serialize(PacketInMessage message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeShort(message.getTotalLen().intValue()); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeByte(message.getTableId().getValue().byteValue()); + outBuffer.writeLong(message.getCookie().longValue()); + OFSerializer matchSerializer = registry + .> getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class)); + matchSerializer.serialize(message.getMatch(), outBuffer); + outBuffer.writeZero(PADDING); + + byte[] data = message.getData(); + + if (data != null) { + outBuffer.writeBytes(data); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} \ No newline at end of file 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 65364aeb..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 @@ -9,40 +9,41 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; import io.netty.buffer.ByteBuf; - import java.util.HashMap; import java.util.Map; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; -import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; 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.protocol.rev130731.PortModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortMod; /** - * Translates PortMod messages + * Translates PortMod messages. + * OF protocol versions: 1.3. * @author timotej.kubas * @author michal.polkorab */ -public class PortModInputMessageFactory implements OFSerializer { +public class PortModInputMessageFactory implements OFSerializer { private static final byte MESSAGE_TYPE = 16; private static final byte PADDING_IN_PORT_MOD_MESSAGE_01 = 4; private static final byte PADDING_IN_PORT_MOD_MESSAGE_02 = 2; private static final byte PADDING_IN_PORT_MOD_MESSAGE_03 = 4; @Override - public void serialize(final PortModInput message, final ByteBuf outBuffer) { + 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); - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(message.getHwAddress().getValue())); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(message.getHwAddress())); outBuffer.writeZero(PADDING_IN_PORT_MOD_MESSAGE_02); outBuffer.writeInt(createPortConfigBitmask(message.getConfig())); 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/serialization/factories/PortStatusMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactory.java new file mode 100644 index 00000000..1a4e6fc8 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactory.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.HashMap; +import java.util.Map; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +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.PortState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PortStatusMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 12; + private static final byte PADDING = 7; + private static final byte PORT_PADDING_1 = 4; + private static final byte PORT_PADDING_2 = 2; + + @Override + public void serialize(final PortStatusMessage message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeByte(message.getReason().getIntValue()); + outBuffer.writeZero(PADDING); + outBuffer.writeInt(message.getPortNo().intValue()); + outBuffer.writeZero(PORT_PADDING_1); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(message.getHwAddr())); + outBuffer.writeZero(PORT_PADDING_2); + writeName(message.getName(), outBuffer); + writePortConfig(message.getConfig(), outBuffer); + writePortState(message.getState(), outBuffer); + writePortFeatures(message.getCurrentFeatures(), outBuffer); + writePortFeatures(message.getAdvertisedFeatures(), outBuffer); + writePortFeatures(message.getSupportedFeatures(), outBuffer); + writePortFeatures(message.getPeerFeatures(), outBuffer); + outBuffer.writeInt(message.getCurrSpeed().intValue()); + outBuffer.writeInt(message.getMaxSpeed().intValue()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void writePortConfig(final PortConfig config, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, config.isPortDown()); + map.put(2, config.isNoRecv()); + map.put(5, config.isNoFwd()); + map.put(6, config.isNoPacketIn()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writeName(final String name, final ByteBuf outBuffer) { + byte[] nameBytes = name.getBytes(); + if (nameBytes.length < 16) { + byte[] nameBytesPadding = new byte[16]; + int i = 0; + for (byte b : nameBytes) { + nameBytesPadding[i] = b; + i++; + } + for (; i < 16; i++) { + nameBytesPadding[i] = 0x0; + } + outBuffer.writeBytes(nameBytesPadding); + } else { + outBuffer.writeBytes(nameBytes); + } + + } + + private void writePortState(final PortState state, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, state.isLinkDown()); + map.put(1, state.isBlocked()); + map.put(2, state.isLive()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } + + private void writePortFeatures(final PortFeatures features, final ByteBuf outBuffer) { + Map map = new HashMap<>(); + map.put(0, features.is_10mbHd()); + map.put(1, features.is_10mbFd()); + map.put(2, features.is_100mbHd()); + map.put(3, features.is_100mbFd()); + map.put(4, features.is_1gbHd()); + map.put(5, features.is_1gbFd()); + map.put(6, features.is_10gbFd()); + map.put(7, features.is_40gbFd()); + map.put(8, features.is_100gbFd()); + map.put(9, features.is_1tbFd()); + map.put(10, features.isOther()); + map.put(11, features.isCopper()); + map.put(12, features.isFiber()); + map.put(13, features.isAutoneg()); + map.put(14, features.isPause()); + map.put(15, features.isPauseAsym()); + int bitmap = ByteBufUtils.fillBitMaskFromMap(map); + outBuffer.writeInt(bitmap); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java new file mode 100644 index 00000000..3a15aacc --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdQueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class QueueGetConfigReplyMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 23; + private static final byte PADDING = 4; + public static final int QUEUE_LENGTH_INDEX = 8; + public static final int PROPERTY_LENGTH_INDEX = 2; + private static final byte QUEUE_PADDING = 6; + private static final byte PROPERTY_HEADER_PADDING = 4; + private static final byte PROPERTY_RATE_PADDING = 6; + private static final byte PROPERTY_EXPERIMENTER_PADDING = 4; + + @Override + public void serialize(GetQueueConfigOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getPort().getValue().intValue()); + outBuffer.writeZero(PADDING); + for (Queues queue : message.getQueues()) { + ByteBuf queueBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + queueBuff.writeInt(queue.getQueueId().getValue().intValue()); + queueBuff.writeInt(queue.getPort().getValue().intValue()); + queueBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + queueBuff.writeZero(QUEUE_PADDING); + + for (QueueProperty property : queue.getQueueProperty()) { + ByteBuf propertyBuff = UnpooledByteBufAllocator.DEFAULT.buffer(); + propertyBuff.writeShort(property.getProperty().getIntValue()); + propertyBuff.writeShort(EncodeConstants.EMPTY_LENGTH); + propertyBuff.writeZero(PROPERTY_HEADER_PADDING); + switch (property.getProperty()) { + case OFPQTMINRATE: + serializeRateBody(property.getAugmentation(RateQueueProperty.class), propertyBuff); + break; + case OFPQTMAXRATE: + serializeRateBody(property.getAugmentation(RateQueueProperty.class), propertyBuff); + break; + case OFPQTEXPERIMENTER: + serializeExperimenterBody(property.getAugmentation(ExperimenterIdQueueProperty.class), + propertyBuff); + break; + default: + break; + } + propertyBuff.setShort(PROPERTY_LENGTH_INDEX, propertyBuff.readableBytes()); + queueBuff.writeBytes(propertyBuff); + } + + queueBuff.setShort(QUEUE_LENGTH_INDEX, queueBuff.readableBytes()); + outBuffer.writeBytes(queueBuff); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void serializeRateBody(RateQueueProperty body, ByteBuf outBuffer) { + outBuffer.writeShort(body.getRate()); + outBuffer.writeZero(PROPERTY_RATE_PADDING); + } + + private void serializeExperimenterBody(ExperimenterIdQueueProperty body, ByteBuf outBuffer) { + // TODO: Experimenter Data is vendor specific that should implement its + // own serializer + outBuffer.writeInt(body.getExperimenter().getValue().intValue()); + outBuffer.writeZero(PROPERTY_EXPERIMENTER_PADDING); + } +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java new file mode 100644 index 00000000..0225665c --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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.RoleRequestOutput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class RoleReplyMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 25; + private static final byte PADDING = 4; + + @Override + public void serialize(RoleRequestOutput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getRole().getIntValue()); + outBuffer.writeZero(PADDING); + outBuffer.writeLong(message.getGenerationId().longValue()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java index ea9d0a5c..77e7651c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java @@ -8,8 +8,9 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; /** * Parent for Ipv4 address based match entry serializers @@ -17,11 +18,18 @@ */ public abstract class AbstractOxmIpv4AddressSerializer extends AbstractOxmMatchEntrySerializer { - protected static void writeIpv4Address(String address, final ByteBuf out) { + /** + * @deprecated Use {@link #writeIpv4Address(Ipv4Address, ByteBuf)} instead. + */ + @Deprecated + protected static void writeIpv4Address(final String address, final ByteBuf out) { Iterable addressGroups = ByteBufUtils.DOT_SPLITTER.split(address); for (String group : addressGroups) { out.writeByte(Short.parseShort(group)); } } + protected static void writeIpv4Address(final Ipv4Address address, final ByteBuf out) { + out.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(address)); + } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java index a665eb79..9dde0f0c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java @@ -8,9 +8,8 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - -import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; /** * Parent for MAC address based match entry serializers @@ -18,7 +17,7 @@ */ public abstract class AbstractOxmMacAddressSerializer extends AbstractOxmMatchEntrySerializer { - protected void writeMacAddress(MacAddress address, ByteBuf outBuffer) { - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(address.getValue())); // 48 b + mask [OF 1.3.2 spec] + protected void writeMacAddress(final MacAddress address, final ByteBuf outBuffer) { + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(address)); // 48 b + mask [OF 1.3.2 spec] } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java index 6bdff69a..99ed4c9c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java @@ -8,7 +8,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; @@ -21,10 +20,10 @@ public class OxmArpSpaSerializer extends AbstractOxmIpv4AddressSerializer { @Override - public void serialize(MatchEntry entry, ByteBuf outBuffer) { + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { super.serialize(entry, outBuffer); ArpSpaCase entryValue = (ArpSpaCase) entry.getMatchEntryValue(); - writeIpv4Address(entryValue.getArpSpa().getIpv4Address().getValue(), outBuffer); + writeIpv4Address(entryValue.getArpSpa().getIpv4Address(), outBuffer); if (entry.isHasMask()) { writeMask(entryValue.getArpSpa().getMask(), outBuffer, EncodeConstants.GROUPS_IN_IPV4_ADDRESS); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java index 32ce8ffc..29e24cab 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java @@ -8,7 +8,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; @@ -21,10 +20,10 @@ public class OxmArpTpaSerializer extends AbstractOxmIpv4AddressSerializer { @Override - public void serialize(MatchEntry entry, ByteBuf outBuffer) { + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { super.serialize(entry, outBuffer); ArpTpaCase entryValue = (ArpTpaCase) entry.getMatchEntryValue(); - writeIpv4Address(entryValue.getArpTpa().getIpv4Address().getValue(), outBuffer); + writeIpv4Address(entryValue.getArpTpa().getIpv4Address(), outBuffer); if (entry.isHasMask()) { writeMask(entryValue.getArpTpa().getMask(), outBuffer, EncodeConstants.GROUPS_IN_IPV4_ADDRESS); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java index 4a3ba4cb..9e1c00b0 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java @@ -8,7 +8,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; @@ -21,10 +20,10 @@ public class OxmIpv4DstSerializer extends AbstractOxmIpv4AddressSerializer { @Override - public void serialize(MatchEntry entry, ByteBuf outBuffer) { + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { super.serialize(entry, outBuffer); Ipv4DstCase entryValue = (Ipv4DstCase) entry.getMatchEntryValue(); - writeIpv4Address(entryValue.getIpv4Dst().getIpv4Address().getValue(), outBuffer); + writeIpv4Address(entryValue.getIpv4Dst().getIpv4Address(), outBuffer); if (entry.isHasMask()) { writeMask(entryValue.getIpv4Dst().getMask(), outBuffer, EncodeConstants.GROUPS_IN_IPV4_ADDRESS); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java index 08bca868..42667ee0 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java @@ -8,7 +8,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.match; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; @@ -21,10 +20,10 @@ public class OxmIpv4SrcSerializer extends AbstractOxmIpv4AddressSerializer { @Override - public void serialize(MatchEntry entry, ByteBuf outBuffer) { + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { super.serialize(entry, outBuffer); Ipv4SrcCase entryValue = (Ipv4SrcCase) entry.getMatchEntryValue(); - writeIpv4Address(entryValue.getIpv4Src().getIpv4Address().getValue(), outBuffer); + writeIpv4Address(entryValue.getIpv4Src().getIpv4Address(), outBuffer); if (entry.isHasMask()) { writeMask(entryValue.getIpv4Src().getMask(), outBuffer, EncodeConstants.GROUPS_IN_IPV4_ADDRESS); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java new file mode 100644 index 00000000..fec3df21 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.serialization.match.ext; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.AbstractOxmMatchEntrySerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * Created by Anil Vishnoi (avishnoi@Brocade.com) on 7/25/16. + */ +public abstract class AbstractOxmExperimenterMatchEntrySerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + serializeHeader(entry, outBuffer); + } + + @Override + public void serializeHeader(MatchEntry entry, ByteBuf outBuffer) { + outBuffer.writeShort(getOxmClassCode()); + writeOxmFieldAndLength(outBuffer, getOxmFieldCode(), entry.isHasMask(), + getValueLength()); + } + + protected static void writeOxmFieldAndLength(ByteBuf out, int fieldValue, boolean hasMask, int lengthArg) { + int fieldAndMask = fieldValue << 1; + int length = lengthArg; + if (hasMask) { + fieldAndMask |= 1; + length *= 2; + } + + //Add experimenter-id lenge + length = length + EncodeConstants.SIZE_OF_INT_IN_BYTES; + out.writeByte(fieldAndMask); + out.writeByte(length); + } + + protected ExperimenterIdCase serializeExperimenterId(MatchEntry matchEntry, ByteBuf out) { + ExperimenterIdCase expCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue(); + out.writeInt(expCase.getExperimenter().getExperimenter().getValue().intValue()); + return expCase; + } + + /** + * @return Experimenter match entry ID + */ + protected abstract long getExperimenterId(); +} + diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java new file mode 100644 index 00000000..f244cc42 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.serialization.match.ext; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.TcpFlagsContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.oxm.container.match.entry.value.experimenter.id._case.TcpFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * Created by Anil Vishnoi (avishnoi@Brocade.com) on 7/25/16. + */ +public class OnfOxmTcpFlagsSerializer extends AbstractOxmExperimenterMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ExperimenterIdCase expCase = serializeExperimenterId(entry, outBuffer); + TcpFlags tcpFlags = expCase.getAugmentation(TcpFlagsContainer.class).getTcpFlags(); + outBuffer.writeShort(tcpFlags.getFlags()); + if (entry.isHasMask()) { + outBuffer.writeBytes(tcpFlags.getMask()); + } + } + + /** + * @return Experimenter match entry ID + */ + @Override + protected long getExperimenterId() { + return EncodeConstants.ONF_EXPERIMENTER_ID; + } + + /** + * @return numeric representation of oxm_field + */ + @Override + protected int getOxmFieldCode() { + return EncodeConstants.ONFOXM_ET_TCP_FLAGS; + } + + /** + * @return numeric representation of oxm_class + */ + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.EXPERIMENTER_CLASS; + } + + /** + * @return match entry value length (without mask length) + */ + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} 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 b19b47e4..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 @@ -10,10 +10,11 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; +import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; /** + * Helper class for serializer registration. * @author michal.polkorab - * */ public class CommonMessageRegistryHelper { @@ -21,8 +22,8 @@ public class CommonMessageRegistryHelper { private SerializerRegistry serializerRegistry; /** - * @param version - * @param serializerRegistry + * @param version wire protocol version + * @param serializerRegistry registry to be filled with message serializers */ public CommonMessageRegistryHelper(short version, SerializerRegistry serializerRegistry) { this.version = version; @@ -30,10 +31,12 @@ public CommonMessageRegistryHelper(short version, SerializerRegistry serializerR } /** - * @param msgType - * @param serializer + * Registers serializer in registry. + * @param msgType class of object that will be serialized by given serializer + * @param serializer serializer instance */ public void registerSerializer(Class msgType, OFGeneralSerializer serializer) { serializerRegistry.registerSerializer(new MessageTypeKey<>(version, msgType), serializer); } + } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java index a53749c2..44534720 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java @@ -72,13 +72,28 @@ public static List deserializeHeaders(short version, i if (input.readableBytes() > 0) { items = new ArrayList<>(); int startIndex = input.readerIndex(); + boolean exceptionLogged = false; while ((input.readerIndex() - startIndex) < length){ HeaderDeserializer deserializer; MessageCodeKey key = keyMaker.make(input); try { deserializer = registry.getDeserializer(key); - } catch (IllegalStateException e) { - LOG.warn("Problem during reading table feature property. Skipping unknown feature property: {}", key); + } catch (ClassCastException | IllegalStateException e) { + // Following "if" is only hotfix to prevent log flooding. Log flooding is originally + // caused by using OVS 2.4 which directly uses / reports Nicira extensions. These extensions + // are not yet (2nd February 2016) fully supported by existing OF Plugin. + // TODO - simplify to correctly report exception during deserialization + if (!exceptionLogged) { + LOG.warn("Problem during reading table feature property. Skipping unknown feature property: {}." + + "If more information is needed, set org.opendaylight.openflowjava do DEBUG log level.", + key, e.getMessage()); + if (LOG.isDebugEnabled()) { + LOG.debug("Detailed exception: {}", e); + LOG.debug("This exception is logged only once for each multipart reply (table features) to " + + "prevent log flooding. There might be more of table features related exceptions."); + } + exceptionLogged = true; + } input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); continue; } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java index e666f11e..96d01c3d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java @@ -10,6 +10,7 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; /** * @author michal.polkorab @@ -44,4 +45,11 @@ public void register(int oxmField, OFGeneralDeserializer deserializer) { key.setExperimenterId(null); registry.registerDeserializer(key, deserializer); } + + public void registerExperimenter(int oxmField, long expId, OFGeneralDeserializer deserializer) { + MatchEntryDeserializerKey key = + new MatchEntryDeserializerKey(version, OxmMatchConstants.EXPERIMENTER_CLASS, oxmField); + key.setExperimenterId(expId); + registry.registerDeserializer(key, deserializer); + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java index 1c704bb2..d9c76295 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java @@ -10,6 +10,7 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; @@ -46,4 +47,17 @@ public void registerSerializer( key.setExperimenterId(null); serializerRegistry.registerSerializer(key, serializer); } + + /** + * Registers ExperimenterClass type match serializer + * @param specificClass + * @param serializer + */ + public void registerExperimenterSerializer( + Class specificClass, long expId, OFGeneralSerializer serializer) { + MatchEntrySerializerKey key = new MatchEntrySerializerKey<>(version, ExperimenterClass.class, specificClass); + key.setExperimenterId(expId); + serializerRegistry.registerSerializer(key, serializer); + } + } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java index b0a4f41c..7ff074ae 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java @@ -9,12 +9,8 @@ package org.opendaylight.openflowjava.protocol.impl.util; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; @@ -42,12 +38,8 @@ public MatchV10 deserialize(final ByteBuf input) { builder.setNwSrcMask(decodeNwSrcMask(wildcards)); builder.setNwDstMask(decodeNwDstMask(wildcards)); builder.setInPort(input.readUnsignedShort()); - byte[] dlSrc = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; - input.readBytes(dlSrc); - builder.setDlSrc(new MacAddress(ByteBufUtils.macAddressToString(dlSrc))); - byte[] dlDst = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; - input.readBytes(dlDst); - builder.setDlDst(new MacAddress(ByteBufUtils.macAddressToString(dlDst))); + builder.setDlSrc(ByteBufUtils.readIetfMacAddress(input)); + builder.setDlDst(ByteBufUtils.readIetfMacAddress(input)); builder.setDlVlan(input.readUnsignedShort()); builder.setDlVlanPcp(input.readUnsignedByte()); @@ -56,8 +48,8 @@ public MatchV10 deserialize(final ByteBuf input) { builder.setNwTos(input.readUnsignedByte()); builder.setNwProto(input.readUnsignedByte()); input.skipBytes(PADDING_IN_MATCH_2); - builder.setNwSrc(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); - builder.setNwDst(new Ipv4Address(ByteBufUtils.readIpv4Address(input))); + builder.setNwSrc(ByteBufUtils.readIetfIpv4Address(input)); + builder.setNwDst(ByteBufUtils.readIetfIpv4Address(input)); builder.setTpSrc(input.readUnsignedShort()); builder.setTpDst(input.readUnsignedShort()); return builder.build(); diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java index 830753ea..a9db0af9 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java @@ -9,9 +9,10 @@ package org.opendaylight.openflowjava.protocol.impl.util; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; @@ -35,8 +36,8 @@ public class OF10MatchSerializer implements OFSerializer { public void serialize(final MatchV10 match, final ByteBuf outBuffer) { outBuffer.writeInt(encodeWildcards(match.getWildcards(), match.getNwSrcMask(), match.getNwDstMask())); outBuffer.writeShort(match.getInPort()); - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(match.getDlSrc().getValue())); - outBuffer.writeBytes(ByteBufUtils.macAddressToBytes(match.getDlDst().getValue())); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(match.getDlSrc())); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(match.getDlDst())); outBuffer.writeShort(match.getDlVlan()); outBuffer.writeByte(match.getDlVlanPcp()); outBuffer.writeZero(PADDING_IN_MATCH); @@ -44,14 +45,8 @@ public void serialize(final MatchV10 match, final ByteBuf outBuffer) { outBuffer.writeByte(match.getNwTos()); outBuffer.writeByte(match.getNwProto()); outBuffer.writeZero(PADDING_IN_MATCH_2); - Iterable srcGroups = ByteBufUtils.DOT_SPLITTER.split(match.getNwSrc().getValue()); - for (String group : srcGroups) { - outBuffer.writeByte(Short.parseShort(group)); - } - Iterable dstGroups = ByteBufUtils.DOT_SPLITTER.split(match.getNwDst().getValue()); - for (String group : dstGroups) { - outBuffer.writeByte(Short.parseShort(group)); - } + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(match.getNwSrc())); + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(match.getNwDst())); outBuffer.writeShort(match.getTpSrc()); outBuffer.writeShort(match.getTpDst()); } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java index 32ecb5de..7022c98d 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java @@ -32,7 +32,7 @@ * @author timotej.kubas */ public class OF13MatchSerializer implements OFSerializer, SerializerRegistryInjector { - private static final Logger LOGGER = LoggerFactory.getLogger(OF13MatchSerializer.class); + private static final Logger LOG = LoggerFactory.getLogger(OF13MatchSerializer.class); private static final byte STANDARD_MATCH_TYPE_CODE = 0; private static final byte OXM_MATCH_TYPE_CODE = 1; private SerializerRegistry registry; @@ -40,7 +40,7 @@ public class OF13MatchSerializer implements OFSerializer, SerializerRegis @Override public void serialize(Match match, ByteBuf outBuffer) { if (match == null) { - LOGGER.debug("Match is null"); + LOG.debug("Match is null"); return; } int matchStartIndex = outBuffer.writerIndex(); @@ -72,7 +72,7 @@ private static void serializeType(Match match, ByteBuf out) { */ public void serializeMatchEntries(List matchEntries, ByteBuf out) { if (matchEntries == null) { - LOGGER.debug("Match entries are null"); + LOG.debug("Match entries are null"); return; } for (MatchEntry entry : matchEntries) { 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 38d05d2c..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 @@ -12,8 +12,8 @@ import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; /** + * Helper class for deserializer registration. * @author michal.polkorab - * */ public class SimpleDeserializerRegistryHelper { @@ -24,21 +24,24 @@ public class SimpleDeserializerRegistryHelper { * @param version wire protocol version * @param deserializerRegistry registry to be filled with message deserializers */ - public SimpleDeserializerRegistryHelper(short version, DeserializerRegistry deserializerRegistry) { + public SimpleDeserializerRegistryHelper(final short version, final DeserializerRegistry deserializerRegistry) { this.version = version; this.registry = deserializerRegistry; } /** + * Register deserializer in registry. If deserializer supports more protocol versions assign actual one. * @param code code / value to distinguish between deserializers - * @param experimenterID TODO - * @param deserializedObjectClass class of object that will be deserialized - * by given deserializer + * @param deserializedObjectClass class of object that will be deserialized by given deserializer * @param deserializer deserializer instance */ - public void registerDeserializer(int code, - Long experimenterID, Class deserializedObjectClass, OFGeneralDeserializer deserializer) { - registry.registerDeserializer(new MessageCodeKey(version, code, - deserializedObjectClass), deserializer); + public void registerDeserializer(final int code, final Class deserializedObjectClass, + final OFGeneralDeserializer deserializer) { + registry.registerDeserializer(new MessageCodeKey(version, code, deserializedObjectClass), deserializer); + + if (deserializer instanceof VersionAssignableFactory) { + ((VersionAssignableFactory) deserializer).assignVersion(version); + } } + } 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/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java new file mode 100644 index 00000000..d10f8fa6 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java @@ -0,0 +1,36 @@ +/* + * 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.util; + +import javax.annotation.Nonnull; + +/** + * Abstract factory class to support OF protocol version assigning and reading. + */ +public abstract class VersionAssignableFactory { + private Short version; + + /** + * @param version OpenFlow protocol version + */ + public void assignVersion(@Nonnull final Short version) { + if (this.version == null) { + this.version = version; + } else { + throw new IllegalStateException("Version already assigned: " + this.version); + } + } + + /** + * @return OpenFlow protocol version + */ + protected Short getVersion() { + return this.version; + } +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java index 3f900d80..d0c071e5 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java @@ -31,7 +31,7 @@ public final class StatisticsCounters implements StatisticsHandler { */ public static final int MINIMAL_LOG_REPORT_PERIOD = 500; private static StatisticsCounters instanceHolder; - private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsCounters.class); + private static final Logger LOG = LoggerFactory.getLogger(StatisticsCounters.class); private Timer logReporter; private int logReportPeriod; @@ -70,7 +70,7 @@ private StatisticsCounters() { runCounting = false; this.logReportPeriod = 0; this.runLogReport = false; - LOGGER.debug("StaticsCounters has been created"); + LOG.debug("StaticsCounters has been created"); } /** @@ -83,7 +83,7 @@ public void startCounting(boolean reportToLogs, int logReportDelay){ return; } resetCounters(); - LOGGER.debug("Counting started..."); + LOG.debug("Counting started..."); if(reportToLogs){ startLogReport(logReportDelay); } @@ -95,7 +95,7 @@ public void startCounting(boolean reportToLogs, int logReportDelay){ */ public void stopCounting(){ runCounting = false; - LOGGER.debug("Stop counting..."); + LOG.debug("Stop counting..."); stopLogReport(); } @@ -127,7 +127,7 @@ public void startLogReport(int logReportDelay){ logReporter = new Timer("SC_Timer"); logReporter.schedule(new LogReporterTask(this), this.logReportPeriod, this.logReportPeriod); runLogReport = true; - LOGGER.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod); + LOG.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod); } /** @@ -137,7 +137,7 @@ public void stopLogReport(){ if(runLogReport){ if(logReporter != null){ logReporter.cancel(); - LOGGER.debug("Statistics log reporter has been canceled"); + LOG.debug("Statistics log reporter has been canceled"); } runLogReport = false; } @@ -213,7 +213,7 @@ public void resetCounters() { for(CounterEventTypes cet : enabledCounters){ countersMap.get(cet).reset(); } - LOGGER.debug("StaticsCounters has been reset"); + LOG.debug("StaticsCounters has been reset"); } @Override @@ -241,7 +241,7 @@ public LogReporterTask(StatisticsCounters sc) { @Override public void run() { for(CounterEventTypes cet : sc.getEnabledCounters()){ - LOG.debug(cet.name() + ": " + sc.getCountersMap().get(cet).getStat()); + LOG.debug("{}: {}", cet.name(), sc.getCountersMap().get(cet).getStat()); } } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModule.java b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModule.java index 5de0a75f..e30b4d6b 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModule.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModule.java @@ -11,7 +11,7 @@ */ public class StatisticsCollectionModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractStatisticsCollectionModule { - private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsCollectionModule.class); + private static final Logger LOG = LoggerFactory.getLogger(StatisticsCollectionModule.class); public StatisticsCollectionModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); @@ -54,7 +54,7 @@ public int getLogReportDelay() { if (statsConfig != null) { statsCounter.startCounting(statsConfig.getStatisticsCollect(), statsConfig.getLogReportDelay()); } else { - LOGGER.debug("Unable to start StatisticCounter - wrong configuration"); + LOG.debug("Unable to start StatisticCounter - wrong configuration"); } /* Internal MXBean implementation */ @@ -93,11 +93,11 @@ public void close() { } catch (Exception e) { String errMsg = "Error by stoping StatisticsCollectionService."; - LOGGER.error(errMsg, e); + LOG.error(errMsg, e); throw new IllegalStateException(errMsg, e); } } - LOGGER.info("StatisticsCollection Service consumer (instance {} turn down.)", this); + LOG.info("StatisticsCollection Service consumer (instance {} turn down.)", this); } @Override @@ -112,7 +112,7 @@ public String printStatistics() { } AutoCloseable ret = new AutoClosableStatisticsCollection(); - LOGGER.info("StatisticsCollection service (instance {}) initialized.", ret); + LOG.info("StatisticsCollection service (instance {}) initialized.", ret); return ret; } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModule.java b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModule.java index 9cbd9c96..a9756bdd 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModule.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModule.java @@ -9,27 +9,19 @@ */ package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; -import com.google.common.base.MoreObjects; -import java.net.InetAddress; -import java.net.UnknownHostException; -import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; -import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; -import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; -import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.google.common.reflect.AbstractInvocationHandler; +import com.google.common.reflect.Reflection; +import java.lang.reflect.Method; +import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; +import org.osgi.framework.BundleContext; /** -* -*/ -public final class SwitchConnectionProviderModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractSwitchConnectionProviderModule - { - - private static Logger LOG = LoggerFactory - .getLogger(SwitchConnectionProviderModule.class); + * @deprecated Replaced by blueprint wiring + */ +@Deprecated +public final class SwitchConnectionProviderModule extends AbstractSwitchConnectionProviderModule { + private BundleContext bundleContext; /** * @param identifier @@ -51,150 +43,34 @@ public SwitchConnectionProviderModule(final org.opendaylight.controller.config.a } @Override - protected void customValidation(){ - // Add custom validation for module attributes here. - } + public AutoCloseable createInstance() { + // The service is provided via blueprint so wait for and return it here for backwards compatibility. + String typeFilter = String.format("(type=%s)", getIdentifier().getInstanceName()); + final WaitingServiceTracker tracker = WaitingServiceTracker.create( + SwitchConnectionProvider.class, bundleContext, typeFilter); + final SwitchConnectionProvider actualService = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES); - @Override - public java.lang.AutoCloseable createInstance() { - LOG.info("SwitchConnectionProvider started."); - SwitchConnectionProviderImpl switchConnectionProviderImpl = new SwitchConnectionProviderImpl(); - try { - ConnectionConfiguration connConfiguration = createConnectionConfiguration(); - switchConnectionProviderImpl.setConfiguration(connConfiguration); - } catch (UnknownHostException e) { - throw new IllegalArgumentException(e.getMessage(), e); - } - return switchConnectionProviderImpl; - } - - /** - * @return instance configuration object - * @throws UnknownHostException - */ - private ConnectionConfiguration createConnectionConfiguration() throws UnknownHostException { - final InetAddress address = extractIpAddressBin(getAddress()); - final Integer port = getPort(); - final long switchIdleTimeout = getSwitchIdleTimeout(); - final Tls tlsConfig = getTls(); - final Threads threads = getThreads(); - final TransportProtocol transportProtocol = getTransportProtocol(); - - return new ConnectionConfiguration() { - @Override - public InetAddress getAddress() { - return address; - } - @Override - public int getPort() { - return port; - } - @Override - public Object getTransferProtocol() { - return transportProtocol; - } + // We don't want to call close on the actual service as its life cycle is controlled by blueprint but + // we do want to close the tracker so create a proxy to override close appropriately. + return Reflection.newProxy(SwitchConnectionProvider.class, new AbstractInvocationHandler() { @Override - public TlsConfiguration getTlsConfiguration() { - if (tlsConfig == null || !(TransportProtocol.TLS.equals(transportProtocol))) { + protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("close")) { + tracker.close(); return null; + } else { + return method.invoke(actualService, args); } - return new TlsConfiguration() { - @Override - public KeystoreType getTlsTruststoreType() { - return MoreObjects.firstNonNull(tlsConfig.getTruststoreType(), null); - } - @Override - public String getTlsTruststore() { - return MoreObjects.firstNonNull(tlsConfig.getTruststore(), null); - } - @Override - public KeystoreType getTlsKeystoreType() { - return MoreObjects.firstNonNull(tlsConfig.getKeystoreType(), null); - } - @Override - public String getTlsKeystore() { - return MoreObjects.firstNonNull(tlsConfig.getKeystore(), null); - } - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType getTlsKeystorePathType() { - return MoreObjects.firstNonNull(tlsConfig.getKeystorePathType(), null); - } - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType getTlsTruststorePathType() { - return MoreObjects.firstNonNull(tlsConfig.getTruststorePathType(), null); - } - @Override - public String getKeystorePassword() { - return MoreObjects.firstNonNull(tlsConfig.getKeystorePassword(), null); - } - @Override - public String getCertificatePassword() { - return MoreObjects.firstNonNull(tlsConfig.getCertificatePassword(), null); - } - @Override - public String getTruststorePassword() { - return MoreObjects.firstNonNull(tlsConfig.getTruststorePassword(), null); - } - }; } - @Override - public long getSwitchIdleTimeout() { - return switchIdleTimeout; - } - @Override - public Object getSslContext() { - // TODO Auto-generated method stub - return null; - } - @Override - public ThreadConfiguration getThreadConfiguration() { - if (threads == null) { - return null; - } - return new ThreadConfiguration() { - - @Override - public int getWorkerThreadCount() { - return threads.getWorkerThreads(); - } - - @Override - public int getBossThreadCount() { - return threads.getBossThreads(); - } - }; - } - }; + }); } - /** - * @param address - * @return - * @throws UnknownHostException - */ - private static InetAddress extractIpAddressBin(final IpAddress address) throws UnknownHostException { - byte[] addressBin = null; - if (address != null) { - if (address.getIpv4Address() != null) { - addressBin = address2bin(address.getIpv4Address().getValue()); - } else if (address.getIpv6Address() != null) { - addressBin = address2bin(address.getIpv6Address().getValue()); - } - } - - if (addressBin == null) { - return null; - } else { - return InetAddress.getByAddress(addressBin); - } + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; } - /** - * @param value - * @return - */ - private static byte[] address2bin(final String value) { - //TODO: translate ipv4 or ipv6 into byte[] - return null; + @Override + public boolean canReuseInstance(AbstractSwitchConnectionProviderModule oldModule) { + return true; } } diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModuleFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModuleFactory.java index 6bf14239..ca41fc39 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModuleFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/SwitchConnectionProviderModuleFactory.java @@ -9,11 +9,28 @@ */ package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; -/** -* -*/ -public class SwitchConnectionProviderModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractSwitchConnectionProviderModuleFactory -{ +import org.opendaylight.controller.config.api.DependencyResolver; +import org.osgi.framework.BundleContext; +/** + * @deprecated Replaced by blueprint wiring + */ +@Deprecated +public class SwitchConnectionProviderModuleFactory extends AbstractSwitchConnectionProviderModuleFactory { + @Override + public SwitchConnectionProviderModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, + SwitchConnectionProviderModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) { + SwitchConnectionProviderModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule, + oldInstance, bundleContext); + module.setBundleContext(bundleContext); + return module; + } + @Override + public SwitchConnectionProviderModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, + BundleContext bundleContext) { + SwitchConnectionProviderModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext); + module.setBundleContext(bundleContext); + return module; + } } diff --git a/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml b/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml new file mode 100644 index 00000000..c4ce514b --- /dev/null +++ b/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang b/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang index 2f80d957..81e5b3e3 100644 --- a/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang +++ b/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang @@ -5,7 +5,7 @@ module openflow-switch-connection-provider-impl { import config {prefix config; revision-date 2013-04-05; } import openflow-switch-connection-provider {prefix openflow-switch-connection-provider; revision-date 2014-03-28; } - import ietf-inet-types {prefix ietf-inet; revision-date 2010-09-24; } + import ietf-inet-types {prefix ietf-inet; revision-date 2013-07-15; } import openflow-configuration {prefix of-config; revision-date 2014-06-30; } import rpc-context { prefix rpcx; revision-date 2013-06-17; } @@ -21,6 +21,7 @@ module openflow-switch-connection-provider-impl { base "config:module-type"; config:provided-service openflow-switch-connection-provider:openflow-switch-connection-provider; config:java-name-prefix SwitchConnectionProvider; + status deprecated; } identity statistics-collection-service-impl { @@ -35,6 +36,12 @@ module openflow-switch-connection-provider-impl { case openflow-switch-connection-provider-impl { when "/config:modules/config:module/config:type = 'openflow-switch-connection-provider-impl'"; + leaf use-barrier { + description "Enable barrier in Openflow java"; + type boolean; + default true; + } + leaf port { description "local listening port"; type uint16; @@ -91,6 +98,10 @@ module openflow-switch-connection-provider-impl { description "password protecting truststore"; type string; } + leaf-list cipher-suites { + description "combination of cryptographic algorithms used by TLS connection"; + type string; + } } container threads { leaf boss-threads { @@ -178,4 +189,4 @@ module openflow-switch-connection-provider-impl { } } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java index fcab9887..55ebf43d 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java @@ -23,13 +23,13 @@ */ public class DummyDecoder extends ByteToMessageDecoder { - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(DummyDecoder.class); @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { - LOGGER.debug("decoding"); + LOG.debug("decoding"); ctx.fireChannelReadComplete(); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java index 8cf3f75f..7b3d814a 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java @@ -8,14 +8,13 @@ package org.opendaylight.openflowjava.protocol.impl.core; +import static org.junit.Assert.assertEquals; + import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; - import java.util.ArrayList; import java.util.List; - import org.junit.Assert; -import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,8 +23,7 @@ import org.opendaylight.openflowjava.util.ByteBufUtils; /** - * - * @author michal.polkorab + * Test for {@link org.opendaylight.openflowjava.protocol.impl.core.OFVersionDetector}. */ @RunWith(MockitoJUnitRunner.class) public class OFVersionDetectorTest { @@ -36,74 +34,40 @@ public class OFVersionDetectorTest { private OFVersionDetector detector; private List list = new ArrayList<>(); - /** - * Sets up test environment - */ @Before public void setUp() { list.clear(); detector = new OFVersionDetector(); } - /** - * Test of decode - * {@link OFVersionDetector#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List) - * } - * - * @throws Exception - */ @Test - public void testDecode13ProtocolMessage() throws Exception { - detector.decode(channelHandlerContext, - ByteBufUtils.hexStringToByteBuf("04 00 00 08 00 00 00 01"), - list); - - Assert.assertEquals(7, ((VersionMessageWrapper) list.get(0)) - .getMessageBuffer().readableBytes()); + public void testDecode13ProtocolMessage() { + detector.decode(channelHandlerContext, ByteBufUtils.hexStringToByteBuf("04 00 00 08 00 00 00 01"), list); + Assert.assertEquals(7, ((VersionMessageWrapper) list.get(0)).getMessageBuffer().readableBytes()); } - /** - * Test of decode - * {@link OFVersionDetector#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List) - * } - * @throws Exception - */ @Test - public void testDecode10ProtocolMessage() throws Exception { - detector.decode(channelHandlerContext, - ByteBufUtils.hexStringToByteBuf("01 00 00 08 00 00 00 01"), - list); - - Assert.assertEquals(7, ((VersionMessageWrapper) list.get(0)) - .getMessageBuffer().readableBytes()); + public void testDecode10ProtocolMessage() { + detector.decode(channelHandlerContext, ByteBufUtils.hexStringToByteBuf("01 00 00 08 00 00 00 01"), list); + Assert.assertEquals(7, ((VersionMessageWrapper) list.get(0)).getMessageBuffer().readableBytes()); } - /** - * Test of decode - * {@link OFVersionDetector#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List) - * } - * @throws Exception - */ @Test - public void testDecodeEmptyProtocolMessage() throws Exception { + public void testDecodeEmptyProtocolMessage() { ByteBuf byteBuffer = ByteBufUtils.hexStringToByteBuf("01 00 00 08 00 00 00 01").skipBytes(8); detector.decode(channelHandlerContext, byteBuffer, list); - - assertEquals( 0, byteBuffer.refCnt() ) ; + assertEquals(0, byteBuffer.refCnt()); } - /** - * Test of decode - * {@link OFVersionDetector#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List) - * } - * - * @throws Exception - */ @Test - public void testDecodeNotSupportedVersionProtocolMessage() throws Exception { - detector.decode(channelHandlerContext, ByteBufUtils.hexStringToByteBuf("02 00 00 08 00 00 00 01"), list); - + public void testDecodeNotSupportedVersionProtocolMessage() { + detector.decode(channelHandlerContext, ByteBufUtils.hexStringToByteBuf("02 01 00 08 00 00 00 01"), list); Assert.assertEquals("List is not empty", 0, list.size()); } + @Test + public void testDecodeHelloProtocolMessage() { + detector.decode(channelHandlerContext, ByteBufUtils.hexStringToByteBuf("05 00 00 08 00 00 00 01"), list); + Assert.assertEquals(7, ((VersionMessageWrapper) list.get(0)).getMessageBuffer().readableBytes()); + } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java index 6001e7f8..48697240 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java @@ -22,6 +22,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; +import com.google.common.collect.Lists; + /** * * @author jameshall @@ -43,7 +45,8 @@ public void setUp() { MockitoAnnotations.initMocks(this); factory = new ChannelInitializerFactory(); tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore", - PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH); + PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")); factory.setDeserializationFactory(deserializationFactory); factory.setSerializationFactory(serializationFactory); factory.setSwitchConnectionHandler(switchConnectionHandler); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java index 3d8717c7..b855cc91 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java @@ -20,13 +20,10 @@ import io.netty.channel.group.DefaultChannelGroup; import io.netty.channel.socket.SocketChannel; import io.netty.handler.ssl.SslHandler; - import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; - import javax.net.ssl.SSLEngine; - import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -42,6 +39,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.Tls; +import com.google.common.collect.Lists; + /** * * @author james.hall @@ -76,13 +75,14 @@ public void setUp() throws Exception { pubChInitializer.setDeserializationFactory(mockDeserializationFactory); pubChInitializer.setSwitchIdleTimeout(1) ; pubChInitializer.getConnectionIterator() ; + pubChInitializer.setUseBarrier(true); when( mockChGrp.size()).thenReturn(1) ; pubChInitializer.setSwitchConnectionHandler( mockSwConnHandler ) ; inetSockAddr = new InetSocketAddress(InetAddress.getLocalHost(), 8675 ) ; - when(mockConnAdaptorFactory.createConnectionFacade(mockSocketCh, null)) + when(mockConnAdaptorFactory.createConnectionFacade(mockSocketCh, null, true)) .thenReturn(mockConnFacade); when(mockSocketCh.remoteAddress()).thenReturn(inetSockAddr) ; when(mockSocketCh.localAddress()).thenReturn(inetSockAddr) ; @@ -91,7 +91,8 @@ public void setUp() throws Exception { when(mockSocketCh.pipeline()).thenReturn(mockChPipeline) ; tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH, - KeystoreType.JKS, "/selfSignedController", PathType.CLASSPATH); + KeystoreType.JKS, "/selfSignedController", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java index a52f44c6..c73f6c63 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java @@ -20,6 +20,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; +import com.google.common.collect.Lists; + /** * * @author jameshall @@ -36,7 +38,8 @@ public class SslContextFactoryTest { public void setUp() { MockitoAnnotations.initMocks(this); tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore", - PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH) ; + PathType.CLASSPATH, KeystoreType.JKS, "/exemplary-ctlKeystore", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ; sslContextFactory = new SslContextFactory(tlsConfiguration); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java index 6d103355..6faad908 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java @@ -18,6 +18,7 @@ import java.net.Socket; import java.util.concurrent.ExecutionException; +import io.netty.channel.unix.Errors; import org.junit.Assert; import org.junit.Test; import org.mockito.Mock; @@ -62,7 +63,25 @@ public void testRunWithNullAddress() throws IOException, InterruptedException, E tcpHandler = new TcpHandler(null, 0); tcpHandler.setChannelInitializer(mockChannelInitializer); - assertEquals("failed to start server", true, startupServer()) ; + assertEquals("failed to start server", true, startupServer(false)) ; + assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ; + shutdownServer(); + } + + /** + * Test run with null address set on Epoll native transport + * @throws IOException + * @throws InterruptedException + * @throws ExecutionException + */ + @Test + public void testRunWithNullAddressOnEpoll() throws IOException, InterruptedException, ExecutionException { + + tcpHandler = new TcpHandler(null, 0); + tcpHandler.setChannelInitializer(mockChannelInitializer); + + //Use Epoll native transport + assertEquals("failed to start server", true, startupServer(true)) ; assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ; shutdownServer(); } @@ -79,11 +98,29 @@ public void testRunWithAddress() throws IOException, InterruptedException, Execu tcpHandler = new TcpHandler(serverAddress, 0); tcpHandler.setChannelInitializer(mockChannelInitializer); - assertEquals("failed to start server", true, startupServer()) ; + assertEquals("failed to start server", true, startupServer(false)) ; assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ; shutdownServer(); } + /** + * Test run with address set on Epoll native transport + * @throws IOException + * @throws InterruptedException + * @throws ExecutionException + */ + @Test + public void testRunWithAddressOnEpoll() throws IOException, InterruptedException, ExecutionException { + + tcpHandler = new TcpHandler(serverAddress, 0); + tcpHandler.setChannelInitializer(mockChannelInitializer); + + //Use Epoll native transport + assertEquals("failed to start server", true, startupServer(true)); + assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())); + shutdownServer(); + } + /** * Test run with encryption * @throws InterruptedException @@ -91,17 +128,40 @@ public void testRunWithAddress() throws IOException, InterruptedException, Execu * @throws ExecutionException */ @Test - public void testRunWithEncryption () throws InterruptedException, IOException, ExecutionException { + public void testRunWithEncryption() throws InterruptedException, IOException, ExecutionException { int serverPort = 28001; tcpHandler = new TcpHandler(serverAddress, serverPort); tcpHandler.setChannelInitializer(mockChannelInitializer); - assertEquals( "failed to start server", true, startupServer()) ; - assertEquals( "wrong connection count", 0, tcpHandler.getNumberOfConnections() ); - assertEquals( "wrong port", serverPort, tcpHandler.getPort() ); - assertEquals( "wrong address", serverAddress.getHostAddress(), tcpHandler.getAddress()) ; + assertEquals( "failed to start server", true, startupServer(false)); + assertEquals( "wrong connection count", 0, tcpHandler.getNumberOfConnections()); + assertEquals( "wrong port", serverPort, tcpHandler.getPort()); + assertEquals( "wrong address", serverAddress.getHostAddress(), tcpHandler.getAddress()); - assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ; + assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())); + + shutdownServer(); + } + + /** + * Test run with encryption on Epoll native transport + * @throws InterruptedException + * @throws IOException + * @throws ExecutionException + */ + @Test + public void testRunWithEncryptionOnEpoll() throws InterruptedException, IOException, ExecutionException { + int serverPort = 28001; + tcpHandler = new TcpHandler(serverAddress, serverPort); + tcpHandler.setChannelInitializer(mockChannelInitializer); + + //Use Epoll native transport + assertEquals( "failed to start server", true, startupServer(true)); + assertEquals( "wrong connection count", 0, tcpHandler.getNumberOfConnections()); + assertEquals( "wrong port", serverPort, tcpHandler.getPort()); + assertEquals( "wrong address", serverAddress.getHostAddress(), tcpHandler.getAddress()); + + assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())); shutdownServer(); } @@ -123,7 +183,7 @@ public void testSocketAlreadyInUse() throws IOException { try { tcpHandler = new TcpHandler(serverAddress, serverPort); tcpHandler.setChannelInitializer(mockChannelInitializer); - tcpHandler.initiateEventLoopGroups(null); + tcpHandler.initiateEventLoopGroups(null, false); tcpHandler.run(); } catch (Exception e) { if (e instanceof BindException) { @@ -134,6 +194,35 @@ public void testSocketAlreadyInUse() throws IOException { Assert.assertTrue("Expected BindException has not been thrown", exceptionThrown == true); } + /** + * Test run on already used port + * @throws IOException + */ + @Test + public void testSocketAlreadyInUseOnEpoll() throws IOException { + int serverPort = 28001; + Socket firstBinder = new Socket(); + boolean exceptionThrown = false; + try { + firstBinder.bind(new InetSocketAddress(serverAddress, serverPort)); + } catch (Exception e) { + Assert.fail("Test precondition failed - not able to bind socket to port " + serverPort); + } + try { + tcpHandler = new TcpHandler(serverAddress, serverPort); + tcpHandler.setChannelInitializer(mockChannelInitializer); + //Use Epoll native transport + tcpHandler.initiateEventLoopGroups(null, true); + tcpHandler.run(); + } catch (Exception e) { + if (e instanceof BindException || e instanceof Errors.NativeIoException) { + exceptionThrown = true; + } + } + firstBinder.close(); + Assert.assertTrue("Expected BindException has not been thrown", exceptionThrown == true); + } + /** * Trigger the server shutdown and wait 2 seconds for completion */ @@ -149,9 +238,13 @@ private void shutdownServer() throws InterruptedException, ExecutionException { * @throws IOException * @throws ExecutionException */ - private Boolean startupServer() throws InterruptedException, IOException, ExecutionException { + private Boolean startupServer(boolean isEpollEnabled) throws InterruptedException, IOException, ExecutionException { ListenableFuture online = tcpHandler.getIsOnlineFuture(); - tcpHandler.initiateEventLoopGroups(null); + /** + * Test EPoll based native transport if isEpollEnabled is true. + * Else use Nio based transport. + */ + tcpHandler.initiateEventLoopGroups(null, isEpollEnabled); (new Thread(tcpHandler)).start(); int retry = 0; while (online.isDone() != true && retry++ < 20) { diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java index ccc24e55..5f080dc5 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java @@ -7,36 +7,28 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; - import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; - import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ChannelOutboundQueue; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl; -import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ResponseExpectedRpcListener; -import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; - /** * @author madamjak * @@ -82,12 +74,12 @@ public void tierDown(){ */ @Test public void test01() throws Exception { - EmbeddedChannel ec = new EmbeddedChannel(new EmbededChannelHandler()); - adapter = new ConnectionAdapterImpl(ec,InetSocketAddress.createUnresolved("localhost", 9876)); + final EmbeddedChannel ec = new EmbeddedChannel(new EmbededChannelHandler()); + adapter = new ConnectionAdapterImpl(ec, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); - ChannelOutboundQueue cq = (ChannelOutboundQueue) ec.pipeline().last(); + final ChannelOutboundQueue cq = (ChannelOutboundQueue) ec.pipeline().last(); counter=0; adapter.barrier(barrierInput); adapter.echo(echoInput); @@ -107,8 +99,8 @@ public void test01() throws Exception { */ @Test public void test02(){ - ChangeWritableEmbededChannel ec = new ChangeWritableEmbededChannel(new EmbededChannelHandler()); - adapter = new ConnectionAdapterImpl(ec,InetSocketAddress.createUnresolved("localhost", 9876)); + final ChangeWritableEmbededChannel ec = new ChangeWritableEmbededChannel(new EmbededChannelHandler()); + adapter = new ConnectionAdapterImpl(ec, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); @@ -132,8 +124,8 @@ public void test02(){ */ private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { @Override - public void write(ChannelHandlerContext ctx, Object msg, - ChannelPromise promise) throws Exception { + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { if(msg instanceof MessageListenerWrapper){ counter++; } @@ -147,7 +139,7 @@ public void write(ChannelHandlerContext ctx, Object msg, */ private class ChangeWritableEmbededChannel extends EmbeddedChannel { private boolean isWrittable; - public ChangeWritableEmbededChannel(ChannelHandler channelHandler){ + public ChangeWritableEmbededChannel(final ChannelHandler channelHandler){ super(channelHandler); setReadOnly(); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java index a7e9904e..e3317e32 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java @@ -10,16 +10,12 @@ import static org.mockito.Mockito.when; import io.netty.channel.Channel; import io.netty.channel.ChannelPipeline; - import java.net.InetSocketAddress; - -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactoryImpl; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; /** * * @author madamjak @@ -39,8 +35,8 @@ public void startUp(){ @Test public void test(){ - ConnectionAdapterFactoryImpl connAdapterFactory = new ConnectionAdapterFactoryImpl(); - ConnectionFacade connFacade = connAdapterFactory.createConnectionFacade(channel, address); + final ConnectionAdapterFactoryImpl connAdapterFactory = new ConnectionAdapterFactoryImpl(); + final ConnectionFacade connFacade = connAdapterFactory.createConnectionFacade(channel, address, true); Assert.assertNotNull("Wrong - ConnectionFacade has not created.", connFacade); Assert.assertEquals("Wrong - diffrence between channel.isOpen() and ConnectionFacade.isAlive()", channel.isOpen(), connFacade.isAlive()); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java index 7088bc09..0909547c 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java @@ -7,24 +7,22 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; - import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; - import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl; -import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ResponseExpectedRpcListener; -import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey; 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; @@ -46,11 +44,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; - /** * @author madamjak * @author michal.polkorab @@ -109,8 +102,8 @@ public void tierDown(){ */ @Test public void testRcp() { - EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); - adapter = new ConnectionAdapterImpl(embChannel,InetSocketAddress.createUnresolved("localhost", 9876)); + final EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); + adapter = new ConnectionAdapterImpl(embChannel, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); @@ -200,12 +193,12 @@ public void testRcp() { */ private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { @Override - public void write(ChannelHandlerContext ctx, Object msg, - ChannelPromise promise) throws Exception { + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { responseOfCall = null; if(msg instanceof MessageListenerWrapper){ - MessageListenerWrapper listener = (MessageListenerWrapper) msg; - OfHeader ofHeader = listener.getMsg(); + final MessageListenerWrapper listener = (MessageListenerWrapper) msg; + final OfHeader ofHeader = listener.getMsg(); responseOfCall = ofHeader; } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java index 55c3945d..07860095 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java @@ -7,24 +7,22 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; import io.netty.channel.embedded.EmbeddedChannel; - import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; - import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl; -import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ResponseExpectedRpcListener; -import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey; 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; @@ -46,11 +44,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; - /** * @author madamjak * @author michal.polkorab @@ -109,8 +102,8 @@ public void tierDown(){ */ @Test public void testRcp() { - EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); - adapter = new ConnectionAdapterImpl(embChannel,InetSocketAddress.createUnresolved("localhost", 9876)); + final EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); + adapter = new ConnectionAdapterImpl(embChannel, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); @@ -200,12 +193,12 @@ public void testRcp() { */ private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { @Override - public void write(ChannelHandlerContext ctx, Object msg, - ChannelPromise promise) throws Exception { + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { responseOfCall = null; if(msg instanceof MessageListenerWrapper){ - MessageListenerWrapper listener = (MessageListenerWrapper) msg; - OfHeader ofHeader = listener.getMsg(); + final MessageListenerWrapper listener = (MessageListenerWrapper) msg; + final OfHeader ofHeader = listener.getMsg(); responseOfCall = ofHeader; } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java index 862de53d..706c624e 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java @@ -141,8 +141,8 @@ public void testEnterOFJavaCounter() { if(!statCounters.isCounterEnabled(CounterEventTypes.DS_FLOW_MODS_ENTERED)){ Assert.fail("Counter " + CounterEventTypes.DS_FLOW_MODS_ENTERED + " is not enabled"); } - EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); - adapter = new ConnectionAdapterImpl(embChannel,InetSocketAddress.createUnresolved("localhost", 9876)); + final EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler()); + adapter = new ConnectionAdapterImpl(embChannel, InetSocketAddress.createUnresolved("localhost", 9876), true); cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) .removalListener(REMOVAL_LISTENER).build(); adapter.setResponseCache(cache); @@ -198,7 +198,7 @@ public void testMessagePassCounter() { Assert.fail("Counter " + CounterEventTypes.US_MESSAGE_PASS + " is not enabled"); } when(channel.pipeline()).thenReturn(pipeline); - adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653)); + adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653), true); adapter.setMessageListener(messageListener); adapter.setSystemListener(systemListener); adapter.setConnectionReadyListener(readyListener); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java index c9f52772..0859a34f 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java @@ -12,13 +12,15 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; - import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; - import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -26,9 +28,6 @@ import org.mockito.MockitoAnnotations; import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl; -import org.opendaylight.openflowjava.protocol.impl.core.connection.ResponseExpectedRpcListener; -import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; @@ -58,11 +57,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; import org.opendaylight.yangtools.yang.binding.DataObject; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalListener; -import com.google.common.cache.RemovalNotification; - /** * @author michal.polkorab * @author madamjak @@ -98,7 +92,7 @@ public void onRemoval( public void setUp() { MockitoAnnotations.initMocks(this); when(channel.pipeline()).thenReturn(pipeline); - adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653)); + adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653), true); adapter.setMessageListener(messageListener); adapter.setSystemListener(systemListener); adapter.setConnectionReadyListener(readyListener); @@ -154,9 +148,9 @@ public void testConsume() { @Test public void testConsume2() { adapter.setResponseCache(mockCache); - BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + final BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); barrierBuilder.setXid(42L); - BarrierOutput barrier = barrierBuilder.build(); + final BarrierOutput barrier = barrierBuilder.build(); adapter.consume(barrier); verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class)); } @@ -166,19 +160,19 @@ public void testConsume2() { */ @Test public void testConsume3() { - BarrierInputBuilder inputBuilder = new BarrierInputBuilder(); + final BarrierInputBuilder inputBuilder = new BarrierInputBuilder(); inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID); inputBuilder.setXid(42L); - BarrierInput barrierInput = inputBuilder.build(); - RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput"); - ResponseExpectedRpcListener listener = new ResponseExpectedRpcListener<>(barrierInput, + final BarrierInput barrierInput = inputBuilder.build(); + final RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput"); + final ResponseExpectedRpcListener listener = new ResponseExpectedRpcListener<>(barrierInput, "failure", mockCache, key); cache.put(key, listener); - BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + final BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); barrierBuilder.setXid(42L); - BarrierOutput barrierOutput = barrierBuilder.build(); + final BarrierOutput barrierOutput = barrierBuilder.build(); adapter.consume(barrierOutput); - ResponseExpectedRpcListener ifPresent = cache.getIfPresent(key); + final ResponseExpectedRpcListener ifPresent = cache.getIfPresent(key); Assert.assertNull("Listener was not discarded", ifPresent); } /** @@ -186,10 +180,10 @@ public void testConsume3() { */ @Test public void testIsAlive(){ - int port = 9876; - String host ="localhost"; - InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); - ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr); + final int port = 9876; + final String host ="localhost"; + final InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); + final ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel, inetSockAddr, true); Assert.assertEquals("Wrong - diffrence between channel.isOpen() and ConnectionAdapterImpl.isAlive()", channel.isOpen(), connAddapter.isAlive()); connAddapter.disconnect(); @@ -201,10 +195,10 @@ public void testIsAlive(){ */ @Test(expected = java.lang.IllegalStateException.class) public void testMissingListeners(){ - int port = 9876; - String host ="localhost"; - InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); - ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr); + final int port = 9876; + final String host ="localhost"; + final InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); + final ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel, inetSockAddr, true); connAddapter.setSystemListener(null); connAddapter.setMessageListener(null); connAddapter.setConnectionReadyListener(null); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java index 76936754..b4097dda 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; import java.net.InetAddress; - import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; @@ -21,25 +20,30 @@ */ public class ConnectionConfigurationImpl implements ConnectionConfiguration { - private InetAddress address; - private int port; + private final InetAddress address; + private final int port; private Object transferProtocol; - private TlsConfiguration tlsConfig; - private long switchIdleTimeout; + private final TlsConfiguration tlsConfig; + private final long switchIdleTimeout; private ThreadConfiguration threadConfig; + private final boolean useBarrier; /** * Creates {@link ConnectionConfigurationImpl} + * * @param address * @param port * @param tlsConfig * @param switchIdleTimeout + * @param useBarrier */ - public ConnectionConfigurationImpl(InetAddress address, int port, TlsConfiguration tlsConfig, long switchIdleTimeout) { + public ConnectionConfigurationImpl(final InetAddress address, final int port, final TlsConfiguration tlsConfig, + final long switchIdleTimeout, final boolean useBarrier) { this.address = address; this.port = port; this.tlsConfig = tlsConfig; this.switchIdleTimeout = switchIdleTimeout; + this.useBarrier = useBarrier; } @Override @@ -61,7 +65,7 @@ public Object getTransferProtocol() { * Used for testing - sets transport protocol * @param protocol */ - public void setTransferProtocol(TransportProtocol protocol) { + public void setTransferProtocol(final TransportProtocol protocol) { this.transferProtocol = protocol; } @@ -89,7 +93,12 @@ public ThreadConfiguration getThreadConfiguration() { /** * @param threadConfig thread model configuration (configures threads used) */ - public void setThreadConfiguration(ThreadConfiguration threadConfig) { + public void setThreadConfiguration(final ThreadConfiguration threadConfig) { this.threadConfig = threadConfig; } + + @Override + public boolean useBarrier() { + return useBarrier; + } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java new file mode 100644 index 00000000..08c98c41 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.impl.core.connection; + +import com.google.common.util.concurrent.FutureCallback; +import javax.annotation.Nullable; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * {@link OutboundQueueEntry} class test + */ +@RunWith(MockitoJUnitRunner.class) +public class OutboundQueueEntryTest { + + private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntryTest.class); + + private static final short VERSION = (short) 13; + private static final long VALUE = 1L; + + private Integer failCounter = 0; + + @Mock + private OfHeader ofHeader; + @Mock + private FutureCallback futureCallback; + + private final OutboundQueueEntry outboundQueueEntry = new OutboundQueueEntry(); + private final OfHeader barrierInput = new BarrierInputBuilder().setVersion(VERSION).setXid(VALUE).build(); + private final OfHeader packetOutInput = new PacketOutInputBuilder().setVersion(VERSION).setXid(VALUE).build(); + private final OfHeader multipartReplyMessage = + new MultipartReplyMessageBuilder().setVersion(VERSION).setXid(VALUE).setFlags(new MultipartRequestFlags(false)).build(); + private final OfHeader flowModInput = new FlowModInputBuilder().setVersion(VERSION).setXid(VALUE).build(); + private final OfHeader flowRemoved = new FlowRemovedMessageBuilder().setVersion(VERSION).setXid(VALUE).build(); + + @Test + public void commit() throws Exception { + outboundQueueEntry.commit(ofHeader, futureCallback); + Assert.assertTrue(outboundQueueEntry.isCommitted()); + Assert.assertFalse(outboundQueueEntry.isCompleted()); + Assert.assertFalse(outboundQueueEntry.isBarrier()); + } + + @Test + public void reset() throws Exception { + outboundQueueEntry.commit(ofHeader, futureCallback); + Assert.assertTrue(outboundQueueEntry.isCommitted()); + + outboundQueueEntry.reset(); + Assert.assertFalse(outboundQueueEntry.isCommitted()); + } + + @Test + public void isBarrier() throws Exception { + outboundQueueEntry.commit(barrierInput, futureCallback); + Assert.assertTrue(outboundQueueEntry.isBarrier()); + } + + @Test + public void takeMessage() throws Exception { + outboundQueueEntry.commit(packetOutInput, futureCallback); + outboundQueueEntry.takeMessage(); + Mockito.verify(futureCallback).onSuccess(Mockito.any()); + } + + @Test + public void complete() throws Exception { + final boolean result = outboundQueueEntry.complete(multipartReplyMessage); + Assert.assertTrue(result); + Assert.assertTrue(outboundQueueEntry.isCompleted()); + } + + @Test(expected = IllegalStateException.class) + public void completeTwice() throws Exception { + outboundQueueEntry.complete(multipartReplyMessage); + outboundQueueEntry.complete(multipartReplyMessage); + } + + @Test + public void fail() throws Exception { + outboundQueueEntry.commit(ofHeader, futureCallback); + outboundQueueEntry.fail(null); + Mockito.verify(futureCallback).onFailure(Mockito.any()); + } + + private Integer increaseFailCounter() { + return ++this.failCounter; + } + + @Test + public void test() throws Exception { + + final FutureCallback result = + new FutureCallback() { + + @Override + public void onSuccess(@Nullable OfHeader ofHeader) { + LOG.info("onSuccess: xid: {}", ofHeader.getXid()); + } + + @Override + public void onFailure(Throwable throwable) { + LOG.info("onFailure! Error: {}", throwable); + LOG.info("Failure called {} time", increaseFailCounter()); + } + }; + + /** This scenario creates entry with XID 1 then commit it, fail it and again commit it */ + /** Simulates behavior when entry is committed after fail */ + /** It shouldn't be in state completed and still have callback, it can consume all threads in thread pool */ + + /** Entry but no callback */ + outboundQueueEntry.commit(flowModInput, null); + /** Failed entry for whatever reason */ + outboundQueueEntry.fail(null); + /** Commit the same entry adding callback */ + outboundQueueEntry.commit(flowModInput, result); + + Assert.assertTrue(outboundQueueEntry.isCompleted()); + Assert.assertTrue(outboundQueueEntry.isCommitted()); + + /** This is check that no callback is in entry stuck */ + Assert.assertFalse(outboundQueueEntry.hasCallback()); + + Assert.assertTrue(this.failCounter == 1); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java index 0b816c25..2ef9cb82 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java @@ -40,6 +40,8 @@ public void testEquals(){ key1 = new RpcResponseKey(xid1, outputClazz1); Assert.assertFalse("Wrong equal by outputClazz.", key1.equals(key2)); key2 = new RpcResponseKey(xid2, outputClazz1); + Assert.assertFalse("Wrong equal.", key1.equals(key2)); + key1 = new RpcResponseKey(xid2, outputClazz1); Assert.assertTrue("Wrong equal.", key1.equals(key2)); } 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 old mode 100644 new mode 100755 index 73237c4a..03cc3f99 --- 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 @@ -7,9 +7,8 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.ListenableFuture; -import java.net.InetAddress; -import java.net.UnknownHostException; import org.junit.Assert; import org.junit.Test; import org.mockito.Mock; @@ -24,11 +23,14 @@ import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionDeserializerKey; 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; @@ -47,6 +49,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import java.net.InetAddress; +import java.net.UnknownHostException; + /** * @author madamjak * @author michal.polkorab @@ -73,7 +78,7 @@ public class SwitchConnectionProviderImpl02Test { * Creates new {@link SwitchConnectionProvider} instance for each test * @param protocol communication protocol */ - public void startUp(TransportProtocol protocol) { + public void startUp(final TransportProtocol protocol) { MockitoAnnotations.initMocks(this); config = null; if (protocol != null) { @@ -82,19 +87,20 @@ public void startUp(TransportProtocol protocol) { provider = new SwitchConnectionProviderImpl(); } - private void createConfig(TransportProtocol protocol) { + private void createConfig(final TransportProtocol protocol) { try { startupAddress = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { + } catch (final UnknownHostException e) { e.printStackTrace(); } tlsConfiguration = null; if (protocol.equals(TransportProtocol.TLS)) { tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS, - "/selfSignedController", PathType.CLASSPATH) ; + "/selfSignedController", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ; } - config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT); + config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true); config.setTransferProtocol(protocol); } @@ -106,8 +112,8 @@ private void createConfig(TransportProtocol protocol) { public void testServerFacade(){ startUp(TransportProtocol.TCP); provider.setConfiguration(config); - ListenableFuture future = provider.startup(); - ServerFacade serverFacade = provider.getServerFacade(); + final ListenableFuture future = provider.startup(); + final ServerFacade serverFacade = provider.getServerFacade(); Assert.assertNotNull("Wrong -- getServerFacade return null",serverFacade); } @@ -126,10 +132,10 @@ public void testShutdownUnconfigured(){ public void testUnregisterWrongKeys(){ startUp(TransportProtocol.TCP); provider.setConfiguration(config); - ExperimenterInstructionSerializerKey testSerKey + final ExperimenterInstructionSerializerKey testSerKey = new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID,42L); Assert.assertFalse("Wrong -- unregisterSerializer",provider.unregisterSerializer(testSerKey)); - ExperimenterInstructionDeserializerKey tesDeserKey + final ExperimenterInstructionDeserializerKey tesDeserKey = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID,24L); Assert.assertFalse("Wrong -- unregisterDeserializer",provider.unregisterDeserializer(tesDeserKey)); } @@ -142,67 +148,67 @@ public void testUnregisterExistingKeys(){ startUp(TransportProtocol.TCP); provider.setConfiguration(config); // -- registerActionSerializer - ExperimenterActionSerializerKey key1 + final ExperimenterActionSerializerKey key1 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, TestSubType.class); provider.registerActionSerializer(key1, serializer); Assert.assertTrue("Wrong -- unregister ActionSerializer", provider.unregisterSerializer(key1)); Assert.assertFalse("Wrong -- unregister ActionSerializer by not existing key", provider.unregisterSerializer(key1)); // -- registerActionDeserializer - ExperimenterActionDeserializerKey key2 + final ExperimenterActionDeserializerKey key2 = new ExperimenterActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); provider.registerActionDeserializer(key2, deserializer); Assert.assertTrue("Wrong -- unregister ActionDeserializer", provider.unregisterDeserializer(key2)); Assert.assertFalse("Wrong -- unregister ActionDeserializer by not existing key", provider.unregisterDeserializer(key2)); // -- registerInstructionSerializer - ExperimenterInstructionSerializerKey key3 + final ExperimenterInstructionSerializerKey key3 = new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID,42L); provider.registerInstructionSerializer(key3, serializer); Assert.assertTrue("Wrong -- unregister InstructionSerializer", provider.unregisterSerializer(key3)); Assert.assertFalse("Wrong -- unregister InstructionSerializer by not existing key", provider.unregisterSerializer(key3)); // -- registerInstructionDeserializer - ExperimenterInstructionDeserializerKey key4 + final ExperimenterInstructionDeserializerKey key4 = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID,42L); provider.registerInstructionDeserializer(key4, deserializer); Assert.assertTrue("Wrong -- unregister InstructionDeserializer", provider.unregisterDeserializer(key4)); Assert.assertFalse("Wrong -- unregister InstructionDeserializer by not existing key", provider.unregisterDeserializer(key4)); // -- registerMatchEntryDeserializer - MatchEntryDeserializerKey key5 + final MatchEntryDeserializerKey key5 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); provider.registerMatchEntryDeserializer(key5, deserializer); Assert.assertTrue("Wrong -- unregister MatchEntryDeserializer", provider.unregisterDeserializer(key5)); Assert.assertFalse("Wrong -- unregister MatchEntryDeserializer by not existing key", provider.unregisterDeserializer(key5)); // -- registerErrorDeserializer - ExperimenterIdDeserializerKey key6 + final ExperimenterIdDeserializerKey key6 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ErrorMessage.class); provider.registerErrorDeserializer(key6, deserializerError); Assert.assertTrue("Wrong -- unregister ErrorDeserializer", provider.unregisterDeserializer(key6)); Assert.assertFalse("Wrong -- unregister ErrorDeserializer by not existing key", provider.unregisterDeserializer(key6)); // -- registerExperimenterMessageDeserializer - ExperimenterIdDeserializerKey key7 + final ExperimenterIdDeserializerKey key7 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); provider.registerExperimenterMessageDeserializer(key7, deserializerExpMsg); Assert.assertTrue("Wrong -- unregister ExperimenterMessageDeserializer", provider.unregisterDeserializer(key7)); Assert.assertFalse("Wrong -- unregister ExperimenterMessageDeserializer by not existing key", provider.unregisterDeserializer(key7)); // -- registerMultipartReplyMessageDeserializer - ExperimenterIdDeserializerKey key8 + final ExperimenterIdDeserializerKey key8 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, MultipartReplyMessage.class); provider.registerMultipartReplyMessageDeserializer(key8, deserializerMultipartRplMsg); Assert.assertTrue("Wrong -- unregister MultipartReplyMessageDeserializer", provider.unregisterDeserializer(key8)); Assert.assertFalse("Wrong -- unregister MultipartReplyMessageDeserializer by not existing key", provider.unregisterDeserializer(key8)); // -- registerMultipartReplyTFDeserializer - ExperimenterIdDeserializerKey key9 = + final ExperimenterIdDeserializerKey key9 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, MultipartReplyMessage.class); provider.registerMultipartReplyTFDeserializer(key9, deserializer); Assert.assertTrue("Wrong -- unregister MultipartReplyTFDeserializer", provider.unregisterDeserializer(key9)); Assert.assertFalse("Wrong -- unregister MultipartReplyTFDeserializer by non existing key", provider.unregisterDeserializer(key9)); // -- registerQueuePropertyDeserializer - ExperimenterIdDeserializerKey key10 + final ExperimenterIdDeserializerKey key10 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, QueueProperty.class); provider.registerQueuePropertyDeserializer(key10, deserializerQueueProperty); Assert.assertTrue("Wrong -- unregister QueuePropertyDeserializer", provider.unregisterDeserializer(key10)); Assert.assertFalse("Wrong -- unregister QueuePropertyDeserializer by not existing key", provider.unregisterDeserializer(key10)); // -- registerMeterBandDeserializer - ExperimenterIdDeserializerKey key11 + final ExperimenterIdDeserializerKey key11 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, MeterBandExperimenterCase.class); provider.registerMeterBandDeserializer(key11, deserializerMeterBandExpCase); Assert.assertTrue("Wrong -- unregister MeterBandDeserializer", provider.unregisterDeserializer(key11)); @@ -220,23 +226,29 @@ public void testUnregisterExistingKeys(){ Assert.assertTrue("Wrong -- unregister MultipartRequestSerializer", provider.unregisterSerializer(key13)); Assert.assertFalse("Wrong -- unregister MultipartRequestSerializer by not existing key", provider.unregisterSerializer(key13)); // -- registerMultipartRequestTFSerializer - ExperimenterIdSerializerKey key14 + final ExperimenterIdSerializerKey key14 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID,42L,TableFeatureProperties.class); provider.registerMultipartRequestTFSerializer(key14, serializer); Assert.assertTrue("Wrong -- unregister MultipartRequestTFSerializer", provider.unregisterSerializer(key14)); Assert.assertFalse("Wrong -- unregister MultipartRequestTFSerializer by not existing key", provider.unregisterSerializer(key14)); // -- registerMeterBandSerializer - ExperimenterIdSerializerKey key15 - = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID,42L,MeterBandExperimenterCase.class); + final ExperimenterIdMeterSubTypeSerializerKey key15 + = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID,42L,MeterBandExperimenterCase.class,null); provider.registerMeterBandSerializer(key15, serializerMeterBandExpCase); Assert.assertTrue("Wrong -- unregister MeterBandSerializer", provider.unregisterSerializer(key15)); Assert.assertFalse("Wrong -- unregister MeterBandSerializer by not existing key", provider.unregisterSerializer(key15)); // -- registerMatchEntrySerializer - MatchEntrySerializerKey key16 + final MatchEntrySerializerKey key16 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); 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/SwitchConnectionProviderImplTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java index 8fa76e80..17559515 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java @@ -8,12 +8,13 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ListenableFuture; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import org.junit.Assert; import org.junit.Test; import org.mockito.Mock; @@ -27,8 +28,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; -import com.google.common.util.concurrent.ListenableFuture; - /** * @author michal.polkorab * @@ -48,7 +47,7 @@ public class SwitchConnectionProviderImplTest { * Creates new {@link SwitchConnectionProvider} instance for each test * @param protocol communication protocol */ - public void startUp(TransportProtocol protocol) { + public void startUp(final TransportProtocol protocol) { MockitoAnnotations.initMocks(this); config = null; if (protocol != null) { @@ -57,19 +56,20 @@ public void startUp(TransportProtocol protocol) { provider = new SwitchConnectionProviderImpl(); } - private void createConfig(TransportProtocol protocol) { + private void createConfig(final TransportProtocol protocol) { try { startupAddress = InetAddress.getLocalHost(); - } catch (UnknownHostException e) { + } catch (final UnknownHostException e) { e.printStackTrace(); } tlsConfiguration = null; if (protocol.equals(TransportProtocol.TLS)) { tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS, - "/selfSignedController", PathType.CLASSPATH) ; + "/selfSignedController", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")) ; } - config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT); + config = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true); config.setTransferProtocol(protocol); } @@ -79,7 +79,7 @@ private void createConfig(TransportProtocol protocol) { @Test public void testStartup1() { provider = new SwitchConnectionProviderImpl(); - ListenableFuture future = provider.startup(); + final ListenableFuture future = provider.startup(); try { future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { @@ -94,7 +94,7 @@ public void testStartup1() { public void testStartup2() { startUp(null); provider.setSwitchConnectionHandler(handler); - ListenableFuture future = provider.startup(); + final ListenableFuture future = provider.startup(); try { future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { @@ -109,7 +109,7 @@ public void testStartup2() { public void testStartup3() { startUp(TransportProtocol.TCP); provider.setConfiguration(config); - ListenableFuture future = provider.startup(); + final ListenableFuture future = provider.startup(); try { future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { @@ -161,7 +161,7 @@ public void testStartup6() { } catch (InterruptedException | ExecutionException | TimeoutException e) { Assert.fail(); } - } + } /** * Tests correct provider shutdown 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 0dd9ce3b..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,32 @@ 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)); + } catch (TimeoutException e) { + Assert.fail("Wrong - getIsOnlineFuture timed out"); + } + Assert.assertFalse("Wrong - port has been set to zero", udpHandler.getPort() == 0); + shutdownServer(); + } + + /** + * Test to create UdpHandler with empty address and zero port on Epoll native transport + * @throws InterruptedException + * @throws ExecutionException + * @throws IOException + */ + @Test + public void testWithEmptyAddressOnEpoll() throws Exception { udpHandler = new UdpHandler(null, 0); udpHandler.setChannelInitializer(udpChannelInitializerMock); - Assert.assertTrue("Wrong - start server", startupServer()); + 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"); } @@ -64,13 +89,13 @@ public void testWithEmptyAddress() throws InterruptedException, ExecutionExcepti * @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()); + 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"); } @@ -78,21 +103,49 @@ public void testWithAddressAndPort() throws InterruptedException, ExecutionExcep shutdownServer(); } - private Boolean startupServer() throws InterruptedException, IOException, ExecutionException { + /** + * Test to create UdpHandler with fill address and given port on Epoll native transport + * @throws InterruptedException + * @throws ExecutionException + * @throws IOException + */ + @Test + 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)); + } catch (TimeoutException e) { + Assert.fail("Wrong - getIsOnlineFuture timed out"); + } + Assert.assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); + shutdownServer(); + } + + 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(); + + boolean startedSuccessfully = false; + try { + startedSuccessfully = online.get(10, TimeUnit.SECONDS); + } catch (TimeoutException e) { + LOG.warn("Timeout while waiting for UDP handler to start", e); + } - (new Thread(udpHandler)).start(); - int retry = 0; - while (online.isDone() != true && retry++ < 20) { - Thread.sleep(100); - } - return online.isDone() ; + 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 65395c16..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 @@ -12,41 +12,54 @@ import java.util.HashMap; 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.TypeToClassMapInitializer}. * @author michal.polkorab - * + * @author giuseppex.petralia@intel.com */ public class TypeToClassMapInitializerTest { private Map> messageClassMap; - /** - * Tests correct map initialization - */ @Test public void test() { messageClassMap = new HashMap<>(); TypeToClassMapInitializer.initializeTypeToClassMap(messageClassMap); + short version = EncodeConstants.OF10_VERSION_ID; assertEquals("Wrong class", HelloMessage.class, messageClassMap.get(new TypeToClassKey(version, 0))); assertEquals("Wrong class", ErrorMessage.class, messageClassMap.get(new TypeToClassKey(version, 1))); @@ -61,6 +74,7 @@ public void test() { assertEquals("Wrong class", MultipartReplyMessage.class, messageClassMap.get(new TypeToClassKey(version, 17))); assertEquals("Wrong class", BarrierOutput.class, messageClassMap.get(new TypeToClassKey(version, 19))); assertEquals("Wrong class", GetQueueConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 21))); + version = EncodeConstants.OF13_VERSION_ID; assertEquals("Wrong class", HelloMessage.class, messageClassMap.get(new TypeToClassKey(version, 0))); assertEquals("Wrong class", ErrorMessage.class, messageClassMap.get(new TypeToClassKey(version, 1))); @@ -77,5 +91,64 @@ public void test() { assertEquals("Wrong class", GetQueueConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 23))); assertEquals("Wrong class", RoleRequestOutput.class, messageClassMap.get(new TypeToClassKey(version, 25))); assertEquals("Wrong class", GetAsyncOutput.class, messageClassMap.get(new TypeToClassKey(version, 27))); + + version = EncodeConstants.OF14_VERSION_ID; + assertEquals("Wrong class", HelloMessage.class, messageClassMap.get(new TypeToClassKey(version, 0))); + assertEquals("Wrong class", EchoRequestMessage.class, messageClassMap.get(new TypeToClassKey(version, 2))); + assertEquals("Wrong class", EchoOutput.class, messageClassMap.get(new TypeToClassKey(version, 3))); + assertEquals("Wrong class", GetConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 8))); + assertEquals("Wrong class", BarrierOutput.class, messageClassMap.get(new TypeToClassKey(version, 21))); + + version = EncodeConstants.OF15_VERSION_ID; + assertEquals("Wrong class", HelloMessage.class, messageClassMap.get(new TypeToClassKey(version, 0))); + assertEquals("Wrong class", EchoRequestMessage.class, messageClassMap.get(new TypeToClassKey(version, 2))); + assertEquals("Wrong class", EchoOutput.class, messageClassMap.get(new TypeToClassKey(version, 3))); + assertEquals("Wrong class", GetConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 8))); + assertEquals("Wrong class", BarrierOutput.class, messageClassMap.get(new TypeToClassKey(version, 21))); } + + @Test + public void testAdditionalTypes() { + messageClassMap = new HashMap<>(); + TypeToClassMapInitializer.initializeAdditionalTypeToClassMap(messageClassMap); + + short version = EncodeConstants.OF10_VERSION_ID; + assertEquals("Wrong class", GetFeaturesInput.class, messageClassMap.get(new TypeToClassKey(version, 5))); + assertEquals("Wrong class", GetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 7))); + assertEquals("Wrong class", SetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 9))); + assertEquals("Wrong class", PacketOutInput.class, messageClassMap.get(new TypeToClassKey(version, 13))); + assertEquals("Wrong class", FlowModInput.class, messageClassMap.get(new TypeToClassKey(version, 14))); + assertEquals("Wrong class", PortModInput.class, messageClassMap.get(new TypeToClassKey(version, 15))); + assertEquals("Wrong class", MultipartRequestInput.class, messageClassMap.get(new TypeToClassKey(version, 16))); + assertEquals("Wrong class", BarrierInput.class, messageClassMap.get(new TypeToClassKey(version, 18))); + assertEquals("Wrong class", GetQueueConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 20))); + + version = EncodeConstants.OF13_VERSION_ID; + assertEquals("Wrong class", GetFeaturesInput.class, messageClassMap.get(new TypeToClassKey(version, 5))); + assertEquals("Wrong class", GetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 7))); + assertEquals("Wrong class", SetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 9))); + assertEquals("Wrong class", PacketOutInput.class, messageClassMap.get(new TypeToClassKey(version, 13))); + assertEquals("Wrong class", FlowModInput.class, messageClassMap.get(new TypeToClassKey(version, 14))); + assertEquals("Wrong class", GroupModInput.class, messageClassMap.get(new TypeToClassKey(version, 15))); + assertEquals("Wrong class", PortModInput.class, messageClassMap.get(new TypeToClassKey(version, 16))); + assertEquals("Wrong class", TableModInput.class, messageClassMap.get(new TypeToClassKey(version, 17))); + assertEquals("Wrong class", MultipartRequestInput.class, messageClassMap.get(new TypeToClassKey(version, 18))); + assertEquals("Wrong class", BarrierInput.class, messageClassMap.get(new TypeToClassKey(version, 20))); + assertEquals("Wrong class", GetQueueConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 22))); + assertEquals("Wrong class", RoleRequestInput.class, messageClassMap.get(new TypeToClassKey(version, 24))); + assertEquals("Wrong class", GetAsyncInput.class, messageClassMap.get(new TypeToClassKey(version, 26))); + assertEquals("Wrong class", SetAsyncInput.class, messageClassMap.get(new TypeToClassKey(version, 28))); + assertEquals("Wrong class", MeterModInput.class, messageClassMap.get(new TypeToClassKey(version, 29))); + + version = EncodeConstants.OF14_VERSION_ID; + assertEquals("Wrong class", GetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 7))); + assertEquals("Wrong class", SetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 9))); + assertEquals("Wrong class", BarrierInput.class, messageClassMap.get(new TypeToClassKey(version, 20))); + + version = EncodeConstants.OF15_VERSION_ID; + assertEquals("Wrong class", GetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 7))); + assertEquals("Wrong class", SetConfigInput.class, messageClassMap.get(new TypeToClassKey(version, 9))); + assertEquals("Wrong class", BarrierInput.class, messageClassMap.get(new TypeToClassKey(version, 20))); + } + } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java new file mode 100644 index 00000000..5e63639b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierInputMessageFactory}. + * @author giuseppex.petralia@intel.com + */ +public class BarrierInputMessageFactoryTest extends DefaultDeserializerFactoryTest { + + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public BarrierInputMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 20, BarrierInput.class)); + } + + /** + * Testing of {@link BarrierInputMessageFactory} for correct header version. + */ + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer(); + testHeaderVersions(versions, bb); + + // OFP v1.0 need to be tested separately cause of different message type value + messageCodeKey = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 18, BarrierInput.class); + testHeaderVersions(Collections.singletonList(EncodeConstants.OF10_VERSION_ID), bb); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java index a938d5cb..7edff8ed 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java @@ -9,45 +9,46 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - -import org.junit.Before; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; 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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierReplyMessageFactory}. * @author michal.polkorab * @author timotej.kubas */ -public class BarrierReplyMessageFactoryTest { - - private OFDeserializer barrierFactory; +public class BarrierReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { /** - * Initializes deserializer registry and lookups correct deserializer + * Initializes deserializer registry and lookups OF13 deserializer. */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - barrierFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 21, BarrierOutput.class)); + public BarrierReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 21, BarrierOutput.class)); } /** - * Testing of {@link BarrierReplyMessageFactory} for correct translation into POJO + * Testing of {@link BarrierReplyMessageFactory} for correct header version. */ @Test - public void test() { + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); ByteBuf bb = BufferHelper.buildBuffer(); - BarrierOutput builtByFactory = BufferHelper.deserialize( - barrierFactory, bb); + testHeaderVersions(versions, bb); - BufferHelper.checkHeaderV13(builtByFactory); + // OFP v1.0 need to be tested separately cause of different message type value + messageCodeKey = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 19, BarrierOutput.class); + testHeaderVersions(Collections.singletonList(EncodeConstants.OF10_VERSION_ID), bb); } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java index 438ac186..8ec42cb1 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java @@ -9,58 +9,64 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; 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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoReplyMessageFactory}. * @author michal.polkorab * @author timotej.kubas */ -public class EchoReplyMessageFactoryTest { +public class EchoReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { - private OFDeserializer echoFactory; + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public EchoReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 3, EchoOutput.class)); + } /** - * Initializes deserializer registry and lookups correct deserializer + * Testing {@link EchoReplyMessageFactory} for correct header version. */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - echoFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 3, EchoOutput.class)); + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer(); + testHeaderVersions(versions, bb); } /** - * Testing {@link EchoReplyMessageFactory} for correct translation into POJO + * Testing {@link EchoReplyMessageFactory} for correct translation into POJO. */ @Test public void testWithEmptyDataField() { ByteBuf bb = BufferHelper.buildBuffer(); - EchoOutput builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV13(builtByFactory); + EchoOutput builtByFactory = BufferHelper.deserialize(factory, bb); + Assert.assertArrayEquals("Wrong data", null, builtByFactory.getData()); } /** - * Testing {@link EchoReplyMessageFactory} for correct translation into POJO + * Testing {@link EchoReplyMessageFactory} for correct translation into POJO. */ @Test public void testWithDataFieldSet() { byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; ByteBuf bb = BufferHelper.buildBuffer(data); - EchoOutput builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV13(builtByFactory); + EchoOutput builtByFactory = BufferHelper.deserialize(factory, bb); Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); } -} +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java index 376d4dfd..fb8fc490 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java @@ -9,58 +9,66 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; 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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoRequestMessageFactory}. * @author michal.polkorab * @author timotej.kubas */ -public class EchoRequestMessageFactoryTest { +public class EchoRequestMessageFactoryTest extends DefaultDeserializerFactoryTest { - private OFDeserializer echoFactory; + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public EchoRequestMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 2, EchoRequestMessage.class)); + } /** - * Initializes deserializer registry and lookups correct deserializer + * Testing {@link EchoRequestMessageFactory} for correct header version. */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - echoFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 2, EchoRequestMessage.class)); + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer(); + testHeaderVersions(versions, bb); } /** - * Testing {@link EchoRequestMessageFactory} for correct translation into POJO + * Testing {@link EchoRequestMessageFactory} for correct translation into POJO. */ @Test public void testWithEmptyDataField() { + byte[] data = new byte[]{}; ByteBuf bb = BufferHelper.buildBuffer(); - EchoRequestMessage builtByFactory = BufferHelper.deserialize(echoFactory, bb); + EchoRequestMessage builtByFactory = BufferHelper.deserialize(factory, bb); + Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); - BufferHelper.checkHeaderV13(builtByFactory); } /** - * Testing {@link EchoRequestMessageFactory} for correct translation into POJO + * Testing {@link EchoRequestMessageFactory} for correct translation into POJO. */ @Test public void testWithDataFieldSet() { byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; ByteBuf bb = BufferHelper.buildBuffer(data); - EchoRequestMessage builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV13(builtByFactory); + EchoRequestMessage builtByFactory = BufferHelper.deserialize(factory, bb); Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); } -} +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java new file mode 100644 index 00000000..f98564bd --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice._goto.table._case.GotoTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.metadata._case.WriteMetadataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.phy.port._case.InPhyPortBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class FlowModInputMessageFactoryTest { + private OFDeserializer flowFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + flowFactory = registry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 14, FlowModInput.class)); + } + + @Test + public void test() throws Exception { + ByteBuf bb = BufferHelper + .buildBuffer("ff 01 04 01 06 00 07 01 ff 05 00 00 09 30 00 30 41 02 00 0c 00 00 00 7e 00 " + + "00 00 02 00 00 11 46 00 00 00 62 00 0b 00 00 00 01 00 11 80 00 02 04 00 00 00 2a 80 00 12 01 04 00 " + + "00 00 00 00 00 00 00 01 00 08 2b 00 00 00 00 02 00 18 00 00 00 00 ff 01 04 01 06 00 07 01 ff 05 00 00 " + + "09 30 00 30 00 04 00 18 00 00 00 00 00 00 00 10 00 00 00 2a 00 34 00 00 00 00 00 00"); + FlowModInput deserializedMessage = BufferHelper.deserialize(flowFactory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + byte[] cookie = new byte[] { (byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01 }; + Assert.assertEquals("Wrong cookie", new BigInteger(1, cookie), deserializedMessage.getCookie()); + byte[] cookieMask = new byte[] { (byte) 0xFF, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30 }; + Assert.assertEquals("Wrong cookie mask", new BigInteger(1, cookieMask), deserializedMessage.getCookieMask()); + Assert.assertEquals("Wrong table id", new TableId(65L), deserializedMessage.getTableId()); + Assert.assertEquals("Wrong command", FlowModCommand.forValue(2), deserializedMessage.getCommand()); + Assert.assertEquals("Wrong idle timeout", 12, deserializedMessage.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong hard timeout", 0, deserializedMessage.getHardTimeout().intValue()); + Assert.assertEquals("Wrong priority", 126, deserializedMessage.getPriority().intValue()); + Assert.assertEquals("Wrong buffer id ", 2L, deserializedMessage.getBufferId().longValue()); + Assert.assertEquals("Wrong out port", new PortNumber(4422L), deserializedMessage.getOutPort()); + Assert.assertEquals("Wrong out group", 98L, deserializedMessage.getOutGroup().longValue()); + Assert.assertEquals("Wrong flags", new FlowModFlags(true, false, true, false, true), + deserializedMessage.getFlags()); + Assert.assertEquals("Wrong match", createMatch(), deserializedMessage.getMatch()); + Assert.assertEquals("Wrong instructions", createInstructions(), deserializedMessage.getInstruction()); + + } + + private List createInstructions() { + List instructions = new ArrayList<>(); + InstructionBuilder insBuilder = new InstructionBuilder(); + GotoTableCaseBuilder goToCaseBuilder = new GotoTableCaseBuilder(); + GotoTableBuilder instructionBuilder = new GotoTableBuilder(); + instructionBuilder.setTableId((short) 43); + goToCaseBuilder.setGotoTable(instructionBuilder.build()); + insBuilder.setInstructionChoice(goToCaseBuilder.build()); + instructions.add(insBuilder.build()); + WriteMetadataCaseBuilder metadataCaseBuilder = new WriteMetadataCaseBuilder(); + WriteMetadataBuilder metadataBuilder = new WriteMetadataBuilder(); + byte[] metadata = new byte[] { (byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01 }; + metadataBuilder.setMetadata(metadata); + byte[] metadataMask = new byte[] { (byte) 0xFF, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30 }; + metadataBuilder.setMetadataMask(metadataMask); + metadataCaseBuilder.setWriteMetadata(metadataBuilder.build()); + insBuilder.setInstructionChoice(metadataCaseBuilder.build()); + instructions.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder(); + ApplyActionsBuilder actionsBuilder = new ApplyActionsBuilder(); + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(42L)); + outputBuilder.setMaxLength(52); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + actionsBuilder.setAction(actions); + applyActionsCaseBuilder.setApplyActions(actionsBuilder.build()); + insBuilder.setInstructionChoice(applyActionsCaseBuilder.build()); + instructions.add(insBuilder.build()); + return instructions; + } + + private Match createMatch() { + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(42L)); + inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build()); + entriesBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build()); + entries.add(entriesBuilder.build()); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ipEcnBuilder = new IpEcnBuilder(); + ipEcnBuilder.setEcn((short) 4); + ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build()); + entriesBuilder.setMatchEntryValue(ipEcnCaseBuilder.build()); + entries.add(entriesBuilder.build()); + matchBuilder.setMatchEntry(entries); + return matchBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java new file mode 100644 index 00000000..dba971e3 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetAsyncRequestMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 26, GetAsyncInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer(); + GetAsyncInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java new file mode 100644 index 00000000..9f2eb6ab --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetConfigInputMessageFactory}. + * @author giuseppex.petralia@intel.com + */ +public class GetConfigInputMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public GetConfigInputMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 7, GetConfigInput.class)); + } + + /** + * Testing {@link GetConfigInputMessageFactory} for correct header version. + */ + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer(); + testHeaderVersions(versions, bb); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java index 0d48e66d..be3d4faa 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java @@ -9,46 +9,53 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; 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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetConfigReplyMessageFactory}. * @author michal.polkorab * @author timotej.kubas */ -public class GetConfigReplyMessageFactoryTest { +public class GetConfigReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { - private OFDeserializer configFactory; + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public GetConfigReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 8, GetConfigOutput.class)); + } /** - * Initializes deserializer registry and lookups correct deserializer + * Testing {@link GetConfigReplyMessageFactory} for correct header version. */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - configFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 8, GetConfigOutput.class)); + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 03"); + testHeaderVersions(versions, bb); } /** - * Testing {@link GetConfigReplyMessageFactory} for correct translation into POJO + * Testing {@link GetConfigReplyMessageFactory} for correct translation into POJO. */ @Test public void test() { ByteBuf bb = BufferHelper.buildBuffer("00 01 00 03"); - GetConfigOutput builtByFactory = BufferHelper.deserialize(configFactory, bb); - - BufferHelper.checkHeaderV13(builtByFactory); + GetConfigOutput builtByFactory = BufferHelper.deserialize(factory, bb); Assert.assertEquals("Wrong switchConfigFlag", 0x01, builtByFactory.getFlags().getIntValue()); Assert.assertEquals("Wrong missSendLen", 0x03, builtByFactory.getMissSendLen().intValue()); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10BarrierReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java similarity index 58% rename from openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10BarrierReplyMessageFactoryTest.java rename to openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java index ca1db522..0615098c 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10BarrierReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java @@ -1,53 +1,42 @@ /* - * Copyright (c) 2013 Pantheon Technologies s.r.o. and others. All rights reserved. + * Copyright (c) 2015 NetIDE Consortium 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.factories; import io.netty.buffer.ByteBuf; - 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.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.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; /** - * @author michal.polkorab - * @author timotej.kubas + * @author giuseppex.petralia@intel.com + * */ -public class OF10BarrierReplyMessageFactoryTest { - - private OFDeserializer barrierFactory; +public class GetFeaturesInputFactoryTest { + private OFDeserializer factory; - /** - * Initializes deserializer registry and lookups correct deserializer - */ @Before public void startUp() { DeserializerRegistry registry = new DeserializerRegistryImpl(); registry.init(); - barrierFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 19, BarrierOutput.class)); + factory = registry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 5, GetFeaturesInput.class)); } - /** - * Testing of {@link OF10BarrierReplyMessageFactory} for correct translation into POJO - */ @Test - public void testV10() { + public void test() { ByteBuf bb = BufferHelper.buildBuffer(); - BarrierOutput builtByFactory = BufferHelper.deserialize( - barrierFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); + GetFeaturesInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); } } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java new file mode 100644 index 00000000..95f5197d --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetQueueConfigInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 22, GetQueueConfigInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 00 00 00 00"); + GetQueueConfigInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + Assert.assertEquals("Wrong Port No", new PortNumber(0x00010203L), deserializedMessage.getPort()); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java new file mode 100644 index 00000000..0ede670d --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GroupModInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 15, GroupModInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper + .buildBuffer("00 02 03 00 00 00 01 00 00 10 00 0a 00 " + "00 00 41 00 00 00 16 00 00 00 00"); + GroupModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + // Test Message + Assert.assertEquals("Wrong command", GroupModCommand.forValue(2), deserializedMessage.getCommand()); + Assert.assertEquals("Wrong type", GroupType.forValue(3), deserializedMessage.getType()); + Assert.assertEquals("Wrong group id", new GroupId(256L), deserializedMessage.getGroupId()); + BucketsList bucket = deserializedMessage.getBucketsList().get(0); + Assert.assertEquals("Wrong weight", 10, bucket.getWeight().intValue()); + Assert.assertEquals("Wrong watch port", new PortNumber(65L), bucket.getWatchPort()); + Assert.assertEquals("Wrong watch group", 22L, bucket.getWatchGroup().longValue()); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java index 7dab76e2..d4ec69d4 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java @@ -9,46 +9,54 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import java.util.ArrayList; +import java.util.Arrays; import java.util.List; - 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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.ElementsBuilder; /** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.HelloMessageFactory}. * @author michal.polkorab * @author timotej.kubas * @author madamjak */ -public class HelloMessageFactoryTest { +public class HelloMessageFactoryTest extends DefaultDeserializerFactoryTest { - private OFDeserializer helloFactory; + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public HelloMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 0, HelloMessage.class)); + } /** - * Initializes deserializer registry and lookups correct deserializer + * Testing {@link HelloMessageFactory} for correct header version. */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - helloFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 0, HelloMessage.class)); + @Test + public void testVersion() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer("00 01 " // type + + "00 08 " // length + + "00 00 00 11" // bitmap 1 + ); + testHeaderVersions(versions, bb); } /** - * Testing {@link HelloMessageFactory} for correct length without padding + * Testing {@link HelloMessageFactory} for correct length without padding. */ @Test public void testWithoutPadding() { @@ -56,15 +64,14 @@ public void testWithoutPadding() { + "00 08 " // length + "00 00 00 11" // bitmap 1 ); - HelloMessage builtByFactory = BufferHelper.deserialize(helloFactory, bb); - BufferHelper.checkHeaderV13(builtByFactory); + HelloMessage builtByFactory = BufferHelper.deserialize(factory, bb); List element = createElement(4,HelloElementType.VERSIONBITMAP.getIntValue()); Assert.assertEquals("Wrong type", element.get(0).getType(), builtByFactory.getElements().get(0).getType()); Assert.assertEquals("Wrong versionBitmap", element.get(0).getVersionBitmap(), builtByFactory.getElements().get(0).getVersionBitmap()); } /** - * Testing {@link HelloMessageFactory} for correct length with padding + * Testing {@link HelloMessageFactory} for correct length with padding. */ @Test public void testWithPadding() { @@ -74,15 +81,14 @@ public void testWithPadding() { + "00 00 00 00 " // bitmap 2 + "00 00 00 00" // padding ); - HelloMessage builtByFactory = BufferHelper.deserialize(helloFactory, bb); - BufferHelper.checkHeaderV13(builtByFactory); + HelloMessage builtByFactory = BufferHelper.deserialize(factory, bb); List element = createElement(8,HelloElementType.VERSIONBITMAP.getIntValue()); Assert.assertEquals("Wrong type", element.get(0).getType(), builtByFactory.getElements().get(0).getType()); Assert.assertEquals("Wrong versionBitmap", element.get(0).getVersionBitmap(), builtByFactory.getElements().get(0).getVersionBitmap()); } /** - * Testing {@link HelloMessageFactory} if incorrect version is set + * Testing {@link HelloMessageFactory} if incorrect version is set. */ @Test public void testBadType(){ @@ -92,8 +98,7 @@ public void testBadType(){ + "00 00 00 00 " // bitmap 2 + "00 00 00 00" // padding ); - HelloMessage builtByFactory = BufferHelper.deserialize(helloFactory, bb); - BufferHelper.checkHeaderV13(builtByFactory); + HelloMessage builtByFactory = BufferHelper.deserialize(factory, bb); Assert.assertEquals("Wrong - no element has been expected", 0, builtByFactory.getElements().size()); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java new file mode 100644 index 00000000..72c02500 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDropBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemarkBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.Bands; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.mod.BandsBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MeterModInputMessageFactoryTest { + + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 29, MeterModInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 03 00 00 08 c8 00 " + + "01 00 10 00 00 00 01 00 00 00 02 00 00 00 " + "00 00 02 00 10 00 00 00 01 00 00 00 02 03 00 00 00"); + MeterModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong command", MeterModCommand.forValue(1), deserializedMessage.getCommand()); + Assert.assertEquals("Wrong flags", new MeterFlags(false, true, true, false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong meter id", new MeterId(2248L), deserializedMessage.getMeterId()); + Assert.assertEquals("Wrong band", createBandsList().get(0), deserializedMessage.getBands().get(0)); + Assert.assertEquals("Wrong band", createBandsList().get(1), deserializedMessage.getBands().get(1)); + } + + private static List createBandsList() { + List bandsList = new ArrayList<>(); + BandsBuilder bandsBuilder = new BandsBuilder(); + MeterBandDropCaseBuilder dropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropBuilder dropBand = new MeterBandDropBuilder(); + dropBand.setType(MeterBandType.OFPMBTDROP); + dropBand.setRate(1L); + dropBand.setBurstSize(2L); + dropCaseBuilder.setMeterBandDrop(dropBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dropCaseBuilder.build()).build()); + MeterBandDscpRemarkCaseBuilder dscpCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); + MeterBandDscpRemarkBuilder dscpRemarkBand = new MeterBandDscpRemarkBuilder(); + dscpRemarkBand.setType(MeterBandType.OFPMBTDSCPREMARK); + dscpRemarkBand.setRate(1L); + dscpRemarkBand.setBurstSize(2L); + dscpRemarkBand.setPrecLevel((short) 3); + dscpCaseBuilder.setMeterBandDscpRemark(dscpRemarkBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dscpCaseBuilder.build()).build()); + return bandsList; + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java index 00785418..088201b3 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java @@ -87,7 +87,7 @@ public void startUp() { new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 19, MultipartReplyMessage.class)); } - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(MultipartReplyMessageFactoryTest.class); /** @@ -678,7 +678,7 @@ public void testMultipartReplyMeterConfigBodyMulti(){ Assert.assertEquals("Wrong meterBandDscp.burstSize", 32, meterBandDscp.getBurstSize().intValue()); Assert.assertEquals("Wrong meterBandDscp.precLevel", 4, meterBandDscp.getPrecLevel().intValue()); - LOGGER.info(message.getMeterConfig().get(0).getFlags().toString()); + LOG.info(message.getMeterConfig().get(0).getFlags().toString()); Assert.assertEquals("Wrong flags01", new MeterFlags(false, true, true, false), message.getMeterConfig().get(1).getFlags()); Assert.assertEquals("Wrong meterId01", 7, diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java new file mode 100644 index 00000000..43397a8e --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestAggregateInputMessageFactoryTest { + + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 02 00 01 00 00 00 00 08 00 " + + "00 00 00 00 00 55 00 00 00 5f 00 00 00 00 00 01 01 01 01 01 " + "01 01 00 01 01 01 01 01 01 01"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(2), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestAggregate(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestAggregateCase createRequestAggregate() { + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder builder = new MultipartRequestAggregateBuilder(); + builder.setTableId((short) 8); + builder.setOutPort(85L); + builder.setOutGroup(95L); + byte[] cookie = new byte[] { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookieMask = new byte[] { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + builder.setCookieMask(new BigInteger(1, cookieMask)); + caseBuilder.setMultipartRequestAggregate(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java new file mode 100644 index 00000000..89aea312 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestDescInputMessageFactoryTest { + + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 01 00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(0), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestDesc(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestDescCase createRequestDesc() { + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder builder = new MultipartRequestDescBuilder(); + builder.setEmpty(true); + caseBuilder.setMultipartRequestDesc(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java new file mode 100644 index 00000000..d8f9d0a0 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestFlowInputMessageFactoryTest { + + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 01 00 00 00 00 " + "08 00 00 00 00 00 00 55 00 00 00 5f 00 " + + "00 00 00 00 01 01 01 01 01 01 01 00 01 01 01 01 01 01 01"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(1), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong flow", createRequestFlow(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestFlowCase createRequestFlow() { + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder builder = new MultipartRequestFlowBuilder(); + builder.setTableId((short) 8); + builder.setOutPort(85L); + builder.setOutGroup(95L); + byte[] cookie = new byte[] { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookieMask = new byte[] { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + builder.setCookieMask(new BigInteger(1, cookieMask)); + caseBuilder.setMultipartRequestFlow(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java new file mode 100644 index 00000000..6f73801c --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestGroupCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroupBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestGroupInputMessageFactoryTest { + ByteBuf bb = BufferHelper.buildBuffer("00 06 00 01 00 00 00 00 00 00 08 d2 00 00 00 00"); + MultipartRequestInputMessageFactory factory; + MultipartRequestInput deserializedMessage; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + + } + + @Test + public void test() { + deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(6), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestGroup(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestGroupCase createRequestGroup() { + MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder(); + MultipartRequestGroupBuilder builder = new MultipartRequestGroupBuilder(); + builder.setGroupId(new GroupId(2258L)); + caseBuilder.setMultipartRequestGroup(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java new file mode 100644 index 00000000..46c3a13b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterConfigCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfigBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestMeterConfigInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 0a 00 01 00 00 00 00 00 00 04 6d 00 00 00 00"); + + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + Assert.assertEquals("Wrong type", MultipartType.forValue(10), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestMeterConfig(), + deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestMeterConfigCase createRequestMeterConfig() { + MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder(); + MultipartRequestMeterConfigBuilder builder = new MultipartRequestMeterConfigBuilder(); + builder.setMeterId(new MeterId(1133L)); + caseBuilder.setMultipartRequestMeterConfig(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java new file mode 100644 index 00000000..b4f334f9 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestMeterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeterBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestMeterInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 09 00 01 00 00 00 00 00 00 04 61 00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + Assert.assertEquals("Wrong type", MultipartType.forValue(9), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestMeter(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestMeterCase createRequestMeter() { + MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder(); + MultipartRequestMeterBuilder builder = new MultipartRequestMeterBuilder(); + builder.setMeterId(new MeterId(1121L)); + caseBuilder.setMultipartRequestMeter(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java new file mode 100644 index 00000000..68482e36 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestPortStatsInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 04 00 01 00 00 00 00 00 00 08 cb 00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(4), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestPortStats(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestPortStatsCase createRequestPortStats() { + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder builder = new MultipartRequestPortStatsBuilder(); + builder.setPortNo(2251L); + caseBuilder.setMultipartRequestPortStats(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java new file mode 100644 index 00000000..6a746ead --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestQueueInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 05 00 01 00 00 00 00 00 00 08 d0 00 00 08 a3"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(5), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong aggregate", createRequestQueue(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestQueueCase createRequestQueue() { + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder builder = new MultipartRequestQueueBuilder(); + builder.setPortNo(2256L); + builder.setQueueId(2211L); + caseBuilder.setMultipartRequestQueue(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java new file mode 100644 index 00000000..600a7aaf --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.multipart.request.table.features.TableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestTableFeaturesInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 0c 00 01 00 00 00 00 00 68 01 00 00 00 00 00 4e 61 6d " + + "65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 " + + "00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 10 00 01 " + + "00 04 00 02 00 04 00 04 00 04 00 02 00 05 01 00 00 00 00 04 00 08 00 00 00 04 00 08 00 08 80 00 02 04 "); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + Assert.assertEquals("Wrong type", MultipartType.forValue(12), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createTableFeatures(), deserializedMessage.getMultipartRequestBody()); + } + + public MultipartRequestTableFeaturesCase createTableFeatures() { + MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + MultipartRequestTableFeaturesBuilder builder = new MultipartRequestTableFeaturesBuilder(); + builder.setTableFeatures(createTableFeaturesList()); + caseBuilder.setMultipartRequestTableFeatures(builder.build()); + return caseBuilder.build(); + + } + + public List createTableFeaturesList() { + List list = new ArrayList<>(); + TableFeaturesBuilder builder = new TableFeaturesBuilder(); + builder.setTableId((short) 1); + builder.setName("Name"); + builder.setMetadataWrite(new BigInteger("1")); + builder.setMetadataMatch(new BigInteger("1")); + builder.setMaxEntries(1L); + builder.setConfig(new TableConfig(false)); + builder.setTableFeatureProperties(createTableFeatureProperties()); + list.add(builder.build()); + return list; + } + + public List createTableFeatureProperties() { + List list = new ArrayList<>(); + TableFeaturePropertiesBuilder builder = new TableFeaturePropertiesBuilder(); + builder.setType(TableFeaturesPropType.forValue(0)); + InstructionRelatedTableFeaturePropertyBuilder insBuilder = new InstructionRelatedTableFeaturePropertyBuilder(); + insBuilder.setInstruction(createInstructions()); + builder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insBuilder.build()); + list.add(builder.build()); + + builder = new TableFeaturePropertiesBuilder(); + builder.setType(TableFeaturesPropType.forValue(2)); + NextTableRelatedTableFeaturePropertyBuilder nextBuilder = new NextTableRelatedTableFeaturePropertyBuilder(); + nextBuilder.setNextTableIds(createNextTableIds()); + builder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextBuilder.build()); + list.add(builder.build()); + + builder = new TableFeaturePropertiesBuilder(); + builder.setType(TableFeaturesPropType.forValue(4)); + ActionRelatedTableFeaturePropertyBuilder actionBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + actionBuilder.setAction(createAction()); + builder.addAugmentation(ActionRelatedTableFeatureProperty.class, actionBuilder.build()); + list.add(builder.build()); + + builder = new TableFeaturePropertiesBuilder(); + builder.setType(TableFeaturesPropType.forValue(8)); + OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + oxmBuilder.setMatchEntry(createMatchEntries()); + builder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + list.add(builder.build()); + + return list; + } + + public List createMatchEntries() { + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + return entries; + } + + public List createAction() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + return actions; + } + + public List createNextTableIds() { + List list = new ArrayList<>(); + NextTableIdsBuilder builder = new NextTableIdsBuilder(); + builder.setTableId((short) 1); + list.add(builder.build()); + return list; + } + + public List createInstructions() { + List instructions = new ArrayList<>(); + InstructionBuilder insBuilder = new InstructionBuilder(); + GotoTableCaseBuilder goToCaseBuilder = new GotoTableCaseBuilder(); + insBuilder.setInstructionChoice(goToCaseBuilder.build()); + instructions.add(insBuilder.build()); + WriteMetadataCaseBuilder metadataCaseBuilder = new WriteMetadataCaseBuilder(); + insBuilder.setInstructionChoice(metadataCaseBuilder.build()); + instructions.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder(); + insBuilder.setInstructionChoice(applyActionsCaseBuilder.build()); + instructions.add(insBuilder.build()); + return instructions; + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java new file mode 100644 index 00000000..8719dc2b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartRequestTableInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 18, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 01 00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong type", MultipartType.forValue(3), deserializedMessage.getType()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(true), deserializedMessage.getFlags()); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactoryTest.java deleted file mode 100644 index 3da76971..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoReplyMessageFactoryTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013 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.factories; - -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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; - -/** - * @author michal.polkorab - * @author timotej.kubas - */ -public class OF10EchoReplyMessageFactoryTest { - - private OFDeserializer echoFactory; - - /** - * Initializes deserializer registry and lookups correct deserializer - */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - echoFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 3, EchoOutput.class)); - } - - /** - * Testing {@link OF10EchoReplyMessageFactory} for correct translation into POJO - */ - @Test - public void testWithEmptyDataFieldV10() { - ByteBuf bb = BufferHelper.buildBuffer(); - EchoOutput builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); - } - - /** - * Testing {@link OF10EchoReplyMessageFactory} for correct translation into POJO - */ - @Test - public void testWithDataFieldSetV10() { - byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; - ByteBuf bb = BufferHelper.buildBuffer(data); - EchoOutput builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); - Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); - } -} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactoryTest.java deleted file mode 100644 index 12113a37..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10EchoRequestMessageFactoryTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2013 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.factories; - -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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; - -/** - * @author michal.polkorab - * @author timotej.kubas - */ -public class OF10EchoRequestMessageFactoryTest { - - private OFDeserializer echoFactory; - - /** - * Initializes deserializer registry and lookups correct deserializer - */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - echoFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 2, EchoRequestMessage.class)); - } - - /** - * Testing {@link OF10EchoReplyMessageFactoryTest} for correct translation into POJO - */ - @Test - public void testWithEmptyDataFieldV10() { - ByteBuf bb = BufferHelper.buildBuffer(); - EchoRequestMessage builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); - } - - /** - * Testing {@link OF10EchoReplyMessageFactoryTest} for correct translation into POJO - */ - @Test - public void testWithDataFieldSetV10() { - byte[] data = new byte[]{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; - ByteBuf bb = BufferHelper.buildBuffer(data); - EchoRequestMessage builtByFactory = BufferHelper.deserialize(echoFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); - Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); - } -} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java index e759185e..594ca829 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java @@ -19,7 +19,7 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.common.types.rev130731.ActionTypeV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; @@ -128,4 +128,4 @@ public void testWithNoPortsSet() { false, false, false, false, false, false), builtByFactory.getActionsV10()); Assert.assertEquals("Wrong ports size", 0, builtByFactory.getPhyPort().size()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java new file mode 100644 index 00000000..97682d89 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FeaturesRequestMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 5, GetFeaturesInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer(); + GetFeaturesInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java new file mode 100644 index 00000000..9ff3f055 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.action.rev150203.action.grouping.action.choice.SetNwDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.dst._case.SetNwDstActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.tp.src._case.SetTpSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModCommand; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlagsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FlowModInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 14, FlowModInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 38 20 ff 00 3a 01 01 01 01 01 01 ff " + + "ff ff ff ff ff 00 12 05 00 00 2a 04 07 00 00 08 08 08 08 10 10 10 10 " + + "19 fd 19 e9 ff 01 04 01 06 00 07 01 00 00 00 0c 00 10 00 01 00 00 00 02 " + + "11 46 00 03 00 07 00 08 02 02 02 02 00 09 00 08 00 2a 00 00 "); + FlowModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + Assert.assertEquals("Wrong Match", createMatch(), deserializedMessage.getMatchV10()); + byte[] cookie = new byte[] { (byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01 }; + Assert.assertEquals("Wrong cookie", new BigInteger(1, cookie), deserializedMessage.getCookie()); + Assert.assertEquals("Wrong command", FlowModCommand.forValue(0), deserializedMessage.getCommand()); + Assert.assertEquals("Idle Timeout", 12, deserializedMessage.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong Hard Timeout", 16, deserializedMessage.getHardTimeout().intValue()); + Assert.assertEquals("Wrong priority", 1, deserializedMessage.getPriority().intValue()); + Assert.assertEquals("Wrong buffer id", 2L, deserializedMessage.getBufferId().longValue()); + Assert.assertEquals("Wrong out port", new PortNumber(4422L), deserializedMessage.getOutPort()); + Assert.assertEquals("Wrong flags", new FlowModFlagsV10(true, false, true), deserializedMessage.getFlagsV10()); + Assert.assertEquals("Wrong actions", createAction(), deserializedMessage.getAction()); + } + + private static List createAction() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + SetNwDstCaseBuilder nwDstCaseBuilder = new SetNwDstCaseBuilder(); + SetNwDstActionBuilder nwDstBuilder = new SetNwDstActionBuilder(); + nwDstBuilder.setIpAddress(new Ipv4Address("2.2.2.2")); + nwDstCaseBuilder.setSetNwDstAction(nwDstBuilder.build()); + actionBuilder.setActionChoice(nwDstCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetTpSrcCaseBuilder tpSrcCaseBuilder = new SetTpSrcCaseBuilder(); + SetTpSrcActionBuilder tpSrcBuilder = new SetTpSrcActionBuilder(); + tpSrcBuilder.setPort(new PortNumber(42L)); + tpSrcCaseBuilder.setSetTpSrcAction(tpSrcBuilder.build()); + actionBuilder.setActionChoice(tpSrcCaseBuilder.build()); + actions.add(actionBuilder.build()); + return actions; + } + + private static MatchV10 createMatch() { + MatchV10Builder matchBuilder = new MatchV10Builder(); + matchBuilder.setWildcards(new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true)); + matchBuilder.setNwSrcMask((short) 0); + matchBuilder.setNwDstMask((short) 0); + matchBuilder.setInPort(58); + matchBuilder.setDlSrc(new MacAddress("01:01:01:01:01:01")); + matchBuilder.setDlDst(new MacAddress("ff:ff:ff:ff:ff:ff")); + matchBuilder.setDlVlan(18); + matchBuilder.setDlVlanPcp((short) 5); + matchBuilder.setDlType(42); + matchBuilder.setNwTos((short) 4); + matchBuilder.setNwProto((short) 7); + matchBuilder.setNwSrc(new Ipv4Address("8.8.8.8")); + matchBuilder.setNwDst(new Ipv4Address("16.16.16.16")); + matchBuilder.setTpSrc(6653); + matchBuilder.setTpDst(6633); + return matchBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactoryTest.java deleted file mode 100644 index fe75abc4..00000000 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetConfigReplyMessageFactoryTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 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.factories; - -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.keys.MessageCodeKey; -import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; - -/** - * @author michal.polkorab - * @author timotej.kubas - */ -public class OF10GetConfigReplyMessageFactoryTest { - - private OFDeserializer configFactory; - - /** - * Initializes deserializer registry and lookups correct deserializer - */ - @Before - public void startUp() { - DeserializerRegistry registry = new DeserializerRegistryImpl(); - registry.init(); - configFactory = registry.getDeserializer( - new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 8, GetConfigOutput.class)); - } - - /** - * Testing {@link OF10GetConfigReplyMessageFactory} for correct translation into POJO - */ - @Test - public void test() { - ByteBuf bb = BufferHelper.buildBuffer("00 01 00 03"); - GetConfigOutput builtByFactory = BufferHelper.deserialize(configFactory, bb); - - BufferHelper.checkHeaderV10(builtByFactory); - Assert.assertEquals("Wrong switchConfigFlag", 0x01, builtByFactory.getFlags().getIntValue()); - Assert.assertEquals("Wrong missSendLen", 0x03, builtByFactory.getMissSendLen().intValue()); - } - -} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java new file mode 100644 index 00000000..15873bd1 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10GetQueueConfigInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 20, GetQueueConfigInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("19 fd 00 00"); + GetQueueConfigInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + Assert.assertEquals("Wrong port", new PortNumber(6653L), deserializedMessage.getPort()); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java new file mode 100644 index 00000000..93425026 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.StripVlanCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PacketOutInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 13, PacketOutInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 01 00 01 01 00 10 00 00 00 08 " + + "00 2a 00 32 00 03 00 08 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + + PacketOutInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + Assert.assertEquals("Wrong bufferId ", 256L, deserializedMessage.getBufferId().longValue()); + Assert.assertEquals("Wrong inPort ", new PortNumber(257L), deserializedMessage.getInPort()); + Assert.assertEquals("Wrong action ", createActionList().get(0), deserializedMessage.getAction().get(0)); + Assert.assertEquals("Wrong action ", createActionList().get(1), deserializedMessage.getAction().get(1)); + Assert.assertArrayEquals("Wrong data ", + ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"), + deserializedMessage.getData()); + } + + private static List createActionList() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(42L)); + outputBuilder.setMaxLength(50); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new StripVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + return actions; + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java new file mode 100644 index 00000000..660ab5ce --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PortModInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 15, PortModInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper + .buildBuffer("19 e9 08 00 27 00 b0 eb " + "00 00 00 15 00 00 00 62 00 00 02 8c 00 00 00 00 "); + PortModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + Assert.assertEquals("Wrong port", new PortNumber(6633L), deserializedMessage.getPortNo()); + Assert.assertEquals("Wrong hwAddr", new MacAddress("08:00:27:00:b0:eb"), deserializedMessage.getHwAddress()); + Assert.assertEquals("Wrong config", new PortConfigV10(true, false, false, true, false, false, true), + deserializedMessage.getConfigV10()); + Assert.assertEquals("Wrong mask", new PortConfigV10(false, true, true, false, false, true, false), + deserializedMessage.getMaskV10()); + Assert.assertEquals("Wrong advertise", + new PortFeaturesV10(true, true, false, false, false, false, false, true, true, false, false, false), + deserializedMessage.getAdvertiseV10()); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java index 76b94b2c..9467e8d1 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java @@ -19,7 +19,7 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.common.types.rev130731.PortConfigV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; @@ -73,4 +73,4 @@ public void test(){ Assert.assertEquals("Wrong builtByFactory - peer", new PortFeaturesV10(true, false, false, false, false, false, false, false, true, false, false, true), builtByFactory.getPeerFeaturesV10()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java new file mode 100644 index 00000000..5c8ce215 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestAggregateCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.aggregate._case.MultipartRequestAggregateBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputAggregateFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 02 00 00 00 00 00 00 00 33 00 01 02 " + + "03 04 05 05 04 03 02 01 00 00 34 35 00 00 36 37 38 00 00 0a 00 00 01 " + + "0a 00 00 02 00 39 00 3a 2a 00 19 fd"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + + Assert.assertEquals("Wrong type", 2, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder aggregateBuilder = new MultipartRequestAggregateBuilder(); + MatchV10Builder matchBuilder = new MatchV10Builder(); + matchBuilder.setWildcards( + new FlowWildcardsV10(false, false, false, false, false, false, false, false, false, false)); + matchBuilder.setNwSrcMask((short) 32); + matchBuilder.setNwDstMask((short) 32); + matchBuilder.setInPort(51); + matchBuilder.setDlSrc(new MacAddress("00:01:02:03:04:05")); + matchBuilder.setDlDst(new MacAddress("05:04:03:02:01:00")); + matchBuilder.setDlVlan(52); + matchBuilder.setDlVlanPcp((short) 53); + matchBuilder.setDlType(54); + matchBuilder.setNwTos((short) 55); + matchBuilder.setNwProto((short) 56); + matchBuilder.setNwSrc(new Ipv4Address("10.0.0.1")); + matchBuilder.setNwDst(new Ipv4Address("10.0.0.2")); + matchBuilder.setTpSrc(57); + matchBuilder.setTpDst(58); + aggregateBuilder.setMatchV10(matchBuilder.build()); + aggregateBuilder.setTableId((short) 42); + aggregateBuilder.setOutPort(6653L); + caseBuilder.setMultipartRequestAggregate(aggregateBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java new file mode 100644 index 00000000..545d1d7b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.desc._case.MultipartRequestDescBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputDescFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + + Assert.assertEquals("Wrong type", 0, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder(); + descBuilder.setEmpty(true); + caseBuilder.setMultipartRequestDesc(descBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java new file mode 100644 index 00000000..613ff4a1 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlowBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputFlowFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 00 00 34 18 ff 00 33 00 01 02 03 04 " + + "05 05 04 03 02 01 00 00 34 35 00 00 36 37 38 00 00 0a 00 00 01 0a 00 00 02 " + + "00 39 00 3a 01 00 00 2a "); + + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + Assert.assertEquals("Wrong type", 1, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder(); + MatchV10Builder matchBuilder = new MatchV10Builder(); + matchBuilder.setWildcards(new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true)); + matchBuilder.setNwSrcMask((short) 8); + matchBuilder.setNwDstMask((short) 16); + matchBuilder.setInPort(51); + matchBuilder.setDlSrc(new MacAddress("00:01:02:03:04:05")); + matchBuilder.setDlDst(new MacAddress("05:04:03:02:01:00")); + matchBuilder.setDlVlan(52); + matchBuilder.setDlVlanPcp((short) 53); + matchBuilder.setDlType(54); + matchBuilder.setNwTos((short) 55); + matchBuilder.setNwProto((short) 56); + matchBuilder.setNwSrc(new Ipv4Address("10.0.0.1")); + matchBuilder.setNwDst(new Ipv4Address("10.0.0.2")); + matchBuilder.setTpSrc(57); + matchBuilder.setTpDst(58); + flowBuilder.setMatchV10(matchBuilder.build()); + flowBuilder.setTableId((short) 1); + flowBuilder.setOutPort(42L); + caseBuilder.setMultipartRequestFlow(flowBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java new file mode 100644 index 00000000..afe70c92 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStatsBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputPortStatsFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 04 00 00 00 0f 00 00 00 00 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + + Assert.assertEquals("Wrong type", 4, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder(); + portBuilder.setPortNo(15L); + caseBuilder.setMultipartRequestPortStats(portBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java new file mode 100644 index 00000000..39c571cd --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueueBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputQueueFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 05 00 00 00 0f 00 00 00 00 00 10"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + + Assert.assertEquals("Wrong type", 5, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder(); + queueBuilder.setPortNo(15L); + queueBuilder.setQueueId(16L); + caseBuilder.setMultipartRequestQueue(queueBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java new file mode 100644 index 00000000..bc9bdf77 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.MultipartRequestBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table._case.MultipartRequestTableBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputTableFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 16, MultipartRequestInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 00"); + MultipartRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV10(deserializedMessage); + + Assert.assertEquals("Wrong type", 3, deserializedMessage.getType().getIntValue()); + Assert.assertEquals("Wrong flags", new MultipartRequestFlags(false), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong body", createMultipartRequestBody(), deserializedMessage.getMultipartRequestBody()); + } + + private static MultipartRequestBody createMultipartRequestBody() { + MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder(); + MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder(); + tableBuilder.setEmpty(true); + caseBuilder.setMultipartRequestTable(tableBuilder.build()); + return caseBuilder.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java new file mode 100644 index 00000000..8a2b1e98 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopVlanCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.vlan._case.PushVlanActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PacketOutInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + factory = registry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 13, PacketOutInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer( + "00 00 01 00 00 00 01 00 00 28 00 00 00 00 00 00 00 11 00 08 00 19 00 00 00 12 00 08 00 00 00 00 00 12 " + + "00 08 00 00 00 00 00 12 00 08 00 00 00 00 00 12 00 08 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 10 " + + "11 12 13 14"); + PacketOutInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong buffer Id", 256L, deserializedMessage.getBufferId().longValue()); + Assert.assertEquals("Wrong In Port", new PortNumber(256L), deserializedMessage.getInPort()); + Assert.assertEquals("Wrong Numbers of actions", createAction(), deserializedMessage.getAction()); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + Assert.assertArrayEquals("Wrong data", data, deserializedMessage.getData()); + } + + private List createAction() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + PushVlanCaseBuilder pushVlanCaseBuilder = new PushVlanCaseBuilder(); + PushVlanActionBuilder pushVlanBuilder = new PushVlanActionBuilder(); + pushVlanBuilder.setEthertype(new EtherType(new EtherType(25))); + pushVlanCaseBuilder.setPushVlanAction(pushVlanBuilder.build()); + actionBuilder.setActionChoice(pushVlanCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + return actions; + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java new file mode 100644 index 00000000..b27bb279 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PortModInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() throws Exception { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 16, PortModInput.class)); + } + + @Test + public void test() throws Exception { + ByteBuf bb = BufferHelper.buildBuffer( + "00 00 00 09 00 00 00 00 08 00 27 00 " + "b0 eb 00 00 00 00 00 24 00 00 00 41 00 00 01 10 00 00 00 00"); + PortModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + // Test Message + Assert.assertEquals("Wrong port", new PortNumber(9L), deserializedMessage.getPortNo()); + Assert.assertEquals("Wrong hwAddr", new MacAddress("08:00:27:00:b0:eb"), deserializedMessage.getHwAddress()); + Assert.assertEquals("Wrong config", new PortConfig(true, false, true, false), deserializedMessage.getConfig()); + Assert.assertEquals("Wrong mask", new PortConfig(false, true, false, true), deserializedMessage.getMask()); + Assert.assertEquals("Wrong advertise", new PortFeatures(true, false, false, false, false, false, false, true, + false, false, false, false, false, false, false, false), deserializedMessage.getAdvertise()); + + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java index 67f9b266..84653207 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java @@ -20,7 +20,7 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.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.PortState; @@ -72,7 +72,7 @@ public void test(){ BufferHelper.checkHeaderV13(builtByFactory); Assert.assertEquals("Wrong reason", 0x01, builtByFactory.getReason().getIntValue()); Assert.assertEquals("Wrong portNumber", 66051L, builtByFactory.getPortNo().longValue()); - Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:B0:EB"), builtByFactory.getHwAddr()); + Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:b0:eb"), builtByFactory.getHwAddr()); Assert.assertEquals("Wrong name", "s1-eth1", builtByFactory.getName()); Assert.assertEquals("Wrong portConfig", new PortConfig(false, true, false, true), builtByFactory.getConfig()); Assert.assertEquals("Wrong portState", new PortState(false, true, true), builtByFactory.getState()); @@ -118,4 +118,4 @@ public void testWithDifferentBitmaps(){ false, false, false, false, false, false, false, false, false, false, false, false), message.getPeerFeatures()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java new file mode 100644 index 00000000..368aca40 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.math.BigInteger; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ControllerRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class RoleRequestInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 24, RoleRequestInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 02 00 00 00 00 ff 01 01 01 01 01 01 01"); + RoleRequestInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + Assert.assertEquals("Wrong role", ControllerRole.forValue(2), deserializedMessage.getRole()); + byte[] generationId = new byte[] { (byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; + Assert.assertEquals("Wrong generation Id", new BigInteger(1, generationId), + deserializedMessage.getGenerationId()); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java new file mode 100644 index 00000000..e5c1d9af --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.List; +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMaskBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class SetAsyncInputMessageFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 28, SetAsyncInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper + .buildBuffer("00 00 00 07 00 00 00 00 00 00 00 " + "07 00 00 00 00 00 00 00 0f 00 00 00 00"); + SetAsyncInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + + Assert.assertEquals("Wrong packet in mask ", createPacketInMask().get(0), + deserializedMessage.getPacketInMask().get(0)); + Assert.assertEquals("Wrong packet in mask ", createPacketInMask().get(1), + deserializedMessage.getPacketInMask().get(1)); + Assert.assertEquals("Wrong port status mask ", createPortStatusMask().get(0), + deserializedMessage.getPortStatusMask().get(0)); + Assert.assertEquals("Wrong port status mask ", createPortStatusMask().get(1), + deserializedMessage.getPortStatusMask().get(1)); + Assert.assertEquals("Wrong flow removed mask ", createFlowRemowedMask().get(0), + deserializedMessage.getFlowRemovedMask().get(0)); + Assert.assertEquals("Wrong flow removed mask ", createFlowRemowedMask().get(1), + deserializedMessage.getFlowRemovedMask().get(1)); + + } + + private static List createPacketInMask() { + List masks = new ArrayList<>(); + PacketInMaskBuilder builder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + builder = new PacketInMaskBuilder(); + List packetInReasonList = new ArrayList<>(); + packetInReasonList.add(PacketInReason.OFPRNOMATCH); + packetInReasonList.add(PacketInReason.OFPRACTION); + packetInReasonList.add(PacketInReason.OFPRINVALIDTTL); + builder.setMask(packetInReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new PacketInMaskBuilder(); + packetInReasonList = new ArrayList<>(); + builder.setMask(packetInReasonList); + masks.add(builder.build()); + return masks; + } + + private static List createPortStatusMask() { + List masks = new ArrayList<>(); + PortStatusMaskBuilder builder; + builder = new PortStatusMaskBuilder(); + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + List portReasonList = new ArrayList<>(); + portReasonList.add(PortReason.OFPPRADD); + portReasonList.add(PortReason.OFPPRDELETE); + portReasonList.add(PortReason.OFPPRMODIFY); + builder.setMask(portReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new PortStatusMaskBuilder(); + portReasonList = new ArrayList<>(); + builder.setMask(portReasonList); + masks.add(builder.build()); + return masks; + } + + private static List createFlowRemowedMask() { + List masks = new ArrayList<>(); + FlowRemovedMaskBuilder builder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + builder = new FlowRemovedMaskBuilder(); + List flowRemovedReasonList = new ArrayList<>(); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRIDLETIMEOUT); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRHARDTIMEOUT); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRDELETE); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRGROUPDELETE); + builder.setMask(flowRemovedReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new FlowRemovedMaskBuilder(); + flowRemovedReasonList = new ArrayList<>(); + builder.setMask(flowRemovedReasonList); + masks.add(builder.build()); + return masks; + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java new file mode 100644 index 00000000..fe4b4bb8 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.protocol.impl.util.DefaultDeserializerFactoryTest; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.SetConfigInputMessageFactory}. + * @author giuseppex.petralia@intel.com + */ +public class SetConfigInputMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public SetConfigInputMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 9, SetConfigInput.class)); + } + + /** + * Testing {@link SetConfigInputMessageFactory} for correct header version. + */ + @Test + public void testVersions() { + List versions = new ArrayList<>(Arrays.asList( + EncodeConstants.OF10_VERSION_ID, + EncodeConstants.OF13_VERSION_ID, + EncodeConstants.OF14_VERSION_ID, + EncodeConstants.OF15_VERSION_ID + )); + ByteBuf bb = BufferHelper.buildBuffer("00 02 " + "00 0a"); + testHeaderVersions(versions, bb); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 02 " + "00 0a"); + SetConfigInput deserializedMessage = BufferHelper.deserialize(factory, bb); + + // Test Message + Assert.assertEquals("Wrong flags ", SwitchConfigFlag.forValue(2), deserializedMessage.getFlags()); + Assert.assertEquals("Wrong Miss Send len ", 10, deserializedMessage.getMissSendLen().intValue()); + } + +} \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java new file mode 100644 index 00000000..3b63748e --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class TableModInputMessageFactoryTest { + + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry desRegistry = new DeserializerRegistryImpl(); + desRegistry.init(); + factory = desRegistry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 17, TableModInput.class)); + + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("09 00 00 00 00 00 00 01"); + TableModInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + // Test Message + Assert.assertEquals("Wrong table id ", new TableId(9L), deserializedMessage.getTableId()); + Assert.assertEquals("Wrong config ", new TableConfig(true), deserializedMessage.getConfig()); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java index f397831d..d601cfa5 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java @@ -14,7 +14,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.MultipartReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.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.PortState; @@ -88,7 +88,7 @@ public void testMultipartReplyPortDesc() { Assert.assertEquals("Wrong port desc size", 2, message.getPorts().size()); Ports port = message.getPorts().get(0); Assert.assertEquals("Wrong portNo", 66051L, port.getPortNo().longValue()); - Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:B0:EB"), port.getHwAddr()); + Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:b0:eb"), port.getHwAddr()); Assert.assertEquals("Wrong portName", "Opendaylight", port.getName()); Assert.assertEquals("Wrong portConfig", new PortConfig(true, true, true, true), port.getConfig()); Assert.assertEquals("Wrong portState", new PortState(true, true, true), port.getState()); @@ -104,7 +104,7 @@ public void testMultipartReplyPortDesc() { Assert.assertEquals("Wrong maxSpeed", 128L, port.getMaxSpeed().longValue()); port = message.getPorts().get(1); Assert.assertEquals("Wrong portNo", 1L, port.getPortNo().longValue()); - Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:B0:EB"), port.getHwAddr()); + Assert.assertEquals("Wrong macAddress", new MacAddress("08:00:27:00:b0:eb"), port.getHwAddr()); Assert.assertEquals("Wrong portName", "Opendaylight", port.getName()); Assert.assertEquals("Wrong portConfig", new PortConfig(false, false, false, false), port.getConfig()); Assert.assertEquals("Wrong portState", new PortState(false, false, false), port.getState()); @@ -119,4 +119,4 @@ public void testMultipartReplyPortDesc() { Assert.assertEquals("Wrong currSpeed", 5L, port.getCurrSpeed().longValue()); Assert.assertEquals("Wrong maxSpeed", 6L, port.getMaxSpeed().longValue()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java new file mode 100644 index 00000000..cbe260d5 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class BarrierReplyMessageFactoryTest { + private static final byte MESSAGE_TYPE = 21; + private OFSerializer factory; + + @Before + public void startUp() throws Exception { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, BarrierOutput.class)); + + } + + @Test + public void testSerialize() throws Exception { + BarrierOutputBuilder builder = new BarrierOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + BarrierOutput message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 8); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java new file mode 100644 index 00000000..0f70b3ea --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class EchoOutputMessageFactoryTest { + private static final byte MESSAGE_TYPE = 3; + private OFSerializer factory; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, EchoOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + EchoOutputBuilder builder = new EchoOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + builder.setData(data); + EchoOutput message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 24); + byte[] readData = new byte[serializedBuffer.readableBytes()]; + serializedBuffer.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java new file mode 100644 index 00000000..22135bb6 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class EchoRequestMessageFactoryTest { + private static final byte MESSAGE_TYPE = 2; + EchoRequestMessage message; + private OFSerializer factory; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, EchoRequestMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + EchoRequestMessageBuilder builder = new EchoRequestMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + builder.setData(data); + EchoRequestMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 24); + byte[] readData = new byte[serializedBuffer.readableBytes()]; + serializedBuffer.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java new file mode 100644 index 00000000..929cbefe --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class ErrorMessageFactoryTest { + private static final byte MESSAGE_TYPE = 1; + private OFSerializer factory; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, ErrorMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + ErrorMessageBuilder builder = new ErrorMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(10); + builder.setCode(20); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + builder.setData(data); + ErrorMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 28); + Assert.assertEquals("Wrong Type", message.getType().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong Code", message.getCode().intValue(), serializedBuffer.readShort()); + byte[] readData = new byte[serializedBuffer.readableBytes()]; + serializedBuffer.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } +} 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 new file mode 100644 index 00000000..0ba90a23 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.phy.port._case.InPhyPortBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class FlowRemovedMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 11; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, FlowRemovedMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + FlowRemovedMessageBuilder builder = new FlowRemovedMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setCookie(BigInteger.valueOf(1234L)); + builder.setPriority(1234); + builder.setReason(FlowRemovedReason.forValue(2)); + builder.setTableId(new TableId(65L)); + builder.setDurationSec(1234L); + builder.setDurationNsec(1234L); + builder.setIdleTimeout(1234); + builder.setHardTimeout(1234); + builder.setPacketCount(BigInteger.valueOf(1234L)); + builder.setByteCount(BigInteger.valueOf(1234L)); + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(42L)); + inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build()); + entriesBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build()); + entries.add(entriesBuilder.build()); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ipEcnBuilder = new IpEcnBuilder(); + ipEcnBuilder.setEcn((short) 4); + ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build()); + entriesBuilder.setMatchEntryValue(ipEcnCaseBuilder.build()); + entries.add(entriesBuilder.build()); + matchBuilder.setMatchEntry(entries); + 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()); + Assert.assertEquals("Wrong reason", message.getReason().getIntValue(), serializedBuffer.readByte()); + Assert.assertEquals("Wrong Table ID", message.getTableId().getValue().intValue(), + serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong duration sec", message.getDurationSec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", message.getDurationNsec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong Idle timeout", message.getIdleTimeout().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong Hard timeout", message.getIdleTimeout().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong Packet count", message.getPacketCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", message.getByteCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong match type", 1, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong oxm class", 0x8000, serializedBuffer.readUnsignedShort()); + short fieldAndMask = serializedBuffer.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 42, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong oxm class", 0x8000, serializedBuffer.readUnsignedShort()); + fieldAndMask = serializedBuffer.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 4, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(7); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java new file mode 100644 index 00000000..f645944b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.FlowRemovedMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PacketInMaskBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMask; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.async.body.grouping.PortStatusMaskBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetAsyncReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 27; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetAsyncOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetAsyncOutputBuilder builder = new GetAsyncOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPacketInMask(createPacketInMask()); + builder.setPortStatusMask(createPortStatusMask()); + builder.setFlowRemovedMask(createFlowRemowedMask()); + GetAsyncOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 32); + Assert.assertEquals("Wrong packetInMask", 7, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong packetInMask", 0, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong portStatusMask", 7, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong portStatusMask", 0, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong flowRemovedMask", 15, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong flowRemovedMask", 0, serializedBuffer.readUnsignedInt()); + } + + private static List createPacketInMask() { + List masks = new ArrayList<>(); + PacketInMaskBuilder builder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + builder = new PacketInMaskBuilder(); + List packetInReasonList = new ArrayList<>(); + packetInReasonList.add(PacketInReason.OFPRNOMATCH); + packetInReasonList.add(PacketInReason.OFPRACTION); + packetInReasonList.add(PacketInReason.OFPRINVALIDTTL); + builder.setMask(packetInReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new PacketInMaskBuilder(); + packetInReasonList = new ArrayList<>(); + builder.setMask(packetInReasonList); + masks.add(builder.build()); + return masks; + } + + private static List createPortStatusMask() { + List masks = new ArrayList<>(); + PortStatusMaskBuilder builder; + builder = new PortStatusMaskBuilder(); + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + List portReasonList = new ArrayList<>(); + portReasonList.add(PortReason.OFPPRADD); + portReasonList.add(PortReason.OFPPRDELETE); + portReasonList.add(PortReason.OFPPRMODIFY); + builder.setMask(portReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new PortStatusMaskBuilder(); + portReasonList = new ArrayList<>(); + builder.setMask(portReasonList); + masks.add(builder.build()); + return masks; + } + + private static List createFlowRemowedMask() { + List masks = new ArrayList<>(); + FlowRemovedMaskBuilder builder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + builder = new FlowRemovedMaskBuilder(); + List flowRemovedReasonList = new ArrayList<>(); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRIDLETIMEOUT); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRHARDTIMEOUT); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRDELETE); + flowRemovedReasonList.add(FlowRemovedReason.OFPRRGROUPDELETE); + builder.setMask(flowRemovedReasonList); + masks.add(builder.build()); + // OFPCR_ROLE_SLAVE + builder = new FlowRemovedMaskBuilder(); + flowRemovedReasonList = new ArrayList<>(); + builder.setMask(flowRemovedReasonList); + masks.add(builder.build()); + return masks; + } + + @Test + public void testSetAsyncInputWithNullMasks() throws Exception { + GetAsyncOutputBuilder builder = new GetAsyncOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPacketInMask(null); + builder.setPortStatusMask(null); + builder.setFlowRemovedMask(null); + GetAsyncOutput message = builder.build(); + GetAsyncReplyMessageFactory serializer = new GetAsyncReplyMessageFactory(); + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 8); + Assert.assertTrue("Unexpected data", serializedBuffer.readableBytes() == 0); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java new file mode 100644 index 00000000..a6d00adf --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFlag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class GetConfigReplyMessageFactoryTest { + private static final byte MESSAGE_TYPE = 8; + private OFSerializer factory; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetConfigOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetConfigOutputBuilder builder = new GetConfigOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(SwitchConfigFlag.forValue(2)); + builder.setMissSendLen(20); + GetConfigOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 12); + Assert.assertEquals("Wrong Type", message.getFlags().getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong Code", message.getMissSendLen().intValue(), serializedBuffer.readShort()); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java new file mode 100644 index 00000000..271933d3 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder; + +public class GetFeaturesOutputFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 6; + private static final byte PADDING = 2; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetFeaturesOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetFeaturesOutputBuilder builder = new GetFeaturesOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setDatapathId(BigInteger.valueOf(1234L)); + builder.setBuffers(1234L); + builder.setTables((short) 12); + builder.setAuxiliaryId((short) 12); + builder.setCapabilities(new Capabilities(true, false, true, false, true, false, true)); + builder.setReserved(1234L); + GetFeaturesOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 32); + Assert.assertEquals("Wrong DatapathId", message.getDatapathId().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Buffer ID", message.getBuffers().longValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong tables", message.getTables().shortValue(), serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong auxiliary ID", message.getAuxiliaryId().shortValue(), + serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(PADDING); + Assert.assertEquals("Wrong Capabilities", message.getCapabilities(), + createCapabilities(serializedBuffer.readInt())); + Assert.assertEquals("Wrong reserved", message.getReserved().longValue(), serializedBuffer.readInt()); + } + + private static Capabilities createCapabilities(int input) { + final Boolean one = (input & (1 << 0)) > 0; + final Boolean two = (input & (1 << 1)) > 0; + final Boolean three = (input & (1 << 2)) > 0; + final Boolean four = (input & (1 << 3)) > 0; + final Boolean five = (input & (1 << 5)) > 0; + final Boolean six = (input & (1 << 6)) > 0; + final Boolean seven = (input & (1 << 8)) > 0; + return new Capabilities(one, four, five, seven, three, six, two); + } +} 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/HelloInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java index d947b3fd..e9319a96 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java @@ -38,7 +38,7 @@ */ public class HelloInputMessageFactoryTest { - private static final Logger LOGGER = LoggerFactory.getLogger(HelloInputMessageFactoryTest.class); + private static final Logger LOG = LoggerFactory.getLogger(HelloInputMessageFactoryTest.class); private SerializerRegistry registry; private OFSerializer helloFactory; @@ -84,8 +84,8 @@ public void testWith4BitVersionBitmap() throws Exception { ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); helloFactory.serialize(message, out); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("bytebuf: {}", ByteBufUtils.byteBufToHexString(out)); + if (LOG.isDebugEnabled()) { + LOG.debug("bytebuf: {}", ByteBufUtils.byteBufToHexString(out)); } BufferHelper.checkHeaderV13(out, (byte) 0, 16); @@ -110,8 +110,8 @@ public void testWith64BitVersionBitmap() throws Exception { ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); helloFactory.serialize(message, out); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("bytebuf: ", ByteBufUtils.byteBufToHexString(out)); + if (LOG.isDebugEnabled()) { + LOG.debug("bytebuf: ", ByteBufUtils.byteBufToHexString(out)); } BufferHelper.checkHeaderV13(out, (byte) 0, 24); @@ -146,7 +146,7 @@ private static List createComparationElement(int lengthOfBitmap) { booleanList.add(false); } } - LOGGER.debug("boolsize {}", booleanList.size()); + LOG.debug("boolsize {}", booleanList.size()); elementsBuilder.setType(HelloElementType.forValue(1)); elementsBuilder.setVersionBitmap(booleanList); elementsList.add(elementsBuilder.build()); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactoryTest.java new file mode 100644 index 00000000..0db9c8da --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactoryTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class HelloMessageFactoryTest { + private static final byte MESSAGE_TYPE = 0; + private OFSerializer factory; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, HelloMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + HelloMessageBuilder builder = new HelloMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + HelloMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 8); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java new file mode 100644 index 00000000..a6e18bde --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java @@ -0,0 +1,1496 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.augments.rev150225.ActionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.InstructionRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.OxmRelatedTableFeaturePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIds; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.table.features.properties.container.table.feature.properties.NextTableIdsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopPbbCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTtlCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.vlan._case.PushVlanActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.ttl._case.SetNwTtlActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice._goto.table._case.GotoTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.meter._case.MeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.actions._case.WriteActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.metadata._case.WriteMetadataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ActionType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupTypes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterBandTypeBitmap; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesPropType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpProto; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.phy.port._case.InPhyPortBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsListBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDropCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandDscpRemarkCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.drop._case.MeterBandDropBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.meter.band.dscp.remark._case.MeterBandDscpRemarkBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.MultipartReplyBody; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyGroupFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterConfigCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyMeterFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableFeaturesCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.MultipartReplyGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.GroupStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group._case.multipart.reply.group.group.stats.BucketStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.MultipartReplyGroupDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.desc._case.multipart.reply.group.desc.GroupDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.MultipartReplyMeterBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.MeterStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter._case.multipart.reply.meter.meter.stats.MeterBandStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.MultipartReplyMeterConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.MeterConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.Bands; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.config._case.multipart.reply.meter.config.meter.config.BandsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.meter.features._case.MultipartReplyMeterFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDesc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.MultipartReplyPortDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.Ports; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.desc._case.multipart.reply.port.desc.PortsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.MultipartReplyTableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeatures; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table.features._case.multipart.reply.table.features.TableFeaturesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeaturePropertiesBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class MultipartReplyMessageFactoryTest { + private static final byte MESSAGE_TYPE = 19; + private static final byte PADDING = 4; + + private OFSerializer factory; + + @Before + public void startUp() throws Exception { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartReplyMessage.class)); + } + + @Test + public void testMultipartRequestTableFeaturesMessageFactory() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(12)); + MultipartReplyTableFeaturesCaseBuilder caseBuilder = new MultipartReplyTableFeaturesCaseBuilder(); + MultipartReplyTableFeaturesBuilder featuresBuilder = new MultipartReplyTableFeaturesBuilder(); + List tableFeaturesList = new ArrayList<>(); + TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + tableFeaturesBuilder.setMetadataMatch(new byte[] { 0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01 }); + tableFeaturesBuilder.setMetadataWrite(new byte[] { 0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01 }); + tableFeaturesBuilder.setConfig(new TableConfig(true)); + tableFeaturesBuilder.setMaxEntries(65L); + List properties = new ArrayList<>(); + TableFeaturePropertiesBuilder propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLES); + NextTableRelatedTableFeaturePropertyBuilder nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder(); + List nextIds = new ArrayList<>(); + nextIds.add(new NextTableIdsBuilder().setTableId((short) 1).build()); + nextIds.add(new NextTableIdsBuilder().setTableId((short) 2).build()); + nextPropBuilder.setNextTableIds(nextIds); + propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS); + nextPropBuilder = new NextTableRelatedTableFeaturePropertyBuilder(); + nextIds = new ArrayList<>(); + nextPropBuilder.setNextTableIds(nextIds); + propBuilder.addAugmentation(NextTableRelatedTableFeatureProperty.class, nextPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONS); + InstructionRelatedTableFeaturePropertyBuilder insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder(); + List insIds = new ArrayList<>(); + InstructionBuilder insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new WriteActionsCaseBuilder().build()); + insIds.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new GotoTableCaseBuilder().build()); + insIds.add(insBuilder.build()); + insPropBuilder.setInstruction(insIds); + propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS); + insPropBuilder = new InstructionRelatedTableFeaturePropertyBuilder(); + insIds = new ArrayList<>(); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new WriteMetadataCaseBuilder().build()); + insIds.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new ApplyActionsCaseBuilder().build()); + insIds.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new MeterCaseBuilder().build()); + insIds.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new ClearActionsCaseBuilder().build()); + insIds.add(insBuilder.build()); + insBuilder = new InstructionBuilder(); + insBuilder.setInstructionChoice(new GotoTableCaseBuilder().build()); + insIds.add(insBuilder.build()); + insPropBuilder.setInstruction(insIds); + propBuilder.addAugmentation(InstructionRelatedTableFeatureProperty.class, insPropBuilder.build()); + properties.add(propBuilder.build()); + tableFeaturesBuilder.setTableFeatureProperties(properties); + tableFeaturesList.add(tableFeaturesBuilder.build()); + tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + byte[] metadataMatch = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01 }; + tableFeaturesBuilder.setMetadataMatch(metadataMatch); + byte[] metadataWrite = new byte[] { 0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01 }; + tableFeaturesBuilder.setMetadataWrite(metadataWrite); + tableFeaturesBuilder.setConfig(new TableConfig(true)); + tableFeaturesBuilder.setMaxEntries(67L); + properties = new ArrayList<>(); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONS); + ActionRelatedTableFeaturePropertyBuilder actBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new OutputActionCaseBuilder().build()); + actions.add(actionBuilder.build()); + actBuilder.setAction(actions); + propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS); + actBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + actions = new ArrayList<>(); + actBuilder.setAction(actions); + propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONS); + actBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + actions = new ArrayList<>(); + actBuilder.setAction(actions); + propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS); + actBuilder = new ActionRelatedTableFeaturePropertyBuilder(); + actions = new ArrayList<>(); + actBuilder.setAction(actions); + propBuilder.addAugmentation(ActionRelatedTableFeatureProperty.class, actBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTMATCH); + OxmRelatedTableFeaturePropertyBuilder oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPort.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTWILDCARDS); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELD); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpProto.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + entries.add(entriesBuilder.build()); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS); + oxmBuilder = new OxmRelatedTableFeaturePropertyBuilder(); + entries = new ArrayList<>(); + oxmBuilder.setMatchEntry(entries); + propBuilder.addAugmentation(OxmRelatedTableFeatureProperty.class, oxmBuilder.build()); + properties.add(propBuilder.build()); + tableFeaturesBuilder.setTableFeatureProperties(properties); + tableFeaturesList.add(tableFeaturesBuilder.build()); + featuresBuilder.setTableFeatures(tableFeaturesList); + caseBuilder.setMultipartReplyTableFeatures(featuresBuilder.build()); + builder.setMultipartReplyBody(caseBuilder.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 520); + Assert.assertEquals("Wrong type", MultipartType.OFPMPTABLEFEATURES.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + + Assert.assertEquals("Wrong length", 232, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong registry-id", 8, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(serializedBuffer, 32)); + byte[] metadataMatchOutput = new byte[metadataMatch.length]; + serializedBuffer.readBytes(metadataMatchOutput); + Assert.assertArrayEquals("Wrong metadata-match", new byte[] { 0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01 }, + metadataMatchOutput); + serializedBuffer.skipBytes(64 - metadataMatch.length); + byte[] metadataWriteOutput = new byte[metadataWrite.length]; + serializedBuffer.readBytes(metadataWriteOutput); + Assert.assertArrayEquals("Wrong metadata-write", new byte[] { 0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01 }, + metadataWriteOutput); + serializedBuffer.skipBytes(64 - metadataWrite.length); + Assert.assertEquals("Wrong config", 1, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 65, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 2, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 6, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong next-registry-id", 1, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong next-registry-id", 2, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong property type", 3, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 0, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 3, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 1, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 24, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 2, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 6, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 5, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong length", 272, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong registry-id", 8, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(serializedBuffer, 32)); + metadataMatchOutput = new byte[metadataMatch.length]; + serializedBuffer.readBytes(metadataMatchOutput); + serializedBuffer.skipBytes(64 - metadataMatch.length); + Assert.assertArrayEquals("Wrong metadata-match", new byte[] { 0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01 }, + metadataMatchOutput); + metadataWriteOutput = new byte[metadataWrite.length]; + serializedBuffer.readBytes(metadataWriteOutput); + serializedBuffer.skipBytes(64 - metadataWrite.length); + Assert.assertArrayEquals("Wrong metadata-write", new byte[] { 0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01 }, + metadataWriteOutput); + Assert.assertEquals("Wrong config", 1, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 67, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 8, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 0, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property type", 5, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 6, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 7, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 8, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 2, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 0x8000, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 0, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 10, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 12, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 13, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 14, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 20, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 0x8000, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 18, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong property type", 15, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(4); + Assert.assertTrue("Unread data", serializedBuffer.readableBytes() == 0); + } + + @Test + public void testPortDescSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(13)); + MultipartReplyPortDescCaseBuilder portDescCase = new MultipartReplyPortDescCaseBuilder(); + MultipartReplyPortDescBuilder portDesc = new MultipartReplyPortDescBuilder(); + portDesc.setPorts(createPortList()); + portDescCase.setMultipartReplyPortDesc(portDesc.build()); + builder.setMultipartReplyBody(portDescCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 80); + Assert.assertEquals("Wrong type", MultipartType.OFPMPPORTDESC.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyPortDescCase body = (MultipartReplyPortDescCase) message.getMultipartReplyBody(); + MultipartReplyPortDesc messageOutput = body.getMultipartReplyPortDesc(); + Ports port = messageOutput.getPorts().get(0); + Assert.assertEquals("Wrong PortNo", port.getPortNo().intValue(), serializedBuffer.readUnsignedInt()); + serializedBuffer.skipBytes(4); + byte[] address = new byte[6]; + serializedBuffer.readBytes(address); + Assert.assertEquals("Wrong MacAddress", port.getHwAddr().getValue().toLowerCase(), + new MacAddress(ByteBufUtils.macAddressToString(address)).getValue().toLowerCase()); + serializedBuffer.skipBytes(2); + byte[] name = new byte[16]; + serializedBuffer.readBytes(name); + Assert.assertEquals("Wrong name", port.getName(), new String(name).trim()); + Assert.assertEquals("Wrong config", port.getConfig(), createPortConfig(serializedBuffer.readInt())); + Assert.assertEquals("Wrong state", port.getState(), createPortState(serializedBuffer.readInt())); + Assert.assertEquals("Wrong current", port.getCurrentFeatures(), createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong advertised", port.getAdvertisedFeatures(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong supported", port.getSupportedFeatures(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong peer", port.getPeerFeatures(), createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong Current speed", port.getCurrSpeed().longValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong Max speed", port.getMaxSpeed().longValue(), serializedBuffer.readInt()); + } + + @Test + public void testMeterFeaturesSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(11)); + MultipartReplyMeterFeaturesCaseBuilder meterFeaturesCase = new MultipartReplyMeterFeaturesCaseBuilder(); + MultipartReplyMeterFeaturesBuilder meterFeatures = new MultipartReplyMeterFeaturesBuilder(); + meterFeatures.setMaxMeter(1L); + meterFeatures.setBandTypes(new MeterBandTypeBitmap(true, false)); + meterFeatures.setCapabilities(new MeterFlags(true, false, true, false)); + meterFeatures.setMaxBands((short) 1); + meterFeatures.setMaxColor((short) 1); + meterFeaturesCase.setMultipartReplyMeterFeatures(meterFeatures.build()); + builder.setMultipartReplyBody(meterFeaturesCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 30); + Assert.assertEquals("Wrong type", MultipartType.OFPMPMETERFEATURES.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyMeterFeaturesCase body = (MultipartReplyMeterFeaturesCase) message.getMultipartReplyBody(); + MultipartReplyMeterFeatures messageOutput = body.getMultipartReplyMeterFeatures(); + Assert.assertEquals("Wrong max meter", messageOutput.getMaxMeter().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong band type", messageOutput.getBandTypes(), + createMeterBandTypeBitmap(serializedBuffer.readInt())); + Assert.assertEquals("Wrong capabilities", messageOutput.getCapabilities(), + createMeterFlags(serializedBuffer.readShort())); + Assert.assertEquals("Wrong max bands", messageOutput.getMaxBands().shortValue(), + serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong max color", messageOutput.getMaxColor().shortValue(), + serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(2); + } + + @Test + public void testMeterConfigSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(10)); + MultipartReplyMeterConfigCaseBuilder meterConfigCase = new MultipartReplyMeterConfigCaseBuilder(); + MultipartReplyMeterConfigBuilder meterConfigBuilder = new MultipartReplyMeterConfigBuilder(); + meterConfigBuilder.setMeterConfig(createMeterConfig()); + meterConfigCase.setMultipartReplyMeterConfig(meterConfigBuilder.build()); + builder.setMultipartReplyBody(meterConfigCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 48); + Assert.assertEquals("Wrong type", MultipartType.OFPMPMETERCONFIG.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyMeterConfigCase body = (MultipartReplyMeterConfigCase) message.getMultipartReplyBody(); + MultipartReplyMeterConfig messageOutput = body.getMultipartReplyMeterConfig(); + MeterConfig meterConfig = messageOutput.getMeterConfig().get(0); + Assert.assertEquals("Wrong len", 32, serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", meterConfig.getFlags(), createMeterFlags(serializedBuffer.readShort())); + Assert.assertEquals("Wrong meterId", meterConfig.getMeterId().getValue().intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong bands", meterConfig.getBands(), decodeBandsList(serializedBuffer)); + } + + @Test + public void testMeterSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(9)); + MultipartReplyMeterCaseBuilder meterCase = new MultipartReplyMeterCaseBuilder(); + MultipartReplyMeterBuilder meter = new MultipartReplyMeterBuilder(); + meter.setMeterStats(createMeterStats()); + meterCase.setMultipartReplyMeter(meter.build()); + builder.setMultipartReplyBody(meterCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 74); + Assert.assertEquals("Wrong type", MultipartType.OFPMPMETER.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyMeterCase body = (MultipartReplyMeterCase) message.getMultipartReplyBody(); + MultipartReplyMeter messageOutput = body.getMultipartReplyMeter(); + MeterStats meterStats = messageOutput.getMeterStats().get(0); + Assert.assertEquals("Wrong meterId", meterStats.getMeterId().getValue().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong len", 58, serializedBuffer.readInt()); + serializedBuffer.skipBytes(6); + Assert.assertEquals("Wrong flow count", meterStats.getFlowCount().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong packet in count", meterStats.getPacketInCount().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong byte in count", meterStats.getByteInCount().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong duration sec", meterStats.getDurationSec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", meterStats.getDurationNsec().intValue(), serializedBuffer.readInt()); + MeterBandStats meterBandStats = meterStats.getMeterBandStats().get(0); + Assert.assertEquals("Wrong packet in count", meterBandStats.getPacketBandCount().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong byte in count", meterBandStats.getByteBandCount().longValue(), + serializedBuffer.readLong()); + } + + @Test + public void testGroupFeaturesSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(8)); + MultipartReplyGroupFeaturesCaseBuilder featureCase = new MultipartReplyGroupFeaturesCaseBuilder(); + MultipartReplyGroupFeaturesBuilder feature = new MultipartReplyGroupFeaturesBuilder(); + feature.setTypes(new GroupTypes(true, false, true, false)); + feature.setCapabilities(new GroupCapabilities(true, false, true, true)); + List maxGroups = new ArrayList<>(); + maxGroups.add(1L); + maxGroups.add(2L); + maxGroups.add(3L); + maxGroups.add(4L); + feature.setMaxGroups(maxGroups); + feature.setActionsBitmap(createActionType()); + featureCase.setMultipartReplyGroupFeatures(feature.build()); + builder.setMultipartReplyBody(featureCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 56); + Assert.assertEquals("Wrong type", MultipartType.OFPMPGROUPFEATURES.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyGroupFeaturesCase body = (MultipartReplyGroupFeaturesCase) message.getMultipartReplyBody(); + MultipartReplyGroupFeatures messageOutput = body.getMultipartReplyGroupFeatures(); + Assert.assertEquals("Wrong type", messageOutput.getTypes(), createGroupTypes(serializedBuffer.readInt())); + Assert.assertEquals("Wrong capabilities", messageOutput.getCapabilities(), + createGroupCapabilities(serializedBuffer.readInt())); + Assert.assertEquals("Wrong max groups", messageOutput.getMaxGroups().get(0).intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong max groups", messageOutput.getMaxGroups().get(1).intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong max groups", messageOutput.getMaxGroups().get(2).intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong max groups", messageOutput.getMaxGroups().get(3).intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong actions", messageOutput.getActionsBitmap().get(0), + createActionType(serializedBuffer.readInt())); + Assert.assertEquals("Wrong actions", messageOutput.getActionsBitmap().get(1), + createActionType(serializedBuffer.readInt())); + Assert.assertEquals("Wrong actions", messageOutput.getActionsBitmap().get(2), + createActionType(serializedBuffer.readInt())); + Assert.assertEquals("Wrong actions", messageOutput.getActionsBitmap().get(3), + createActionType(serializedBuffer.readInt())); + } + + @Test + public void testGroupDescSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(7)); + MultipartReplyGroupDescCaseBuilder groupCase = new MultipartReplyGroupDescCaseBuilder(); + MultipartReplyGroupDescBuilder group = new MultipartReplyGroupDescBuilder(); + group.setGroupDesc(createGroupDesc()); + groupCase.setMultipartReplyGroupDesc(group.build()); + builder.setMultipartReplyBody(groupCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 64); + Assert.assertEquals("Wrong type", MultipartType.OFPMPGROUPDESC.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyGroupDescCase body = (MultipartReplyGroupDescCase) message.getMultipartReplyBody(); + MultipartReplyGroupDesc messageOutput = body.getMultipartReplyGroupDesc(); + GroupDesc groupDesc = messageOutput.getGroupDesc().get(0); + Assert.assertEquals("Wrong length", 48, serializedBuffer.readShort()); + Assert.assertEquals("Wrong type", groupDesc.getType().getIntValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + Assert.assertEquals("Wrong group id", groupDesc.getGroupId().getValue().intValue(), serializedBuffer.readInt()); + BucketsList bucketList = groupDesc.getBucketsList().get(0); + Assert.assertEquals("Wrong length", 40, serializedBuffer.readShort()); + Assert.assertEquals("Wrong weight", bucketList.getWeight().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong watch port", bucketList.getWatchPort().getValue().intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong watch group", bucketList.getWatchGroup().intValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(4); + + Assert.assertEquals("Wrong action type", 0, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 45, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong action type", 55, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(6); + Assert.assertEquals("Wrong action type", 23, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 64, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(3); + Assert.assertTrue("Not all data were read", serializedBuffer.readableBytes() == 0); + } + + @Test + public void testGroupSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(6)); + MultipartReplyGroupCaseBuilder groupCase = new MultipartReplyGroupCaseBuilder(); + MultipartReplyGroupBuilder group = new MultipartReplyGroupBuilder(); + group.setGroupStats(createGroupStats()); + groupCase.setMultipartReplyGroup(group.build()); + builder.setMultipartReplyBody(groupCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 72); + Assert.assertEquals("Wrong type", MultipartType.OFPMPGROUP.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyGroupCase body = (MultipartReplyGroupCase) message.getMultipartReplyBody(); + MultipartReplyGroup messageOutput = body.getMultipartReplyGroup(); + GroupStats groupStats = messageOutput.getGroupStats().get(0); + Assert.assertEquals("Wrong length", 56, serializedBuffer.readShort()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong group id", groupStats.getGroupId().getValue().intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong ref count", groupStats.getRefCount().intValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong Packet count", groupStats.getPacketCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", groupStats.getByteCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong duration sec", groupStats.getDurationSec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", groupStats.getDurationNsec().intValue(), serializedBuffer.readInt()); + BucketStats bucketStats = groupStats.getBucketStats().get(0); + Assert.assertEquals("Wrong Packet count", bucketStats.getPacketCount().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", bucketStats.getByteCount().longValue(), serializedBuffer.readLong()); + } + + @Test + public void testQueueSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(5)); + MultipartReplyQueueCaseBuilder queueCase = new MultipartReplyQueueCaseBuilder(); + MultipartReplyQueueBuilder queue = new MultipartReplyQueueBuilder(); + queue.setQueueStats(createQueueStats()); + queueCase.setMultipartReplyQueue(queue.build()); + builder.setMultipartReplyBody(queueCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 56); + Assert.assertEquals("Wrong type", MultipartType.OFPMPQUEUE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyQueueCase body = (MultipartReplyQueueCase) message.getMultipartReplyBody(); + MultipartReplyQueue messageOutput = body.getMultipartReplyQueue(); + QueueStats queueStats = messageOutput.getQueueStats().get(0); + Assert.assertEquals("Wrong PortNo", queueStats.getPortNo().intValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong queue id", queueStats.getQueueId().intValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong tx bytes", queueStats.getTxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx packets", queueStats.getTxPackets().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx errors", queueStats.getTxErrors().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong duration sec", queueStats.getDurationSec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", queueStats.getDurationNsec().intValue(), serializedBuffer.readInt()); + } + + @Test + public void testPortStatsSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(4)); + MultipartReplyPortStatsCaseBuilder portStatsCase = new MultipartReplyPortStatsCaseBuilder(); + MultipartReplyPortStatsBuilder portStats = new MultipartReplyPortStatsBuilder(); + portStats.setPortStats(createPortStats()); + portStatsCase.setMultipartReplyPortStats(portStats.build()); + builder.setMultipartReplyBody(portStatsCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 128); + Assert.assertEquals("Wrong type", MultipartType.OFPMPPORTSTATS.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyPortStatsCase body = (MultipartReplyPortStatsCase) message.getMultipartReplyBody(); + MultipartReplyPortStats messageOutput = body.getMultipartReplyPortStats(); + PortStats portStatsOutput = messageOutput.getPortStats().get(0); + Assert.assertEquals("Wrong port no", portStatsOutput.getPortNo().intValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(4); + Assert.assertEquals("Wrong rx packets", portStatsOutput.getRxPackets().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx packets", portStatsOutput.getTxPackets().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx bytes", portStatsOutput.getRxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx bytes", portStatsOutput.getTxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx dropped", portStatsOutput.getRxDropped().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx dropped", portStatsOutput.getTxDropped().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx errors", portStatsOutput.getRxErrors().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx errors", portStatsOutput.getTxErrors().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx frame err", portStatsOutput.getRxFrameErr().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx over err", portStatsOutput.getRxOverErr().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx crc err", portStatsOutput.getRxCrcErr().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong collisions", portStatsOutput.getCollisions().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong duration sec", portStatsOutput.getDurationSec().intValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", portStatsOutput.getDurationNsec().intValue(), + serializedBuffer.readInt()); + } + + @Test + public void testTableSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(3)); + MultipartReplyTableCaseBuilder tableCase = new MultipartReplyTableCaseBuilder(); + MultipartReplyTableBuilder table = new MultipartReplyTableBuilder(); + table.setTableStats(createTableStats()); + tableCase.setMultipartReplyTable(table.build()); + builder.setMultipartReplyBody(tableCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 40); + Assert.assertEquals("Wrong type", MultipartType.OFPMPTABLE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyTableCase body = (MultipartReplyTableCase) message.getMultipartReplyBody(); + MultipartReplyTable messageOutput = body.getMultipartReplyTable(); + TableStats tableStats = messageOutput.getTableStats().get(0); + Assert.assertEquals("Wrong tableId", tableStats.getTableId().shortValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(3); + Assert.assertEquals("Wrong active count", tableStats.getActiveCount().longValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong lookup count", tableStats.getLookupCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong matched count", tableStats.getMatchedCount().longValue(), + serializedBuffer.readLong()); + } + + @Test + public void testAggregateSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(2)); + MultipartReplyAggregateCaseBuilder aggregateCase = new MultipartReplyAggregateCaseBuilder(); + MultipartReplyAggregateBuilder aggregate = new MultipartReplyAggregateBuilder(); + aggregate.setPacketCount(BigInteger.valueOf(1L)); + aggregate.setByteCount(BigInteger.valueOf(1L)); + aggregate.setFlowCount(1L); + aggregateCase.setMultipartReplyAggregate(aggregate.build()); + builder.setMultipartReplyBody(aggregateCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 40); + Assert.assertEquals("Wrong type", MultipartType.OFPMPAGGREGATE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + MultipartReplyAggregateCase body = (MultipartReplyAggregateCase) message.getMultipartReplyBody(); + MultipartReplyAggregate messageOutput = body.getMultipartReplyAggregate(); + Assert.assertEquals("Wrong Packet count", messageOutput.getPacketCount().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", messageOutput.getByteCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Flow count", messageOutput.getFlowCount().longValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(4); + } + + @Test + public void testFlowSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(1)); + MultipartReplyFlowCaseBuilder flowCase = new MultipartReplyFlowCaseBuilder(); + MultipartReplyFlowBuilder flow = new MultipartReplyFlowBuilder(); + flow.setFlowStats(createFlowStats()); + flowCase.setMultipartReplyFlow(flow.build()); + builder.setMultipartReplyBody(flowCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 192); + Assert.assertEquals("Wrong type", MultipartType.OFPMPFLOW.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + testFlowBody(message.getMultipartReplyBody(), serializedBuffer); + } + + @Test + public void testDescSerialize() throws Exception { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(0)); + MultipartReplyDescCaseBuilder descCase = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder desc = new MultipartReplyDescBuilder(); + desc.setMfrDesc("Test"); + desc.setHwDesc("Test"); + desc.setSwDesc("Test"); + desc.setSerialNum("12345"); + desc.setDpDesc("Test"); + descCase.setMultipartReplyDesc(desc.build()); + builder.setMultipartReplyBody(descCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 1072); + Assert.assertEquals("Wrong type", MultipartType.OFPMPDESC.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + serializedBuffer.skipBytes(PADDING); + Assert.assertEquals("Wrong desc body", message.getMultipartReplyBody(), decodeDescBody(serializedBuffer)); + } + + private static void testFlowBody(MultipartReplyBody body, ByteBuf output) { + MultipartReplyFlowCase flowCase = (MultipartReplyFlowCase) body; + MultipartReplyFlow flow = flowCase.getMultipartReplyFlow(); + FlowStats flowStats = flow.getFlowStats().get(0); + Assert.assertEquals("Wrong length", 176, output.readShort()); + Assert.assertEquals("Wrong Table ID", flowStats.getTableId().intValue(), output.readUnsignedByte()); + output.skipBytes(1); + Assert.assertEquals("Wrong duration sec", flowStats.getDurationSec().intValue(), output.readInt()); + Assert.assertEquals("Wrong duration nsec", flowStats.getDurationNsec().intValue(), output.readInt()); + Assert.assertEquals("Wrong priority", flowStats.getPriority().intValue(), output.readShort()); + Assert.assertEquals("Wrong idle timeout", flowStats.getIdleTimeout().intValue(), output.readShort()); + Assert.assertEquals("Wrong hard timeout", flowStats.getHardTimeout().intValue(), output.readShort()); + output.skipBytes(6); + Assert.assertEquals("Wrong cookie", flowStats.getCookie().longValue(), output.readLong()); + Assert.assertEquals("Wrong Packet count", flowStats.getPacketCount().longValue(), output.readLong()); + Assert.assertEquals("Wrong Byte count", flowStats.getByteCount().longValue(), output.readLong()); + Assert.assertEquals("Wrong match type", 1, output.readUnsignedShort()); + output.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong oxm class", 0x8000, output.readUnsignedShort()); + short fieldAndMask = output.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1); + output.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 42, output.readUnsignedInt()); + Assert.assertEquals("Wrong oxm class", 0x8000, output.readUnsignedShort()); + fieldAndMask = output.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1); + output.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 4, output.readUnsignedByte()); + output.skipBytes(7); + Assert.assertEquals("Wrong instruction type", 1, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction table-id", 5, output.readUnsignedByte()); + output.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 2, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 24, output.readUnsignedShort()); + output.skipBytes(4); + byte[] actual = new byte[8]; + output.readBytes(actual); + Assert.assertEquals("Wrong instruction metadata", "00 01 02 03 04 05 06 07", + ByteBufUtils.bytesToHexString(actual)); + actual = new byte[8]; + output.readBytes(actual); + Assert.assertEquals("Wrong instruction metadata-mask", "07 06 05 04 03 02 01 00", + ByteBufUtils.bytesToHexString(actual)); + Assert.assertEquals("Wrong instruction type", 5, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, output.readUnsignedShort()); + output.skipBytes(4); + Assert.assertEquals("Wrong instruction type", 6, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction meter-id", 42, output.readUnsignedInt()); + Assert.assertEquals("Wrong instruction type", 3, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 32, output.readUnsignedShort()); + output.skipBytes(4); + Assert.assertEquals("Wrong action type", 0, output.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, output.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 45, output.readUnsignedInt()); + Assert.assertEquals("Wrong action type", 55, output.readUnsignedShort()); + output.skipBytes(6); + Assert.assertEquals("Wrong action type", 23, output.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, output.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 64, output.readUnsignedByte()); + output.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 4, output.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 24, output.readUnsignedShort()); + output.skipBytes(4); + Assert.assertEquals("Wrong action type", 17, output.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, output.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 14, output.readUnsignedShort()); + output.skipBytes(2); + Assert.assertEquals("Wrong action type", 27, output.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, output.readUnsignedShort()); + output.skipBytes(4); + Assert.assertTrue("Not all data were read", output.readableBytes() == 0); + } + + private static List createPortList() { + PortsBuilder builder = new PortsBuilder(); + builder.setPortNo(1L); + builder.setHwAddr(new MacAddress("94:de:80:a6:61:40")); + builder.setName("Port name"); + builder.setConfig(new PortConfig(true, false, true, false)); + builder.setState(new PortState(true, false, true)); + builder.setCurrentFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setAdvertisedFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setSupportedFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setPeerFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, true, + false, true, false, true, false)); + builder.setCurrSpeed(1234L); + builder.setMaxSpeed(1234L); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static PortConfig createPortConfig(long input) { + final Boolean _portDown = ((input) & (1 << 0)) > 0; + final Boolean _noRecv = ((input) & (1 << 2)) > 0; + final Boolean _noFwd = ((input) & (1 << 5)) > 0; + final Boolean _noPacketIn = ((input) & (1 << 6)) > 0; + return new PortConfig(_noFwd, _noPacketIn, _noRecv, _portDown); + } + + private static PortFeatures createPortFeatures(long input) { + final Boolean _10mbHd = ((input) & (1 << 0)) > 0; + final Boolean _10mbFd = ((input) & (1 << 1)) > 0; + final Boolean _100mbHd = ((input) & (1 << 2)) > 0; + final Boolean _100mbFd = ((input) & (1 << 3)) > 0; + final Boolean _1gbHd = ((input) & (1 << 4)) > 0; + final Boolean _1gbFd = ((input) & (1 << 5)) > 0; + final Boolean _10gbFd = ((input) & (1 << 6)) > 0; + final Boolean _40gbFd = ((input) & (1 << 7)) > 0; + final Boolean _100gbFd = ((input) & (1 << 8)) > 0; + final Boolean _1tbFd = ((input) & (1 << 9)) > 0; + final Boolean _other = ((input) & (1 << 10)) > 0; + final Boolean _copper = ((input) & (1 << 11)) > 0; + final Boolean _fiber = ((input) & (1 << 12)) > 0; + final Boolean _autoneg = ((input) & (1 << 13)) > 0; + final Boolean _pause = ((input) & (1 << 14)) > 0; + final Boolean _pauseAsym = ((input) & (1 << 15)) > 0; + return new PortFeatures(_100gbFd, _100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd, _1gbHd, _1tbFd, + _40gbFd, _autoneg, _copper, _fiber, _other, _pause, _pauseAsym); + } + + private static PortState createPortState(long input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + return new PortState(two, one, three); + } + + private static List decodeBandsList(ByteBuf input) { + List bandsList = new ArrayList<>(); + BandsBuilder bandsBuilder = new BandsBuilder(); + MeterBandDropCaseBuilder dropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropBuilder dropBand = new MeterBandDropBuilder(); + dropBand.setType(MeterBandType.forValue(input.readUnsignedShort())); + input.skipBytes(Short.SIZE / Byte.SIZE); + dropBand.setRate(input.readUnsignedInt()); + dropBand.setBurstSize(input.readUnsignedInt()); + dropCaseBuilder.setMeterBandDrop(dropBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dropCaseBuilder.build()).build()); + MeterBandDscpRemarkCaseBuilder dscpCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); + MeterBandDscpRemarkBuilder dscpRemarkBand = new MeterBandDscpRemarkBuilder(); + dscpRemarkBand.setType(MeterBandType.forValue(input.readUnsignedShort())); + input.skipBytes(Short.SIZE / Byte.SIZE); + dscpRemarkBand.setRate(input.readUnsignedInt()); + dscpRemarkBand.setBurstSize(input.readUnsignedInt()); + dscpRemarkBand.setPrecLevel((short) 3); + dscpCaseBuilder.setMeterBandDscpRemark(dscpRemarkBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dscpCaseBuilder.build()).build()); + return bandsList; + } + + private static List createMeterConfig() { + MeterConfigBuilder builder = new MeterConfigBuilder(); + builder.setFlags(new MeterFlags(true, false, true, false)); + builder.setMeterId(new MeterId(1L)); + builder.setBands(createBandsList()); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static MeterBandTypeBitmap createMeterBandTypeBitmap(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + return new MeterBandTypeBitmap(one, two); + } + + private static List createBandsList() { + List bandsList = new ArrayList<>(); + BandsBuilder bandsBuilder = new BandsBuilder(); + MeterBandDropCaseBuilder dropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropBuilder dropBand = new MeterBandDropBuilder(); + dropBand.setType(MeterBandType.OFPMBTDROP); + dropBand.setRate(1L); + dropBand.setBurstSize(2L); + dropCaseBuilder.setMeterBandDrop(dropBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dropCaseBuilder.build()).build()); + MeterBandDscpRemarkCaseBuilder dscpCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); + MeterBandDscpRemarkBuilder dscpRemarkBand = new MeterBandDscpRemarkBuilder(); + dscpRemarkBand.setType(MeterBandType.OFPMBTDSCPREMARK); + dscpRemarkBand.setRate(1L); + dscpRemarkBand.setBurstSize(2L); + dscpRemarkBand.setPrecLevel((short) 3); + dscpCaseBuilder.setMeterBandDscpRemark(dscpRemarkBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dscpCaseBuilder.build()).build()); + return bandsList; + } + + private static MeterFlags createMeterFlags(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + final Boolean four = ((input) & (1 << 3)) > 0; + return new MeterFlags(three, one, two, four); + } + + private static List createMeterStats() { + MeterStatsBuilder builder = new MeterStatsBuilder(); + builder.setMeterId(new MeterId(1L)); + builder.setFlowCount(1L); + builder.setPacketInCount(BigInteger.valueOf(1L)); + builder.setByteInCount(BigInteger.valueOf(1L)); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + builder.setMeterBandStats(createMeterBandStats()); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createMeterBandStats() { + MeterBandStatsBuilder builder = new MeterBandStatsBuilder(); + builder.setPacketBandCount(BigInteger.valueOf(1L)); + builder.setByteBandCount(BigInteger.valueOf(1L)); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static ActionType createActionType(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + final Boolean four = ((input) & (1 << 3)) > 0; + final Boolean five = ((input) & (1 << 4)) > 0; + final Boolean six = ((input) & (1 << 5)) > 0; + final Boolean seven = ((input) & (1 << 6)) > 0; + final Boolean eight = ((input) & (1 << 7)) > 0; + final Boolean nine = ((input) & (1 << 8)) > 0; + final Boolean ten = ((input) & (1 << 9)) > 0; + final Boolean eleven = ((input) & (1 << 10)) > 0; + final Boolean twelve = ((input) & (1 << 11)) > 0; + final Boolean thirteen = ((input) & (1 << 12)) > 0; + final Boolean fourteen = ((input) & (1 << 13)) > 0; + final Boolean fifthteen = ((input) & (1 << 14)) > 0; + final Boolean sixteen = ((input) & (1 << 15)) > 0; + final Boolean seventeen = ((input) & (1 << 16)) > 0; + return new ActionType(three, two, five, thirteen, seventeen, eleven, one, nine, sixteen, seven, eight, + fifthteen, six, fourteen, four, twelve, ten); + } + + private static GroupCapabilities createGroupCapabilities(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + final Boolean four = ((input) & (1 << 3)) > 0; + return new GroupCapabilities(three, four, two, one); + } + + private static GroupTypes createGroupTypes(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + final Boolean four = ((input) & (1 << 3)) > 0; + return new GroupTypes(one, four, three, two); + } + + private static List createActionType() { + ActionType actionType1 = new ActionType(true, false, true, false, true, false, true, false, true, false, true, + false, true, false, true, false, true); + ActionType actionType2 = new ActionType(true, false, false, false, true, false, true, false, true, false, true, + false, true, false, true, true, true); + ActionType actionType3 = new ActionType(true, false, true, false, true, false, true, false, true, false, true, + false, true, false, true, false, true); + ActionType actionType4 = new ActionType(true, false, true, false, true, false, true, false, true, false, true, + false, true, false, true, false, true); + List list = new ArrayList<>(); + list.add(actionType1); + list.add(actionType2); + list.add(actionType3); + list.add(actionType4); + return list; + + } + + private static List createGroupDesc() { + GroupDescBuilder builder = new GroupDescBuilder(); + builder.setType(GroupType.forValue(1)); + builder.setGroupId(new GroupId(1L)); + builder.setBucketsList(createBucketsList()); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createGroupStats() { + GroupStatsBuilder builder = new GroupStatsBuilder(); + builder.setGroupId(new GroupId(1L)); + builder.setRefCount(1L); + builder.setPacketCount(BigInteger.valueOf(1L)); + builder.setByteCount(BigInteger.valueOf(1L)); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + builder.setBucketStats(createBucketStats()); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createBucketsList() { + BucketsListBuilder builder = new BucketsListBuilder(); + builder.setWeight(1); + builder.setWatchPort(new PortNumber(1L)); + builder.setWatchGroup(1L); + builder.setAction(createActionList()); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createActionList() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(45L)); + outputBuilder.setMaxLength(55); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwTtlCaseBuilder ttlCaseBuilder = new SetNwTtlCaseBuilder(); + SetNwTtlActionBuilder ttlActionBuilder = new SetNwTtlActionBuilder(); + ttlActionBuilder.setNwTtl((short) 64); + ttlCaseBuilder.setSetNwTtlAction(ttlActionBuilder.build()); + actionBuilder.setActionChoice(ttlCaseBuilder.build()); + actions.add(actionBuilder.build()); + return actions; + } + + private static List createBucketStats() { + BucketStatsBuilder builder = new BucketStatsBuilder(); + builder.setPacketCount(BigInteger.valueOf(1L)); + builder.setByteCount(BigInteger.valueOf(1L)); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createQueueStats() { + QueueStatsBuilder builder = new QueueStatsBuilder(); + builder.setPortNo(1L); + builder.setQueueId(1L); + builder.setTxBytes(BigInteger.valueOf(1L)); + builder.setTxPackets(BigInteger.valueOf(1L)); + builder.setTxErrors(BigInteger.valueOf(1L)); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createPortStats() { + PortStatsBuilder builder = new PortStatsBuilder(); + builder.setPortNo(1L); + builder.setRxPackets(BigInteger.valueOf(1L)); + builder.setTxPackets(BigInteger.valueOf(1L)); + builder.setRxBytes(BigInteger.valueOf(1L)); + builder.setTxBytes(BigInteger.valueOf(1L)); + builder.setRxDropped(BigInteger.valueOf(1L)); + builder.setTxDropped(BigInteger.valueOf(1L)); + builder.setRxErrors(BigInteger.valueOf(1L)); + builder.setTxErrors(BigInteger.valueOf(1L)); + builder.setRxFrameErr(BigInteger.valueOf(1L)); + builder.setRxOverErr(BigInteger.valueOf(1L)); + builder.setRxCrcErr(BigInteger.valueOf(1L)); + builder.setCollisions(BigInteger.valueOf(1L)); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + List list = new ArrayList(); + list.add(builder.build()); + return list; + } + + private static List createTableStats() { + TableStatsBuilder builder = new TableStatsBuilder(); + builder.setTableId((short) 1); + builder.setActiveCount(1L); + builder.setLookupCount(BigInteger.valueOf(1L)); + builder.setMatchedCount(BigInteger.valueOf(1L)); + List list = new ArrayList(); + list.add(builder.build()); + return list; + } + + private static List createFlowStats() { + FlowStatsBuilder builder = new FlowStatsBuilder(); + builder.setTableId((short) 1); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + builder.setPriority(1); + builder.setIdleTimeout(1); + builder.setHardTimeout(1); + builder.setCookie(BigInteger.valueOf(1234L)); + builder.setPacketCount(BigInteger.valueOf(1234L)); + builder.setByteCount(BigInteger.valueOf(1234L)); + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(42L)); + inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build()); + entriesBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build()); + entries.add(entriesBuilder.build()); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ipEcnBuilder = new IpEcnBuilder(); + ipEcnBuilder.setEcn((short) 4); + ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build()); + entriesBuilder.setMatchEntryValue(ipEcnCaseBuilder.build()); + entries.add(entriesBuilder.build()); + matchBuilder.setMatchEntry(entries); + builder.setMatch(matchBuilder.build()); + List instructions = new ArrayList<>(); + // Goto_table instruction + InstructionBuilder builderInstruction = new InstructionBuilder(); + GotoTableCaseBuilder gotoCaseBuilder = new GotoTableCaseBuilder(); + GotoTableBuilder instructionBuilder = new GotoTableBuilder(); + instructionBuilder.setTableId((short) 5); + gotoCaseBuilder.setGotoTable(instructionBuilder.build()); + builderInstruction.setInstructionChoice(gotoCaseBuilder.build()); + instructions.add(builderInstruction.build()); + // Write_metadata instruction + builderInstruction = new InstructionBuilder(); + WriteMetadataCaseBuilder metadataCaseBuilder = new WriteMetadataCaseBuilder(); + WriteMetadataBuilder metadataBuilder = new WriteMetadataBuilder(); + metadataBuilder.setMetadata(ByteBufUtils.hexStringToBytes("00 01 02 03 04 05 06 07")); + metadataBuilder.setMetadataMask(ByteBufUtils.hexStringToBytes("07 06 05 04 03 02 01 00")); + metadataCaseBuilder.setWriteMetadata(metadataBuilder.build()); + builderInstruction.setInstructionChoice(metadataCaseBuilder.build()); + instructions.add(builderInstruction.build()); + // Clear_actions instruction + builderInstruction = new InstructionBuilder(); + builderInstruction.setInstructionChoice(new ClearActionsCaseBuilder().build()); + instructions.add(builderInstruction.build()); + // Meter instruction + builderInstruction = new InstructionBuilder(); + MeterCaseBuilder meterCaseBuilder = new MeterCaseBuilder(); + MeterBuilder meterBuilder = new MeterBuilder(); + meterBuilder.setMeterId(42L); + meterCaseBuilder.setMeter(meterBuilder.build()); + builderInstruction.setInstructionChoice(meterCaseBuilder.build()); + instructions.add(builderInstruction.build()); + // Write_actions instruction + builderInstruction = new InstructionBuilder(); + WriteActionsCaseBuilder writeActionsCaseBuilder = new WriteActionsCaseBuilder(); + WriteActionsBuilder writeActionsBuilder = new WriteActionsBuilder(); + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(45L)); + outputBuilder.setMaxLength(55); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwTtlCaseBuilder ttlCaseBuilder = new SetNwTtlCaseBuilder(); + SetNwTtlActionBuilder ttlActionBuilder = new SetNwTtlActionBuilder(); + ttlActionBuilder.setNwTtl((short) 64); + ttlCaseBuilder.setSetNwTtlAction(ttlActionBuilder.build()); + actionBuilder.setActionChoice(ttlCaseBuilder.build()); + actions.add(actionBuilder.build()); + writeActionsBuilder.setAction(actions); + writeActionsCaseBuilder.setWriteActions(writeActionsBuilder.build()); + builderInstruction.setInstructionChoice(writeActionsCaseBuilder.build()); + instructions.add(builderInstruction.build()); + // Apply_actions instruction + builderInstruction = new InstructionBuilder(); + ApplyActionsCaseBuilder applyActionsCaseBuilder = new ApplyActionsCaseBuilder(); + ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder(); + actions = new ArrayList<>(); + actionBuilder = new ActionBuilder(); + PushVlanCaseBuilder vlanCaseBuilder = new PushVlanCaseBuilder(); + PushVlanActionBuilder vlanBuilder = new PushVlanActionBuilder(); + vlanBuilder.setEthertype(new EtherType(new EtherType(14))); + vlanCaseBuilder.setPushVlanAction(vlanBuilder.build()); + actionBuilder.setActionChoice(vlanCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopPbbCaseBuilder().build()); + actions.add(actionBuilder.build()); + applyActionsBuilder.setAction(actions); + applyActionsCaseBuilder.setApplyActions(applyActionsBuilder.build()); + builderInstruction.setInstructionChoice(applyActionsCaseBuilder.build()); + instructions.add(builderInstruction.build()); + builder.setInstruction(instructions); + List list = new ArrayList(); + list.add(builder.build()); + return list; + } + + private static MultipartRequestFlags createMultipartRequestFlags(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + return new MultipartRequestFlags(one); + } + + private static MultipartReplyDescCase decodeDescBody(ByteBuf output) { + MultipartReplyDescCaseBuilder descCase = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder desc = new MultipartReplyDescBuilder(); + byte[] mfrDesc = new byte[256]; + output.readBytes(mfrDesc); + desc.setMfrDesc(new String(mfrDesc).trim()); + byte[] hwDesc = new byte[256]; + output.readBytes(hwDesc); + desc.setHwDesc(new String(hwDesc).trim()); + byte[] swDesc = new byte[256]; + output.readBytes(swDesc); + desc.setSwDesc(new String(swDesc).trim()); + byte[] serialNumber = new byte[32]; + output.readBytes(serialNumber); + desc.setSerialNum(new String(serialNumber).trim()); + byte[] dpDesc = new byte[256]; + output.readBytes(dpDesc); + desc.setDpDesc(new String(dpDesc).trim()); + descCase.setMultipartReplyDesc(desc.build()); + return descCase.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java new file mode 100644 index 00000000..7ec4e446 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10BarrierReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 19; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + BarrierOutputBuilder builder = new BarrierOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + BarrierOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 8); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java new file mode 100644 index 00000000..ecfbcad5 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.common.types.rev130731.ActionTypeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.CapabilitiesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortConfigV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.features.reply.PhyPortBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FeaturesReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 6; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, GetFeaturesOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetFeaturesOutputBuilder builder = new GetFeaturesOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setDatapathId(BigInteger.valueOf(1L)); + builder.setBuffers(1L); + builder.setTables((short) 1); + builder.setCapabilitiesV10(new CapabilitiesV10(true, false, true, false, true, false, true, false)); + builder.setActionsV10( + new ActionTypeV10(true, false, true, false, true, false, true, false, true, false, true, false, true)); + builder.setPhyPort(createPorts()); + GetFeaturesOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 80); + Assert.assertEquals("Wrong datapath id", message.getDatapathId().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong n buffers", message.getBuffers().longValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong n tables", message.getTables().shortValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(3); + Assert.assertEquals("Wrong capabilities", message.getCapabilitiesV10(), + createCapabilities(serializedBuffer.readInt())); + Assert.assertEquals("Wrong actions", message.getActionsV10(), createActionsV10(serializedBuffer.readInt())); + PhyPort port = message.getPhyPort().get(0); + Assert.assertEquals("Wrong port No", port.getPortNo().intValue(), serializedBuffer.readShort()); + byte[] address = new byte[6]; + serializedBuffer.readBytes(address); + Assert.assertEquals("Wrong MacAddress", port.getHwAddr().getValue().toLowerCase(), + new MacAddress(ByteBufUtils.macAddressToString(address)).getValue().toLowerCase()); + byte[] name = new byte[16]; + serializedBuffer.readBytes(name); + Assert.assertEquals("Wrong name", port.getName(), new String(name).trim()); + Assert.assertEquals("Wrong config", port.getConfigV10(), createPortConfig(serializedBuffer.readInt())); + Assert.assertEquals("Wrong state", port.getStateV10(), createPortState(serializedBuffer.readInt())); + Assert.assertEquals("Wrong current", port.getCurrentFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong advertised", port.getAdvertisedFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong supported", port.getSupportedFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong peer", port.getPeerFeaturesV10(), createPortFeatures(serializedBuffer.readInt())); + + } + + private static List createPorts() { + List ports = new ArrayList<>(); + PhyPortBuilder builder = new PhyPortBuilder(); + builder.setPortNo(1L); + builder.setHwAddr(new MacAddress("94:de:80:a6:61:40")); + builder.setName("Port name"); + builder.setConfigV10(new PortConfigV10(true, false, true, false, true, false, true)); + builder.setStateV10(new PortStateV10(true, false, true, false, true, false, true, false)); + builder.setCurrentFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setAdvertisedFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setSupportedFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setPeerFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + ports.add(builder.build()); + return ports; + } + + private static PortConfigV10 createPortConfig(long input) { + final Boolean _portDown = ((input) & (1 << 0)) > 0; + final Boolean _noStp = ((input) & (1 << 1)) > 0; + final Boolean _noRecv = ((input) & (1 << 2)) > 0; + final Boolean _noRecvStp = ((input) & (1 << 3)) > 0; + final Boolean _noFlood = ((input) & (1 << 4)) > 0; + final Boolean _noFwd = ((input) & (1 << 5)) > 0; + final Boolean _noPacketIn = ((input) & (1 << 6)) > 0; + return new PortConfigV10(_noFlood, _noFwd, _noPacketIn, _noRecv, _noRecvStp, _noStp, _portDown); + } + + private static PortFeaturesV10 createPortFeatures(long input) { + final Boolean _10mbHd = ((input) & (1 << 0)) > 0; + final Boolean _10mbFd = ((input) & (1 << 1)) > 0; + final Boolean _100mbHd = ((input) & (1 << 2)) > 0; + final Boolean _100mbFd = ((input) & (1 << 3)) > 0; + final Boolean _1gbHd = ((input) & (1 << 4)) > 0; + final Boolean _1gbFd = ((input) & (1 << 5)) > 0; + final Boolean _10gbFd = ((input) & (1 << 6)) > 0; + final Boolean _copper = ((input) & (1 << 7)) > 0; + final Boolean _fiber = ((input) & (1 << 8)) > 0; + final Boolean _autoneg = ((input) & (1 << 9)) > 0; + final Boolean _pause = ((input) & (1 << 10)) > 0; + final Boolean _pauseAsym = ((input) & (1 << 11)) > 0; + return new PortFeaturesV10(_100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd, _1gbHd, _autoneg, _copper, + _fiber, _pause, _pauseAsym); + } + + private static PortStateV10 createPortState(long input) { + final Boolean _linkDown = ((input) & (1 << 0)) > 0; + final Boolean _blocked = ((input) & (1 << 1)) > 0; + final Boolean _live = ((input) & (1 << 2)) > 0; + final Boolean _stpListen = ((input) & (1 << 3)) > 0; + final Boolean _stpLearn = ((input) & (1 << 4)) > 0; + final Boolean _stpForward = ((input) & (1 << 5)) > 0; + final Boolean _stpBlock = ((input) & (1 << 6)) > 0; + final Boolean _stpMask = ((input) & (1 << 7)) > 0; + return new PortStateV10(_blocked, _linkDown, _live, _stpBlock, _stpForward, _stpLearn, _stpListen, _stpMask); + } + + private static CapabilitiesV10 createCapabilities(long input) { + Boolean _oFPCFLOWSTATS = ((input) & (1 << 0)) > 0; + Boolean _oFPCTABLESTATS = ((input) & (1 << 1)) > 0; + Boolean _oFPCPORTSTATS = ((input) & (1 << 2)) > 0; + Boolean _oFPCSTP = ((input) & (1 << 3)) > 0; + Boolean _oFPCRESERVED = ((input) & (1 << 4)) > 0; + Boolean _oFPCIPREASM = ((input) & (1 << 5)) > 0; + Boolean _oFPCQUEUESTATS = ((input) & (1 << 6)) > 0; + Boolean _oFPCARPMATCHIP = ((input) & (1 << 7)) > 0; + return new CapabilitiesV10(_oFPCARPMATCHIP, _oFPCFLOWSTATS, _oFPCIPREASM, _oFPCPORTSTATS, _oFPCQUEUESTATS, + _oFPCRESERVED, _oFPCSTP, _oFPCTABLESTATS); + } + + private static ActionTypeV10 createActionsV10(long input) { + Boolean _oFPATOUTPUT = ((input) & (1 << 0)) > 0; + Boolean _oFPATSETVLANVID = ((input) & (1 << 1)) > 0; + Boolean _oFPATSETVLANPCP = ((input) & (1 << 2)) > 0; + Boolean _oFPATSTRIPVLAN = ((input) & (1 << 3)) > 0; + Boolean _oFPATSETDLSRC = ((input) & (1 << 4)) > 0; + Boolean _oFPATSETDLDST = ((input) & (1 << 5)) > 0; + Boolean _oFPATSETNWSRC = ((input) & (1 << 6)) > 0; + Boolean _oFPATSETNWDST = ((input) & (1 << 7)) > 0; + Boolean _oFPATSETNWTOS = ((input) & (1 << 8)) > 0; + Boolean _oFPATSETTPSRC = ((input) & (1 << 9)) > 0; + Boolean _oFPATSETTPDST = ((input) & (1 << 10)) > 0; + Boolean _oFPATENQUEUE = ((input) & (1 << 11)) > 0; + Boolean _oFPATVENDOR = ((input) & (1 << 12)) > 0; + return new ActionTypeV10(_oFPATENQUEUE, _oFPATOUTPUT, _oFPATSETDLDST, _oFPATSETDLSRC, _oFPATSETNWDST, + _oFPATSETNWSRC, _oFPATSETNWTOS, _oFPATSETTPDST, _oFPATSETTPSRC, _oFPATSETVLANPCP, _oFPATSETVLANVID, + _oFPATSTRIPVLAN, _oFPATVENDOR); + + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java index 0d765be1..b8343bbd 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java @@ -25,8 +25,8 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.action.rev150203.action.grouping.action.choice.SetNwDstCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpSrcCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.dst._case.SetNwDstActionBuilder; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java new file mode 100644 index 00000000..ed54d82e --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowRemovedReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FlowRemovedMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 11; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, FlowRemovedMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + FlowRemovedMessageBuilder builder = new FlowRemovedMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + MatchV10Builder matchBuilder = new MatchV10Builder(); + matchBuilder.setWildcards(new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true)); + matchBuilder.setNwSrcMask((short) 0); + matchBuilder.setNwDstMask((short) 0); + matchBuilder.setInPort(58); + matchBuilder.setDlSrc(new MacAddress("01:01:01:01:01:01")); + matchBuilder.setDlDst(new MacAddress("ff:ff:ff:ff:ff:ff")); + matchBuilder.setDlVlan(18); + matchBuilder.setDlVlanPcp((short) 5); + matchBuilder.setDlType(42); + matchBuilder.setNwTos((short) 4); + matchBuilder.setNwProto((short) 7); + matchBuilder.setNwSrc(new Ipv4Address("8.8.8.8")); + matchBuilder.setNwDst(new Ipv4Address("16.16.16.16")); + matchBuilder.setTpSrc(6653); + matchBuilder.setTpDst(6633); + builder.setMatchV10(matchBuilder.build()); + byte[] cookie = new byte[] { (byte) 0xFF, 0x01, 0x04, 0x01, 0x01, 0x01, 0x04, 0x01 }; + builder.setCookie(new BigInteger(1, cookie)); + builder.setPriority(1); + builder.setReason(FlowRemovedReason.forValue(1)); + builder.setDurationSec(1L); + builder.setDurationNsec(1L); + builder.setIdleTimeout(12); + builder.setPacketCount(BigInteger.valueOf(1L)); + builder.setByteCount(BigInteger.valueOf(2L)); + FlowRemovedMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 88); + Assert.assertEquals("Wrong wildcards", 3678463, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong inPort", 58, serializedBuffer.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + serializedBuffer.readBytes(dlSrc); + Assert.assertEquals("Wrong dlSrc", "01:01:01:01:01:01", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + serializedBuffer.readBytes(dlDst); + Assert.assertEquals("Wrong dlDst", "FF:FF:FF:FF:FF:FF", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dlVlan", 18, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong dlVlanPcp", 5, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + Assert.assertEquals("Wrong dlType", 42, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong nwTos", 4, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong nwProto", 7, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong nwSrc", 134744072, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong nwDst", 269488144, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong tpSrc", 6653, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong tpDst", 6633, serializedBuffer.readUnsignedShort()); + byte[] cookieRead = new byte[8]; + serializedBuffer.readBytes(cookieRead); + Assert.assertArrayEquals("Wrong cookie", cookie, cookieRead); + Assert.assertEquals("Wrong priority", 1, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong reason", 1, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + Assert.assertEquals("Wrong duration", 1L, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong duration nsec", 1L, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong idle timeout", 12, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong packet count", 1L, serializedBuffer.readLong()); + Assert.assertEquals("Wrong byte count", 2L, serializedBuffer.readLong()); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java new file mode 100644 index 00000000..abe0055d --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PacketInMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 10; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, PacketInMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + PacketInMessageBuilder builder = new PacketInMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setBufferId(1L); + builder.setTotalLen(1); + builder.setInPort(1); + builder.setReason(PacketInReason.forValue(0)); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + builder.setData(data); + PacketInMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 34); + Assert.assertEquals("Wrong buffer id", message.getBufferId().longValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong total len", message.getTotalLen().intValue(), serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong port in", message.getInPort().intValue(), serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong reason", message.getReason().getIntValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + byte[] readData = new byte[serializedBuffer.readableBytes()]; + serializedBuffer.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java index 6b1ff682..af4f139e 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java @@ -94,7 +94,9 @@ public void testPacketOutInputMessage() throws Exception { Assert.assertEquals("Wrong action type", 3, out.readUnsignedShort()); Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); out.skipBytes(4); - Assert.assertArrayEquals("Wrong data", message.getData(), out.readBytes(out.readableBytes()).array()); + byte[] readData = new byte[out.readableBytes()]; + out.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); Assert.assertTrue("Unread data", out.readableBytes() == 0); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java index 1b98d77d..da063fbd 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java @@ -20,7 +20,7 @@ import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.common.types.rev130731.PortConfigV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java new file mode 100644 index 00000000..11688279 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.common.types.rev130731.PortConfigV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortStateV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PortStatusMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 12; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, PortStatusMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + PortStatusMessageBuilder builder = new PortStatusMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setReason(PortReason.forValue(1)); + builder.setPortNo(1L); + builder.setHwAddr(new MacAddress("94:de:80:a6:61:40")); + builder.setName("Port name"); + builder.setConfigV10(new PortConfigV10(true, false, true, false, true, false, true)); + builder.setStateV10(new PortStateV10(true, false, true, false, true, false, true, false)); + builder.setCurrentFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setAdvertisedFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setSupportedFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + builder.setPeerFeaturesV10( + new PortFeaturesV10(true, false, true, false, true, false, true, false, true, false, true, false)); + PortStatusMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 64); + Assert.assertEquals("Wrong reason", message.getReason().getIntValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(7); + Assert.assertEquals("Wrong port No", message.getPortNo().intValue(), serializedBuffer.readShort()); + byte[] address = new byte[6]; + serializedBuffer.readBytes(address); + Assert.assertEquals("Wrong MacAddress", message.getHwAddr().getValue().toLowerCase(), + new MacAddress(ByteBufUtils.macAddressToString(address)).getValue().toLowerCase()); + byte[] name = new byte[16]; + serializedBuffer.readBytes(name); + Assert.assertEquals("Wrong name", message.getName(), new String(name).trim()); + Assert.assertEquals("Wrong config", message.getConfigV10(), createPortConfig(serializedBuffer.readInt())); + Assert.assertEquals("Wrong state", message.getStateV10(), createPortState(serializedBuffer.readInt())); + Assert.assertEquals("Wrong current", message.getCurrentFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong advertised", message.getAdvertisedFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong supported", message.getSupportedFeaturesV10(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong peer", message.getPeerFeaturesV10(), createPortFeatures(serializedBuffer.readInt())); + } + + private static PortConfigV10 createPortConfig(long input) { + final Boolean _portDown = ((input) & (1 << 0)) > 0; + final Boolean _noStp = ((input) & (1 << 1)) > 0; + final Boolean _noRecv = ((input) & (1 << 2)) > 0; + final Boolean _noRecvStp = ((input) & (1 << 3)) > 0; + final Boolean _noFlood = ((input) & (1 << 4)) > 0; + final Boolean _noFwd = ((input) & (1 << 5)) > 0; + final Boolean _noPacketIn = ((input) & (1 << 6)) > 0; + return new PortConfigV10(_noFlood, _noFwd, _noPacketIn, _noRecv, _noRecvStp, _noStp, _portDown); + } + + private static PortFeaturesV10 createPortFeatures(long input) { + final Boolean _10mbHd = ((input) & (1 << 0)) > 0; + final Boolean _10mbFd = ((input) & (1 << 1)) > 0; + final Boolean _100mbHd = ((input) & (1 << 2)) > 0; + final Boolean _100mbFd = ((input) & (1 << 3)) > 0; + final Boolean _1gbHd = ((input) & (1 << 4)) > 0; + final Boolean _1gbFd = ((input) & (1 << 5)) > 0; + final Boolean _10gbFd = ((input) & (1 << 6)) > 0; + final Boolean _copper = ((input) & (1 << 7)) > 0; + final Boolean _fiber = ((input) & (1 << 8)) > 0; + final Boolean _autoneg = ((input) & (1 << 9)) > 0; + final Boolean _pause = ((input) & (1 << 10)) > 0; + final Boolean _pauseAsym = ((input) & (1 << 11)) > 0; + return new PortFeaturesV10(_100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd, _1gbHd, _autoneg, _copper, + _fiber, _pause, _pauseAsym); + } + + private static PortStateV10 createPortState(long input) { + final Boolean _linkDown = ((input) & (1 << 0)) > 0; + final Boolean _blocked = ((input) & (1 << 1)) > 0; + final Boolean _live = ((input) & (1 << 2)) > 0; + final Boolean _stpListen = ((input) & (1 << 3)) > 0; + final Boolean _stpLearn = ((input) & (1 << 4)) > 0; + final Boolean _stpForward = ((input) & (1 << 5)) > 0; + final Boolean _stpBlock = ((input) & (1 << 6)) > 0; + final Boolean _stpMask = ((input) & (1 << 7)) > 0; + return new PortStateV10(_blocked, _linkDown, _live, _stpBlock, _stpForward, _stpLearn, _stpListen, _stpMask); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 00000000..c46d03d7 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueuePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.QueuesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueuePropertyBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10QueueGetConfigReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 21; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, GetQueueConfigOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setPort(new PortNumber(1L)); + builder.setQueues(createQueues()); + GetQueueConfigOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 40); + Assert.assertEquals("Wrong port", message.getPort().getValue().longValue(), serializedBuffer.readShort()); + serializedBuffer.skipBytes(6); + Assert.assertEquals("Wrong queue Id", message.getQueues().get(0).getQueueId().getValue().longValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong length", 24, serializedBuffer.readShort()); + serializedBuffer.skipBytes(2); + List properties = message.getQueues().get(0).getQueueProperty(); + Assert.assertEquals("Wrong property", properties.get(0).getProperty().getIntValue(), + serializedBuffer.readShort()); + Assert.assertEquals("Wrong property length", 16, serializedBuffer.readShort()); + serializedBuffer.skipBytes(4); + RateQueueProperty rateQueueProperty = properties.get(0).getAugmentation(RateQueueProperty.class); + Assert.assertEquals("Wrong rate", rateQueueProperty.getRate().intValue(), serializedBuffer.readShort()); + serializedBuffer.skipBytes(6); + } + + private List createQueues() { + List list = new ArrayList<>(); + QueuesBuilder builder = new QueuesBuilder(); + builder.setQueueId(new QueueId(1L)); + builder.setQueueProperty(createPropertiesList()); + + list.add(builder.build()); + return list; + } + + private static List createPropertiesList() { + List propertiesList = new ArrayList<>(); + QueuePropertyBuilder pb = new QueuePropertyBuilder(); + pb.setProperty(QueueProperties.forValue(1)); + RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder(); + rateBuilder.setRate(5); + pb.addAugmentation(RateQueueProperty.class, rateBuilder.build()); + propertiesList.add(pb.build()); + return propertiesList; + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java new file mode 100644 index 00000000..8b52cb01 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.output.action._case.OutputActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyAggregateCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyDescCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyFlowCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyPortStatsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyTableCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.aggregate._case.MultipartReplyAggregateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.desc._case.MultipartReplyDescBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.MultipartReplyFlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.flow._case.multipart.reply.flow.FlowStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.MultipartReplyPortStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.port.stats._case.multipart.reply.port.stats.PortStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.MultipartReplyQueueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.queue._case.multipart.reply.queue.QueueStatsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.multipart.reply.table.TableStatsBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 17; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, MultipartReplyMessage.class)); + } + + @Test + public void testDescBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(0)); + MultipartReplyDescCaseBuilder descCase = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder desc = new MultipartReplyDescBuilder(); + desc.setMfrDesc("Test"); + desc.setHwDesc("Test"); + desc.setSwDesc("Test"); + desc.setSerialNum("12345"); + desc.setDpDesc("Test"); + descCase.setMultipartReplyDesc(desc.build()); + builder.setMultipartReplyBody(descCase.build()); + MultipartReplyMessage message = builder.build(); + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 1068); + Assert.assertEquals("Wrong type", MultipartType.OFPMPDESC.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + Assert.assertEquals("Wrong desc body", message.getMultipartReplyBody(), decodeDescBody(serializedBuffer)); + } + + @Test + public void testFlowBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(1)); + MultipartReplyFlowCaseBuilder flowCase = new MultipartReplyFlowCaseBuilder(); + MultipartReplyFlowBuilder flow = new MultipartReplyFlowBuilder(); + flow.setFlowStats(createFlowStats()); + flowCase.setMultipartReplyFlow(flow.build()); + builder.setMultipartReplyBody(flowCase.build()); + MultipartReplyMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 108); + Assert.assertEquals("Wrong type", MultipartType.OFPMPFLOW.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + FlowStats flowStats = flow.getFlowStats().get(0); + Assert.assertEquals("Wrong length", 96, serializedBuffer.readShort()); + Assert.assertEquals("Wrong Table ID", flowStats.getTableId().intValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + Assert.assertEquals("Wrong wildcards", 3678463, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong inPort", 58, serializedBuffer.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + serializedBuffer.readBytes(dlSrc); + Assert.assertEquals("Wrong dlSrc", "01:01:01:01:01:01", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + serializedBuffer.readBytes(dlDst); + Assert.assertEquals("Wrong dlDst", "FF:FF:FF:FF:FF:FF", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dlVlan", 18, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong dlVlanPcp", 5, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(1); + Assert.assertEquals("Wrong dlType", 42, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong nwTos", 4, serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong nwProto", 7, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong nwSrc", 134744072, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong nwDst", 269488144, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong tpSrc", 6653, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong tpDst", 6633, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong duration sec", flowStats.getDurationSec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong duration nsec", flowStats.getDurationNsec().intValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong priority", flowStats.getPriority().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong idle timeout", flowStats.getIdleTimeout().intValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong hard timeout", flowStats.getHardTimeout().intValue(), serializedBuffer.readShort()); + serializedBuffer.skipBytes(6); + Assert.assertEquals("Wrong cookie", flowStats.getCookie().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Packet count", flowStats.getPacketCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", flowStats.getByteCount().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong action type", 0, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong port", 42, serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong maxlength", 50, serializedBuffer.readUnsignedShort()); + } + + @Test + public void testAggregateBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(2)); + MultipartReplyAggregateCaseBuilder aggregateCase = new MultipartReplyAggregateCaseBuilder(); + MultipartReplyAggregateBuilder aggregate = new MultipartReplyAggregateBuilder(); + aggregate.setPacketCount(BigInteger.valueOf(1234L)); + aggregate.setByteCount(BigInteger.valueOf(1234L)); + aggregate.setFlowCount(1L); + aggregateCase.setMultipartReplyAggregate(aggregate.build()); + builder.setMultipartReplyBody(aggregateCase.build()); + MultipartReplyMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 36); + Assert.assertEquals("Wrong type", MultipartType.OFPMPAGGREGATE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + Assert.assertEquals("Wrong Packet count", 1234L, serializedBuffer.readLong()); + Assert.assertEquals("Wrong Byte count", 1234L, serializedBuffer.readLong()); + Assert.assertEquals("Wrong flow count", 1L, serializedBuffer.readInt()); + serializedBuffer.skipBytes(4); + } + + @Test + public void testTableBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(3)); + MultipartReplyTableCaseBuilder tableCase = new MultipartReplyTableCaseBuilder(); + MultipartReplyTableBuilder table = new MultipartReplyTableBuilder(); + table.setTableStats(createTableStats()); + tableCase.setMultipartReplyTable(table.build()); + builder.setMultipartReplyBody(tableCase.build()); + MultipartReplyMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 60); + Assert.assertEquals("Wrong type", MultipartType.OFPMPTABLE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + Assert.assertEquals("Wrong table id", 1, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(3); + Assert.assertEquals("Wrong name", "Table name", ByteBufUtils.decodeNullTerminatedString(serializedBuffer, 16)); + Assert.assertEquals("Wrong wildcards", 3145983, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong max entries", 1L, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong active count", 1L, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong lookup count", 1234L, serializedBuffer.readLong()); + Assert.assertEquals("Wrong matched count", 1234L, serializedBuffer.readLong()); + } + + @Test + public void testPortStatsBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(4)); + MultipartReplyPortStatsCaseBuilder portStatsCase = new MultipartReplyPortStatsCaseBuilder(); + MultipartReplyPortStatsBuilder portStats = new MultipartReplyPortStatsBuilder(); + portStats.setPortStats(createPortStats()); + portStatsCase.setMultipartReplyPortStats(portStats.build()); + builder.setMultipartReplyBody(portStatsCase.build()); + MultipartReplyMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 118); + Assert.assertEquals("Wrong type", MultipartType.OFPMPPORTSTATS.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + MultipartReplyPortStatsCase body = (MultipartReplyPortStatsCase) message.getMultipartReplyBody(); + MultipartReplyPortStats messageOutput = body.getMultipartReplyPortStats(); + PortStats portStatsOutput = messageOutput.getPortStats().get(0); + Assert.assertEquals("Wrong port no", portStatsOutput.getPortNo().intValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(6); + Assert.assertEquals("Wrong rx packets", portStatsOutput.getRxPackets().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx packets", portStatsOutput.getTxPackets().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx bytes", portStatsOutput.getRxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx bytes", portStatsOutput.getTxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx dropped", portStatsOutput.getRxDropped().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx dropped", portStatsOutput.getTxDropped().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx errors", portStatsOutput.getRxErrors().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx errors", portStatsOutput.getTxErrors().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx frame err", portStatsOutput.getRxFrameErr().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx over err", portStatsOutput.getRxOverErr().longValue(), + serializedBuffer.readLong()); + Assert.assertEquals("Wrong rx crc err", portStatsOutput.getRxCrcErr().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong collisions", portStatsOutput.getCollisions().longValue(), + serializedBuffer.readLong()); + } + + @Test + public void testQueueBodySerialize() throws Exception { + MultipartReplyMessageBuilder builder; + builder = new MultipartReplyMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setType(MultipartType.forValue(5)); + MultipartReplyQueueCaseBuilder queueCase = new MultipartReplyQueueCaseBuilder(); + MultipartReplyQueueBuilder queue = new MultipartReplyQueueBuilder(); + queue.setQueueStats(createQueueStats()); + queueCase.setMultipartReplyQueue(queue.build()); + builder.setMultipartReplyBody(queueCase.build()); + MultipartReplyMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV10(serializedBuffer, MESSAGE_TYPE, 44); + Assert.assertEquals("Wrong type", MultipartType.OFPMPQUEUE.getIntValue(), serializedBuffer.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), + createMultipartRequestFlags(serializedBuffer.readShort())); + MultipartReplyQueueCase body = (MultipartReplyQueueCase) message.getMultipartReplyBody(); + MultipartReplyQueue messageOutput = body.getMultipartReplyQueue(); + QueueStats queueStats = messageOutput.getQueueStats().get(0); + Assert.assertEquals("Wrong length", 32, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(2); + Assert.assertEquals("Wrong queue id", queueStats.getQueueId().intValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong tx bytes", queueStats.getTxBytes().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx packets", queueStats.getTxPackets().longValue(), serializedBuffer.readLong()); + Assert.assertEquals("Wrong tx errors", queueStats.getTxErrors().longValue(), serializedBuffer.readLong()); + } + + private static List createQueueStats() { + QueueStatsBuilder builder = new QueueStatsBuilder(); + builder.setQueueId(1L); + builder.setTxBytes(BigInteger.valueOf(1L)); + builder.setTxPackets(BigInteger.valueOf(1L)); + builder.setTxErrors(BigInteger.valueOf(1L)); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createPortStats() { + PortStatsBuilder builder = new PortStatsBuilder(); + builder.setPortNo(1L); + builder.setRxPackets(BigInteger.valueOf(1L)); + builder.setTxPackets(BigInteger.valueOf(1L)); + builder.setRxBytes(BigInteger.valueOf(1L)); + builder.setTxBytes(BigInteger.valueOf(1L)); + builder.setRxDropped(BigInteger.valueOf(1L)); + builder.setTxDropped(BigInteger.valueOf(1L)); + builder.setRxErrors(BigInteger.valueOf(1L)); + builder.setTxErrors(BigInteger.valueOf(1L)); + builder.setRxFrameErr(BigInteger.valueOf(1L)); + builder.setRxOverErr(BigInteger.valueOf(1L)); + builder.setRxCrcErr(BigInteger.valueOf(1L)); + builder.setCollisions(BigInteger.valueOf(1L)); + List list = new ArrayList(); + list.add(builder.build()); + return list; + } + + private static List createTableStats() { + TableStatsBuilder builder = new TableStatsBuilder(); + builder.setTableId((short) 1); + builder.setName("Table name"); + builder.setWildcards(new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true)); + builder.setMaxEntries(1L); + builder.setActiveCount(1L); + builder.setLookupCount(BigInteger.valueOf(1234L)); + builder.setMatchedCount(BigInteger.valueOf(1234L)); + List list = new ArrayList<>(); + list.add(builder.build()); + return list; + } + + private static List createFlowStats() { + FlowStatsBuilder builder = new FlowStatsBuilder(); + builder.setTableId((short) 1); + MatchV10Builder matchBuilder = new MatchV10Builder(); + matchBuilder.setWildcards(new FlowWildcardsV10(true, true, true, true, true, true, true, true, true, true)); + matchBuilder.setNwSrcMask((short) 0); + matchBuilder.setNwDstMask((short) 0); + matchBuilder.setInPort(58); + matchBuilder.setDlSrc(new MacAddress("01:01:01:01:01:01")); + matchBuilder.setDlDst(new MacAddress("ff:ff:ff:ff:ff:ff")); + matchBuilder.setDlVlan(18); + matchBuilder.setDlVlanPcp((short) 5); + matchBuilder.setDlType(42); + matchBuilder.setNwTos((short) 4); + matchBuilder.setNwProto((short) 7); + matchBuilder.setNwSrc(new Ipv4Address("8.8.8.8")); + matchBuilder.setNwDst(new Ipv4Address("16.16.16.16")); + matchBuilder.setTpSrc(6653); + matchBuilder.setTpDst(6633); + builder.setMatchV10(matchBuilder.build()); + builder.setDurationSec(1L); + builder.setDurationNsec(2L); + builder.setPriority(1); + builder.setIdleTimeout(1); + builder.setHardTimeout(1); + builder.setCookie(BigInteger.valueOf(1234L)); + builder.setPacketCount(BigInteger.valueOf(1234L)); + builder.setByteCount(BigInteger.valueOf(1234L)); + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(42L)); + outputBuilder.setMaxLength(50); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + builder.setAction(actions); + List list = new ArrayList(); + list.add(builder.build()); + return list; + } + + private static MultipartRequestFlags createMultipartRequestFlags(int input) { + final Boolean one = ((input) & (1 << 0)) > 0; + return new MultipartRequestFlags(one); + } + + private static MultipartReplyDescCase decodeDescBody(ByteBuf output) { + MultipartReplyDescCaseBuilder descCase = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder desc = new MultipartReplyDescBuilder(); + byte[] mfrDesc = new byte[256]; + output.readBytes(mfrDesc); + desc.setMfrDesc(new String(mfrDesc).trim()); + byte[] hwDesc = new byte[256]; + output.readBytes(hwDesc); + desc.setHwDesc(new String(hwDesc).trim()); + byte[] swDesc = new byte[256]; + output.readBytes(swDesc); + desc.setSwDesc(new String(swDesc).trim()); + byte[] serialNumber = new byte[32]; + output.readBytes(serialNumber); + desc.setSerialNum(new String(serialNumber).trim()); + byte[] dpDesc = new byte[256]; + output.readBytes(dpDesc); + desc.setDpDesc(new String(dpDesc).trim()); + descCase.setMultipartReplyDesc(desc.build()); + return descCase.build(); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java index da2486c4..c44b9f0c 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java @@ -20,8 +20,8 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -300,4 +300,4 @@ public void testQueue() throws Exception { Assert.assertEquals("Wrong queue-id", 16, out.readUnsignedInt()); Assert.assertTrue("Unread data", out.readableBytes() == 0); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java new file mode 100644 index 00000000..8f917b7b --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PacketInReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.phy.port._case.InPhyPortBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PacketInMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 10; + private static final byte PADDING = 2; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry.getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, PacketInMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + PacketInMessageBuilder builder = new PacketInMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setBufferId(256L); + builder.setTotalLen(10); + builder.setReason(PacketInReason.forValue(0)); + builder.setTableId(new TableId(1L)); + byte[] cookie = new byte[] { (byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01 }; + builder.setCookie(new BigInteger(1, cookie)); + MatchBuilder matchBuilder = new MatchBuilder(); + matchBuilder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(InPhyPort.class); + entriesBuilder.setHasMask(false); + InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(42L)); + inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build()); + entriesBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build()); + entries.add(entriesBuilder.build()); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(IpEcn.class); + entriesBuilder.setHasMask(false); + IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ipEcnBuilder = new IpEcnBuilder(); + ipEcnBuilder.setEcn((short) 4); + ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build()); + entriesBuilder.setMatchEntryValue(ipEcnCaseBuilder.build()); + entries.add(entriesBuilder.build()); + matchBuilder.setMatchEntry(entries); + builder.setMatch(matchBuilder.build()); + byte[] data = ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14"); + builder.setData(data); + PacketInMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 66); + Assert.assertEquals("Wrong BufferId", message.getBufferId().longValue(), serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong actions length", message.getTotalLen().intValue(), + serializedBuffer.readUnsignedShort()); + Assert.assertEquals("Wrong reason", message.getReason().getIntValue(), serializedBuffer.readUnsignedByte()); + Assert.assertEquals("Wrong tableId", message.getTableId().getValue().intValue(), + serializedBuffer.readUnsignedByte()); + cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + serializedBuffer.readBytes(cookie); + Assert.assertEquals("Wrong cookie", message.getCookie(), new BigInteger(1, cookie)); + Assert.assertEquals("Wrong match type", 1, serializedBuffer.readUnsignedShort()); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong oxm class", 0x8000, serializedBuffer.readUnsignedShort()); + short fieldAndMask = serializedBuffer.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 42, serializedBuffer.readUnsignedInt()); + Assert.assertEquals("Wrong oxm class", 0x8000, serializedBuffer.readUnsignedShort()); + fieldAndMask = serializedBuffer.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1); + serializedBuffer.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 4, serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(7); + serializedBuffer.skipBytes(PADDING); + byte[] readData = new byte[serializedBuffer.readableBytes()]; + serializedBuffer.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java index 50c0839f..60ee5210 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java @@ -96,7 +96,9 @@ public void testPacketOutInputMessage() throws Exception { Assert.assertEquals("Wrong action type", 18, out.readUnsignedShort()); Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); out.skipBytes(PADDING_IN_ACTION_HEADER); - Assert.assertArrayEquals("Wrong data", message.getData(), out.readBytes(out.readableBytes()).array()); + byte[] readData = new byte[out.readableBytes()]; + out.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); } /** 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 12e756a5..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 @@ -20,7 +20,7 @@ import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.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; @@ -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-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java new file mode 100644 index 00000000..362d2fd8 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.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.PortReason; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class PortStatusMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 12; + private static final byte PADDING = 7; + private static final byte PORT_PADDING_1 = 4; + private static final byte PORT_PADDING_2 = 2; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, PortStatusMessage.class)); + } + + @Test + public void testSerialize() throws Exception { + PortStatusMessageBuilder builder = new PortStatusMessageBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setReason(PortReason.forValue(1)); + builder.setPortNo(1L); + builder.setHwAddr(new MacAddress("94:de:80:a6:61:40")); + builder.setName("Port name"); + builder.setConfig(new PortConfig(true, false, true, false)); + builder.setState(new PortState(true, false, true)); + builder.setCurrentFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setAdvertisedFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setSupportedFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, + true, false, true, false, true, false)); + builder.setPeerFeatures(new PortFeatures(true, false, true, false, true, false, true, false, true, false, true, + false, true, false, true, false)); + builder.setCurrSpeed(1234L); + builder.setMaxSpeed(1234L); + PortStatusMessage message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 80); + Assert.assertEquals("Wrong reason", message.getReason().getIntValue(), serializedBuffer.readUnsignedByte()); + serializedBuffer.skipBytes(PADDING); + Assert.assertEquals("Wrong PortNo", message.getPortNo().intValue(), serializedBuffer.readUnsignedInt()); + serializedBuffer.skipBytes(PORT_PADDING_1); + byte[] address = new byte[6]; + serializedBuffer.readBytes(address); + Assert.assertEquals("Wrong MacAddress", message.getHwAddr().getValue().toLowerCase(), + new MacAddress(ByteBufUtils.macAddressToString(address)).getValue().toLowerCase()); + serializedBuffer.skipBytes(PORT_PADDING_2); + byte[] name = new byte[16]; + serializedBuffer.readBytes(name); + Assert.assertEquals("Wrong name", message.getName(), new String(name).trim()); + Assert.assertEquals("Wrong config", message.getConfig(), createPortConfig(serializedBuffer.readInt())); + Assert.assertEquals("Wrong state", message.getState(), createPortState(serializedBuffer.readInt())); + Assert.assertEquals("Wrong current", message.getCurrentFeatures(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong advertised", message.getAdvertisedFeatures(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong supported", message.getSupportedFeatures(), + createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong peer", message.getPeerFeatures(), createPortFeatures(serializedBuffer.readInt())); + Assert.assertEquals("Wrong Current speed", message.getCurrSpeed().longValue(), serializedBuffer.readInt()); + Assert.assertEquals("Wrong Max speed", message.getMaxSpeed().longValue(), serializedBuffer.readInt()); + } + + private static PortConfig createPortConfig(long input) { + final Boolean _portDown = ((input) & (1 << 0)) > 0; + final Boolean _noRecv = ((input) & (1 << 2)) > 0; + final Boolean _noFwd = ((input) & (1 << 5)) > 0; + final Boolean _noPacketIn = ((input) & (1 << 6)) > 0; + return new PortConfig(_noFwd, _noPacketIn, _noRecv, _portDown); + } + + private static PortFeatures createPortFeatures(long input) { + final Boolean _10mbHd = ((input) & (1 << 0)) > 0; + final Boolean _10mbFd = ((input) & (1 << 1)) > 0; + final Boolean _100mbHd = ((input) & (1 << 2)) > 0; + final Boolean _100mbFd = ((input) & (1 << 3)) > 0; + final Boolean _1gbHd = ((input) & (1 << 4)) > 0; + final Boolean _1gbFd = ((input) & (1 << 5)) > 0; + final Boolean _10gbFd = ((input) & (1 << 6)) > 0; + final Boolean _40gbFd = ((input) & (1 << 7)) > 0; + final Boolean _100gbFd = ((input) & (1 << 8)) > 0; + final Boolean _1tbFd = ((input) & (1 << 9)) > 0; + final Boolean _other = ((input) & (1 << 10)) > 0; + final Boolean _copper = ((input) & (1 << 11)) > 0; + final Boolean _fiber = ((input) & (1 << 12)) > 0; + final Boolean _autoneg = ((input) & (1 << 13)) > 0; + final Boolean _pause = ((input) & (1 << 14)) > 0; + final Boolean _pauseAsym = ((input) & (1 << 15)) > 0; + return new PortFeatures(_100gbFd, _100mbFd, _100mbHd, _10gbFd, _10mbFd, _10mbHd, _1gbFd, _1gbHd, _1tbFd, + _40gbFd, _autoneg, _copper, _fiber, _other, _pause, _pauseAsym); + } + + private static PortState createPortState(long input) { + final Boolean one = ((input) & (1 << 0)) > 0; + final Boolean two = ((input) & (1 << 1)) > 0; + final Boolean three = ((input) & (1 << 2)) > 0; + return new PortState(two, one, three); + } + +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 00000000..c69a0da1 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.RateQueuePropertyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigOutputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.get.config.reply.QueuesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueuePropertyBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class QueueGetConfigReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 23; + private static final byte PADDING = 4; + private static final byte QUEUE_PADDING = 6; + private static final byte PROPERTY_HEADER_PADDING = 4; + private static final byte PROPERTY_RATE_PADDING = 6; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetQueueConfigOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPort(new PortNumber(0x00010203L)); + builder.setQueues(createQueuesList()); + GetQueueConfigOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 80); + Assert.assertEquals("Wrong port", message.getPort().getValue().longValue(), serializedBuffer.readInt()); + serializedBuffer.skipBytes(PADDING); + + Assert.assertEquals("Wrong queue Id", message.getQueues().get(0).getQueueId().getValue().longValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong port", message.getQueues().get(0).getPort().getValue().longValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong length", 32, serializedBuffer.readShort()); + serializedBuffer.skipBytes(QUEUE_PADDING); + List properties = message.getQueues().get(0).getQueueProperty(); + Assert.assertEquals("Wrong property", properties.get(0).getProperty().getIntValue(), + serializedBuffer.readShort()); + Assert.assertEquals("Wrong property length", 16, serializedBuffer.readShort()); + serializedBuffer.skipBytes(PROPERTY_HEADER_PADDING); + RateQueueProperty rateQueueProperty = properties.get(0).getAugmentation(RateQueueProperty.class); + Assert.assertEquals("Wrong rate", rateQueueProperty.getRate().intValue(), serializedBuffer.readShort()); + serializedBuffer.skipBytes(PROPERTY_RATE_PADDING); + + Assert.assertEquals("Wrong queue Id", message.getQueues().get(1).getQueueId().getValue().longValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong queue Id", message.getQueues().get(1).getPort().getValue().longValue(), + serializedBuffer.readInt()); + Assert.assertEquals("Wrong length", 32, serializedBuffer.readShort()); + serializedBuffer.skipBytes(QUEUE_PADDING); + List propertiesTwo = message.getQueues().get(1).getQueueProperty(); + Assert.assertEquals("Wrong property", propertiesTwo.get(0).getProperty().getIntValue(), + serializedBuffer.readShort()); + Assert.assertEquals("Wrong property length", 16, serializedBuffer.readShort()); + serializedBuffer.skipBytes(PROPERTY_HEADER_PADDING); + RateQueueProperty rateQueuePropertyTwo = propertiesTwo.get(0).getAugmentation(RateQueueProperty.class); + Assert.assertEquals("Wrong rate", rateQueuePropertyTwo.getRate().intValue(), serializedBuffer.readShort()); + serializedBuffer.skipBytes(PROPERTY_RATE_PADDING); + + } + + private static List createQueuesList() { + List queuesList = new ArrayList<>(); + for (int i = 1; i < 3; i++) { + QueuesBuilder qb = new QueuesBuilder(); + qb.setQueueId(new QueueId((long) i)); + qb.setPort(new PortNumber((long) i)); + qb.setQueueProperty(createPropertiesList()); + queuesList.add(qb.build()); + } + return queuesList; + } + + private static List createPropertiesList() { + List propertiesList = new ArrayList<>(); + QueuePropertyBuilder pb = new QueuePropertyBuilder(); + pb.setProperty(QueueProperties.forValue(2)); + RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder(); + rateBuilder.setRate(5); + pb.addAugmentation(RateQueueProperty.class, rateBuilder.build()); + propertiesList.add(pb.build()); + return propertiesList; + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java new file mode 100644 index 00000000..8ed58553 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 NetIDE Consortium 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.factories; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import java.math.BigInteger; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +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.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ControllerRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestOutputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class RoleReplyMessageFactoryTest { + private OFSerializer factory; + private static final byte MESSAGE_TYPE = 25; + private static final byte PADDING = 4; + + @Before + public void startUp() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + factory = registry + .getSerializer(new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, RoleRequestOutput.class)); + } + + @Test + public void testSerialize() throws Exception { + RoleRequestOutputBuilder builder = new RoleRequestOutputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setRole(ControllerRole.forValue(0)); + builder.setGenerationId(BigInteger.valueOf(1L)); + RoleRequestOutput message = builder.build(); + + ByteBuf serializedBuffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, serializedBuffer); + BufferHelper.checkHeaderV13(serializedBuffer, MESSAGE_TYPE, 24); + Assert.assertEquals("Wrong role", message.getRole().getIntValue(), + ControllerRole.forValue((int) serializedBuffer.readUnsignedInt()).getIntValue()); + serializedBuffer.skipBytes(PADDING); + byte[] genId = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + serializedBuffer.readBytes(genId); + Assert.assertEquals("Wrong generation ID", message.getGenerationId(), new BigInteger(1, genId)); + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java index 220a2af5..48106634 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java @@ -21,8 +21,8 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10StatsRequestInputFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartRequestFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; @@ -99,4 +99,4 @@ public void test() throws Exception { out.skipBytes(1); Assert.assertEquals("Wrong out port", 42, out.readUnsignedShort()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java index 145772b7..a3100d65 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.ArpSha; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java index 176595da..5e5fcc4b 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java index a753c964..062178ce 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.ArpTha; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java index 78812111..11b64a33 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTpa; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java index c442608b..137c47aa 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.EthDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java index 263399dc..f171505a 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.EthSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java index 527252b8..b7cc4aef 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpDscp; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java index e4c184f9..233a5469 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Dst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java index c1c8f9eb..286cbab6 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -154,4 +154,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); } } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java index d625317c..5a1b6ca0 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.Ipv6NdSll; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -112,4 +112,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java index 02680589..8d6d95cc 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +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.oxm.rev150225.Ipv6NdTll; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -112,4 +112,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java index 38ca6dc7..386d1cd4 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Src; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java index dd51c957..b3a1fa90 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java index ca46f9ef..3c6eb1fb 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java index adcdf7bb..c6033946 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java index 003c6e62..a0be555f 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java index a77e20ec..10166595 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpDst; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java index 9edfccb4..db7a60e0 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.api.util.OxmMatchConstants; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpSrc; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; @@ -109,4 +109,4 @@ private static void checkHeader(ByteBuf buffer, boolean hasMask) { assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java index 76fe9888..b9d2b0f5 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java @@ -46,7 +46,7 @@ */ public class ActionsDeserializerTest { - private static final Logger LOGGER = LoggerFactory + private static final Logger LOG = LoggerFactory .getLogger(ActionsDeserializerTest.class); private DeserializerRegistry registry; @@ -82,7 +82,7 @@ public void test() { + "00 1B 00 08 00 00 00 00"); message.skipBytes(4); // skip XID - LOGGER.info("bytes: {}", message.readableBytes()); + LOG.info("bytes: {}", message.readableBytes()); CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); List actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java index dcdbec18..29d0da2f 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java @@ -19,6 +19,7 @@ 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.OfHeader; +import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; /** @@ -107,7 +108,12 @@ public static void checkHeaderV10(OfHeader ofHeader) { checkHeader(ofHeader, (short) EncodeConstants.OF10_VERSION_ID); } - private static void checkHeader(OfHeader ofHeader, Short version) { + /** + * Check version and xid of OFP header. + * @param ofHeader OpenFlow protocol header + * @param version OpenFlow protocol version + */ + public static void checkHeader(OfHeader ofHeader, Short version) { Assert.assertEquals("Wrong version", version, ofHeader.getVersion()); Assert.assertEquals("Wrong Xid", DEFAULT_XID, ofHeader.getXid()); } @@ -134,7 +140,7 @@ public static void setupHeader(Object builder, int version) throws NoSuchMethodE * @param bb data input buffer * @return message decoded pojo */ - public static E deserialize(OFDeserializer decoder, ByteBuf bb) { + public static E deserialize(OFDeserializer decoder, ByteBuf bb) { return decoder.deserialize(bb); } diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java new file mode 100644 index 00000000..b5eead74 --- /dev/null +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java @@ -0,0 +1,50 @@ +/* + * 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.util; + +import io.netty.buffer.ByteBuf; +import java.util.List; +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.impl.deserialization.DeserializerRegistryImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * Super class for common stuff of deserialization factories tests. + */ +public abstract class DefaultDeserializerFactoryTest { + + private DeserializerRegistry registry; + protected OFDeserializer factory; + protected MessageCodeKey messageCodeKey; + + public DefaultDeserializerFactoryTest(final MessageCodeKey key) { + this.registry = new DeserializerRegistryImpl(); + this.registry.init(); + this.messageCodeKey = key; + this.factory = registry.getDeserializer(key); + } + + /** + * Test correct version after deserialization for all supported OF versions. + * @param versions supported OF versions + * @param buffer byte buffer to deserialze + */ + protected void testHeaderVersions(final List versions, final ByteBuf buffer) { + for (short version : versions) { + ByteBuf bb = buffer.copy(); + OFDeserializer factory = registry.getDeserializer( + new MessageCodeKey(version, messageCodeKey.getMsgType(), messageCodeKey.getClazz())); + T builtByFactory = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeader((OfHeader) builtByFactory, version); + } + } +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java index 4519deed..792f1f9d 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java @@ -22,9 +22,9 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +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.common.types.rev130731.Ipv6ExthdrFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.StandardMatchType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpOp; @@ -161,7 +161,7 @@ public void testIpv6Address() { key.setExperimenterId(null); OFDeserializer entryDeserializer = registry.getDeserializer(key); MatchEntry entry = entryDeserializer.deserialize(buffer); - Assert.assertEquals("Wrong Ipv6 address format", new Ipv6Address("0000:0001:0002:0003:0004:0005:0006:0F07"), + Assert.assertEquals("Wrong Ipv6 address format", new Ipv6Address("0:1:2:3:4:5:6:f07"), ((Ipv6SrcCase) entry.getMatchEntryValue()).getIpv6Src().getIpv6Address()); } @@ -401,7 +401,7 @@ public void testMatch() { Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry26.getOxmClass()); Assert.assertEquals("Wrong entry field", Ipv6Src.class, entry26.getOxmMatchField()); Assert.assertEquals("Wrong entry hasMask", true, entry26.isHasMask()); - Assert.assertEquals("Wrong entry value", new Ipv6Address("0000:0000:0000:0000:0000:0000:0000:0015"), + Assert.assertEquals("Wrong entry value", new Ipv6Address("::15"), ((Ipv6SrcCase) entry26.getMatchEntryValue()).getIpv6Src().getIpv6Address()); Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16"), @@ -410,7 +410,7 @@ public void testMatch() { Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry27.getOxmClass()); Assert.assertEquals("Wrong entry field", Ipv6Dst.class, entry27.getOxmMatchField()); Assert.assertEquals("Wrong entry hasMask", true, entry27.isHasMask()); - Assert.assertEquals("Wrong entry value", new Ipv6Address("0000:0000:0000:0000:0000:0000:0000:0017"), + Assert.assertEquals("Wrong entry value", new Ipv6Address("::17"), ((Ipv6DstCase) entry27.getMatchEntryValue()).getIpv6Dst().getIpv6Address()); Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18"), @@ -438,7 +438,7 @@ public void testMatch() { Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry31.getOxmClass()); Assert.assertEquals("Wrong entry field", Ipv6NdTarget.class, entry31.getOxmMatchField()); Assert.assertEquals("Wrong entry hasMask", false, entry31.isHasMask()); - Assert.assertEquals("Wrong entry value", new Ipv6Address("0000:0000:0000:0000:0000:0000:0000:0020"), + Assert.assertEquals("Wrong entry value", new Ipv6Address("::20"), ((Ipv6NdTargetCase) entry31.getMatchEntryValue()).getIpv6NdTarget().getIpv6Address()); MatchEntry entry32 = entries.get(32); Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry32.getOxmClass()); @@ -528,4 +528,4 @@ public void testStandardMatch() { Assert.assertEquals("Wrong match type", StandardMatchType.class, match.getType()); Assert.assertEquals("Wrong match entries size", 1, match.getMatchEntry().size()); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java index fdb15dd4..8c0d4eaa 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java @@ -8,17 +8,14 @@ package org.opendaylight.openflowjava.protocol.impl.util; import io.netty.buffer.ByteBuf; - import java.util.List; - 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.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializerRegistryImpl; -import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.EnqueueCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlDstCase; @@ -91,14 +88,12 @@ public void test() { Assert.assertTrue("Wrong action type", action4.getActionChoice() instanceof StripVlanCase); Action action5 = actions.get(4); Assert.assertTrue("Wrong action type", action5.getActionChoice() instanceof SetDlSrcCase); - Assert.assertArrayEquals("Wrong dl-src", ByteBufUtils.macAddressToBytes("01:02:03:04:05:06"), - ByteBufUtils.macAddressToBytes(((SetDlSrcCase) action5.getActionChoice()) - .getSetDlSrcAction().getDlSrcAddress().getValue())); + Assert.assertEquals("Wrong dl-src", "01:02:03:04:05:06", + ((SetDlSrcCase) action5.getActionChoice()).getSetDlSrcAction().getDlSrcAddress().getValue()); Action action6 = actions.get(5); Assert.assertTrue("Wrong action type", action6.getActionChoice() instanceof SetDlDstCase); - Assert.assertArrayEquals("Wrong dl-dst", ByteBufUtils.macAddressToBytes("02:03:04:05:06:07"), - ByteBufUtils.macAddressToBytes(((SetDlDstCase) action6.getActionChoice()) - .getSetDlDstAction().getDlDstAddress().getValue())); + Assert.assertEquals("Wrong dl-dst", "02:03:04:05:06:07", + ((SetDlDstCase) action6.getActionChoice()).getSetDlDstAction().getDlDstAddress().getValue()); Action action7 = actions.get(6); Assert.assertTrue("Wrong action type", action7.getActionChoice() instanceof SetNwSrcCase); Assert.assertEquals("Wrong nw-src", new Ipv4Address("10.0.0.1"), diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java index f66aa061..07f11eba 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java @@ -20,8 +20,8 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.action.rev150203.action.grouping.action.choice.EnqueueCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.OutputActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetDlDstCaseBuilder; @@ -219,4 +219,4 @@ public void test() { Assert.assertTrue("Written more bytes than needed", out.readableBytes() == 0); } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java index 83242ce4..d4f7b9be 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java @@ -18,8 +18,8 @@ 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; @@ -57,8 +57,8 @@ public void test() { Assert.assertEquals("Wrong srcMask", 24, match.getNwSrcMask().shortValue()); Assert.assertEquals("Wrong dstMask", 16, match.getNwDstMask().shortValue()); Assert.assertEquals("Wrong in-port", 32, match.getInPort().intValue()); - Assert.assertEquals("Wrong dl-src", new MacAddress("AA:BB:CC:DD:EE:FF"), match.getDlSrc()); - Assert.assertEquals("Wrong dl-dst", new MacAddress("AA:BB:CC:DD:EE:FF"), match.getDlDst()); + Assert.assertEquals("Wrong dl-src", new MacAddress("aa:bb:cc:dd:ee:ff"), match.getDlSrc()); + Assert.assertEquals("Wrong dl-dst", new MacAddress("aa:bb:cc:dd:ee:ff"), match.getDlDst()); Assert.assertEquals("Wrong dl-vlan", 5, match.getDlVlan().intValue()); Assert.assertEquals("Wrong dl-vlan-pcp", 16, match.getDlVlanPcp().shortValue()); Assert.assertEquals("Wrong dl-type", 8, match.getDlType().intValue()); @@ -85,8 +85,8 @@ public void test2() { Assert.assertEquals("Wrong srcMask", 0, match.getNwSrcMask().shortValue()); Assert.assertEquals("Wrong dstMask", 0, match.getNwDstMask().shortValue()); Assert.assertEquals("Wrong in-port", 32, match.getInPort().intValue()); - Assert.assertEquals("Wrong dl-src", new MacAddress("AA:BB:CC:DD:EE:FF"), match.getDlSrc()); - Assert.assertEquals("Wrong dl-dst", new MacAddress("AA:BB:CC:DD:EE:FF"), match.getDlDst()); + Assert.assertEquals("Wrong dl-src", new MacAddress("aa:bb:cc:dd:ee:ff"), match.getDlSrc()); + Assert.assertEquals("Wrong dl-dst", new MacAddress("aa:bb:cc:dd:ee:ff"), match.getDlDst()); Assert.assertEquals("Wrong dl-vlan", 5, match.getDlVlan().intValue()); Assert.assertEquals("Wrong dl-vlan-pcp", 16, match.getDlVlanPcp().shortValue()); Assert.assertEquals("Wrong dl-type", 8, match.getDlType().intValue()); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java index db16f9c5..4e27095e 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java @@ -20,8 +20,8 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +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.common.types.rev130731.FlowWildcardsV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder; diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java index a7bad7ae..e27c049a 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java @@ -21,11 +21,11 @@ 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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; +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.common.types.rev130731.EtherType; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; @@ -345,7 +345,7 @@ public void test() { TcpSrcCaseBuilder tcpSrcCaseBuilder = new TcpSrcCaseBuilder(); TcpSrcBuilder tcpSrcBuilder = new TcpSrcBuilder(); tcpSrcBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6653)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6653)); tcpSrcCaseBuilder.setTcpSrc(tcpSrcBuilder.build()); entryBuilder.setMatchEntryValue(tcpSrcCaseBuilder.build()); entries.add(entryBuilder.build()); @@ -356,7 +356,7 @@ public void test() { TcpDstCaseBuilder tcpDstCaseBuilder = new TcpDstCaseBuilder(); TcpDstBuilder tcpDstBuilder = new TcpDstBuilder(); tcpDstBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6654)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6654)); tcpDstCaseBuilder.setTcpDst(tcpDstBuilder.build()); entryBuilder.setMatchEntryValue(tcpDstCaseBuilder.build()); entries.add(entryBuilder.build()); @@ -367,7 +367,7 @@ public void test() { UdpSrcCaseBuilder udpSrcCaseBuilder = new UdpSrcCaseBuilder(); UdpSrcBuilder udpSrcBuilder = new UdpSrcBuilder(); udpSrcBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6655)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6655)); udpSrcCaseBuilder.setUdpSrc(udpSrcBuilder.build()); entryBuilder.setMatchEntryValue(udpSrcCaseBuilder.build()); entries.add(entryBuilder.build()); @@ -378,7 +378,7 @@ public void test() { UdpDstCaseBuilder udpDstCaseBuilder = new UdpDstCaseBuilder(); UdpDstBuilder udpDstBuilder = new UdpDstBuilder(); udpDstBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6656)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6656)); udpDstCaseBuilder.setUdpDst(udpDstBuilder.build()); entryBuilder.setMatchEntryValue(udpDstCaseBuilder.build()); entries.add(entryBuilder.build()); @@ -389,7 +389,7 @@ public void test() { SctpSrcCaseBuilder sctpSrcCaseBuilder = new SctpSrcCaseBuilder(); SctpSrcBuilder sctpSrcBuilder = new SctpSrcBuilder(); sctpSrcBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6657)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6657)); sctpSrcCaseBuilder.setSctpSrc(sctpSrcBuilder.build()); entryBuilder.setMatchEntryValue(sctpSrcCaseBuilder.build()); entries.add(entryBuilder.build()); @@ -400,7 +400,7 @@ public void test() { SctpDstCaseBuilder sctpDstCaseBuilder = new SctpDstCaseBuilder(); SctpDstBuilder sctpDstBuilder = new SctpDstBuilder(); sctpDstBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params - .xml.ns.yang.ietf.inet.types.rev100924.PortNumber(6658)); + .xml.ns.yang.ietf.inet.types.rev130715.PortNumber(6658)); sctpDstCaseBuilder.setSctpDst(sctpDstBuilder.build()); entryBuilder.setMatchEntryValue(sctpDstCaseBuilder.build()); entries.add(entryBuilder.build()); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java index 999607d2..0c2a6aa0 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java @@ -23,9 +23,11 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; import org.opendaylight.openflowjava.util.ByteBufUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6FlowLabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.TcpFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.approved.extensions.rev160802.oxm.container.match.entry.value.experimenter.id._case.TcpFlagsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.experimenter.id._case.ExperimenterBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; @@ -283,7 +285,7 @@ public void testIpv6Flabel() { byte[] label = new byte[4]; out.readBytes(label); - LOG.debug("label: "+ ByteBufUtils.bytesToHexString(label)); + LOG.debug("label: {}", ByteBufUtils.bytesToHexString(label)); Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label); } @@ -395,4 +397,4 @@ public void testSerializeExperimenterMatchEntry() { private class OxmMatchFieldClass extends MatchField { // only for testing purposes } -} \ No newline at end of file +} diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java index fb641622..6f2f772c 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java @@ -21,7 +21,7 @@ */ public class StatisticsCountersTest { - private static final Logger LOGGER = LoggerFactory.getLogger(StatisticsCountersTest.class); + private static final Logger LOG = LoggerFactory.getLogger(StatisticsCountersTest.class); private StatisticsCounters statCounters; /** @@ -81,7 +81,7 @@ public void testCounterLastRead() { Assert.fail("No counter is enabled"); } incrementCounter(firstEnabledCET,testCount); - LOGGER.debug("Waiting to process event queue"); + LOG.debug("Waiting to process event queue"); Assert.assertEquals("Wrong - bad last read value.", 0,statCounters.getCounter(firstEnabledCET).getCounterLastReadValue()); Assert.assertEquals("Wrong - bad value", testCount,statCounters.getCounter(firstEnabledCET).getCounterValue(false)); Assert.assertEquals("Wrong - bad last read value.", 0,statCounters.getCounter(firstEnabledCET).getCounterLastReadValue()); diff --git a/openflow-protocol-it/pom.xml b/openflow-protocol-it/pom.xml index 436f8bdf..58628b30 100644 --- a/openflow-protocol-it/pom.xml +++ b/openflow-protocol-it/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java b/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java index 54ccb37e..77e747a9 100644 --- a/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java +++ b/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java @@ -14,7 +14,6 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; - import org.junit.After; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; @@ -65,19 +64,20 @@ private enum ClientType {SIMPLE, LISTENING} * @param protocol communication protocol to be used during test * @throws Exception */ - public void setUp(TransportProtocol protocol) throws Exception { + public void setUp(final TransportProtocol protocol) throws Exception { LOGGER.debug("\n starting test -------------------------------"); - String currentDir = System.getProperty("user.dir"); + final String currentDir = System.getProperty("user.dir"); LOGGER.debug("Current dir using System: {}", currentDir); startupAddress = InetAddress.getLocalHost(); tlsConfiguration = null; if (protocol.equals(TransportProtocol.TLS)) { tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH, KeystoreType.JKS, - "/selfSignedController", PathType.CLASSPATH) ; + "/selfSignedController", PathType.CLASSPATH, + new ArrayList()); } - connConfig = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT); + connConfig = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true); connConfig.setTransferProtocol(protocol); mockPlugin = new MockPlugin(); @@ -86,10 +86,10 @@ public void setUp(TransportProtocol protocol) throws Exception { switchConnectionProvider.setConfiguration(connConfig); switchConnectionProvider.startup().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); if (protocol.equals(TransportProtocol.TCP) || protocol.equals(TransportProtocol.TLS)) { - TcpHandler tcpHandler = (TcpHandler) switchConnectionProvider.getServerFacade(); + final TcpHandler tcpHandler = (TcpHandler) switchConnectionProvider.getServerFacade(); port = tcpHandler.getPort(); } else { - UdpHandler udpHandler = (UdpHandler) switchConnectionProvider.getServerFacade(); + final UdpHandler udpHandler = (UdpHandler) switchConnectionProvider.getServerFacade(); port = udpHandler.getPort(); } } @@ -110,11 +110,11 @@ public void tearDown() throws Exception { @Test public void testHandshake() throws Exception { setUp(TransportProtocol.TCP); - int amountOfCLients = 1; - Deque scenario = ScenarioFactory.createHandshakeScenario(); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TCP, ClientType.SIMPLE); - OFClient firstClient = clients.get(0); + final int amountOfCLients = 1; + final Deque scenario = ScenarioFactory.createHandshakeScenario(); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TCP, ClientType.SIMPLE); + final OFClient firstClient = clients.get(0); firstClient.getScenarioDone().get(); Thread.sleep(1000); @@ -128,11 +128,11 @@ public void testHandshake() throws Exception { @Test public void testTlsHandshake() throws Exception { setUp(TransportProtocol.TLS); - int amountOfCLients = 1; - Deque scenario = ScenarioFactory.createHandshakeScenario(); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TLS, ClientType.SIMPLE); - OFClient firstClient = clients.get(0); + final int amountOfCLients = 1; + final Deque scenario = ScenarioFactory.createHandshakeScenario(); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TLS, ClientType.SIMPLE); + final OFClient firstClient = clients.get(0); firstClient.getScenarioDone().get(); Thread.sleep(1000); @@ -146,15 +146,15 @@ public void testTlsHandshake() throws Exception { @Test public void testHandshakeAndEcho() throws Exception { setUp(TransportProtocol.TCP); - int amountOfCLients = 1; - Deque scenario = ScenarioFactory.createHandshakeScenario(); + final int amountOfCLients = 1; + final Deque scenario = ScenarioFactory.createHandshakeScenario(); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04"))); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04"))); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TCP, ClientType.SIMPLE); - OFClient firstClient = clients.get(0); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TCP, ClientType.SIMPLE); + final OFClient firstClient = clients.get(0); firstClient.getScenarioDone().get(); LOGGER.debug("testHandshakeAndEcho() Finished") ; @@ -167,15 +167,15 @@ public void testHandshakeAndEcho() throws Exception { @Test public void testTlsHandshakeAndEcho() throws Exception { setUp(TransportProtocol.TLS); - int amountOfCLients = 1; - Deque scenario = ScenarioFactory.createHandshakeScenario(); + final int amountOfCLients = 1; + final Deque scenario = ScenarioFactory.createHandshakeScenario(); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04"))); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04"))); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TLS, ClientType.SIMPLE); - OFClient firstClient = clients.get(0); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.TLS, ClientType.SIMPLE); + final OFClient firstClient = clients.get(0); firstClient.getScenarioDone().get(); LOGGER.debug("testTlsHandshakeAndEcho() Finished") ; @@ -188,15 +188,15 @@ public void testTlsHandshakeAndEcho() throws Exception { @Test public void testUdpHandshakeAndEcho() throws Exception { setUp(TransportProtocol.UDP); - int amountOfCLients = 1; - Deque scenario = ScenarioFactory.createHandshakeScenario(); + final int amountOfCLients = 1; + final Deque scenario = ScenarioFactory.createHandshakeScenario(); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 02 00 08 00 00 00 04"))); scenario.addFirst(new SleepEvent(1000)); scenario.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 03 00 08 00 00 00 04"))); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.UDP, ClientType.SIMPLE); - OFClient firstClient = clients.get(0); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(amountOfCLients, handler, TransportProtocol.UDP, ClientType.SIMPLE); + final OFClient firstClient = clients.get(0); firstClient.getScenarioDone().get(); LOGGER.debug("testUdpHandshakeAndEcho() Finished") ; @@ -217,9 +217,9 @@ public void testCommunicationWithVM() throws Exception { * @return new clients up and running * @throws ExecutionException if some client could not start */ - private List createAndStartClient(int amountOfCLients, ScenarioHandler scenarioHandler, - TransportProtocol protocol, ClientType clientType) throws ExecutionException { - List clientsHorde = new ArrayList<>(); + private List createAndStartClient(final int amountOfCLients, final ScenarioHandler scenarioHandler, + final TransportProtocol protocol, final ClientType clientType) throws ExecutionException { + final List clientsHorde = new ArrayList<>(); for (int i = 0; i < amountOfCLients; i++) { LOGGER.debug("startup address in createclient: {}", startupAddress.getHostAddress()); OFClient sc = null; @@ -248,10 +248,10 @@ private List createAndStartClient(int amountOfCLients, ScenarioHandler t = new Thread(sc); t.start(); } - for (OFClient sc : clientsHorde) { + for (final OFClient sc : clientsHorde) { try { sc.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); - } catch (Exception e) { + } catch (final Exception e) { LOGGER.error("createAndStartClient: Something borked ... ", e.getMessage(), e); throw new ExecutionException(e); } @@ -266,12 +266,12 @@ private List createAndStartClient(int amountOfCLients, ScenarioHandler public void testInitiateConnection() throws Exception { setUp(TransportProtocol.TCP); - Deque scenario = ScenarioFactory.createHandshakeScenario(); - ScenarioHandler handler = new ScenarioHandler(scenario); - List clients = createAndStartClient(1, handler, TransportProtocol.TCP, ClientType.LISTENING); - OFClient ofClient = clients.get(0); + final Deque scenario = ScenarioFactory.createHandshakeScenario(); + final ScenarioHandler handler = new ScenarioHandler(scenario); + final List clients = createAndStartClient(1, handler, TransportProtocol.TCP, ClientType.LISTENING); + final OFClient ofClient = clients.get(0); ofClient.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); - int listeningClientPort = ((ListeningSimpleClient) ofClient).getPort(); + final int listeningClientPort = ((ListeningSimpleClient) ofClient).getPort(); mockPlugin.initiateConnection(switchConnectionProvider, "localhost", listeningClientPort); ofClient.getScenarioDone().get(); LOGGER.debug("testInitiateConnection() Finished") ; diff --git a/openflow-protocol-spi/pom.xml b/openflow-protocol-spi/pom.xml index 8ec7ea7e..67a9aa90 100644 --- a/openflow-protocol-spi/pom.xml +++ b/openflow-protocol-spi/pom.xml @@ -3,13 +3,15 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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 @@ -23,10 +25,7 @@ true - - org.opendaylight.openflowjava.protocol.spi*, - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.* - + org.opendaylight.openflowjava.protocol.api.keys,* @@ -53,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 @@ -75,7 +74,7 @@ org.opendaylight.mdsal maven-sal-api-gen-plugin - ${yangtools.version} + ${mdsal.model.version} jar diff --git a/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java b/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java index c6910b14..b013471f 100644 --- a/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java +++ b/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java @@ -29,6 +29,12 @@ public interface SwitchConnectionProvider extends AutoCloseable, */ void setConfiguration(ConnectionConfiguration configuration); + /** + * return the connection configuration + * @return configuration [protocol, port, address and supported features] + */ + ConnectionConfiguration getConfiguration(); + /** * start listening to switches, but please don't forget to do * {@link #setSwitchConnectionHandler(SwitchConnectionHandler)} first diff --git a/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java b/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java new file mode 100644 index 00000000..9ef8c4dd --- /dev/null +++ b/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowjava.protocol.spi.connection; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; + +/** + * Factory for creating SwitchConnectionProvider instances. + * + * @author Thomas Pantelis + */ +public interface SwitchConnectionProviderFactory { + /** + * Creates a new SwitchConnectionProvider with the given configuration. + * + * @param config the SwitchConnectionConfig + * @return a SwitchConnectionProvider instance + */ + SwitchConnectionProvider newInstance(SwitchConnectionConfig config); +} diff --git a/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang b/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang new file mode 100644 index 00000000..091f02a5 --- /dev/null +++ b/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang @@ -0,0 +1,116 @@ +module openflow-switch-connection-config { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:config"; + prefix "openflow-switch-connection-config"; + + import ietf-inet-types {prefix ietf-inet; revision-date 2013-07-15; } + import openflow-configuration {prefix of-config; revision-date 2014-06-30; } + + description + "Configuration for an Openflow switch connection."; + + revision "2016-05-06" { + description + "Initial revision"; + } + + list switch-connection-config { + key "instance-name"; + + leaf instance-name { + description "Name of the switch connection instance."; + type string; + } + + leaf port { + description "local listening port"; + type uint16; + mandatory true; + } + + leaf transport-protocol { + description "Transport protocol used for communication."; + type of-config:transport-protocol; + mandatory true; + } + + leaf address { + description "address of local listening interface"; + type ietf-inet:ip-address; + } + + leaf use-barrier { + description "Enable barrier in Openflow java"; + type boolean; + default true; + } + + leaf switch-idle-timeout { + description "idle timeout in [ms]"; + type uint32; + default 15000; + } + + container tls { + leaf keystore { + description "keystore location"; + type string; + } + + leaf keystore-type { + description "keystore type (JKS or PKCS12)"; + type of-config:keystore-type; + } + + leaf keystore-path-type { + description "keystore path type (CLASSPATH or PATH)"; + type of-config:path-type; + } + + leaf keystore-password { + description "password protecting keystore"; + type string; + } + + leaf certificate-password { + description "password protecting certificate"; + type string; + } + + leaf truststore { + description "truststore location"; + type string; + } + + leaf truststore-type { + description "truststore type (JKS or PKCS12)"; + type of-config:keystore-type; + } + + leaf truststore-path-type { + description "truststore path type (CLASSPATH or PATH)"; + type of-config:path-type; + } + + leaf truststore-password { + description "password protecting truststore"; + type string; + } + + leaf-list cipher-suites { + description "combination of cryptographic algorithms used by TLS connection"; + type string; + } + } + + container threads { + leaf boss-threads { + type uint16; + } + + leaf worker-threads { + type uint16; + } + } + } +} diff --git a/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang b/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang index 3ed7c20b..25b38d19 100644 --- a/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang +++ b/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang @@ -16,6 +16,8 @@ module openflow-switch-connection-provider { identity openflow-switch-connection-provider { base "config:service-type"; config:java-class "org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider"; + config:disable-osgi-service-registration; + status deprecated; } identity statistics-collection-service { diff --git a/openflowjava-blueprint-config/pom.xml b/openflowjava-blueprint-config/pom.xml new file mode 100644 index 00000000..71efa0d2 --- /dev/null +++ b/openflowjava-blueprint-config/pom.xml @@ -0,0 +1,68 @@ + + + + + 4.0.0 + + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + openflowjava-blueprint-config + Blueprint configuration files for openflowjava statistics + bundle + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + org.apache.felix + maven-bundle-plugin + true + + + * + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/initial/default-openflow-connection-config.xml + xml + config + + + ${project.build.directory}/classes/initial/legacy-openflow-connection-config.xml + xml + legacyConfig + + + + + + + + + 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 new file mode 100644 index 00000000..08b8a52e --- /dev/null +++ b/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml @@ -0,0 +1,17 @@ + + openflow-switch-connection-provider-default-impl + 6653 + TCP + + configuration/ssl/ctl.jks + JKS + PATH + opendaylight + configuration/ssl/truststore.jks + JKS + PATH + opendaylight + opendaylight + + + \ No newline at end of file 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 new file mode 100644 index 00000000..13860139 --- /dev/null +++ b/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml @@ -0,0 +1,17 @@ + + openflow-switch-connection-provider-legacy-impl + 6633 + TCP + + configuration/ssl/ctl.jks + JKS + PATH + opendaylight + configuration/ssl/truststore.jks + JKS + PATH + opendaylight + opendaylight + + + \ No newline at end of file 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 new file mode 100644 index 00000000..e1d3c000 --- /dev/null +++ b/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openflowjava-config/pom.xml b/openflowjava-config/pom.xml index ad7c00fa..419a0609 100644 --- a/openflowjava-config/pom.xml +++ b/openflowjava-config/pom.xml @@ -11,13 +11,15 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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 7b78d39e..c296e5a7 100644 --- a/openflowjava-util/pom.xml +++ b/openflowjava-util/pom.xml @@ -5,11 +5,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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 d68f6f9c..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,10 +15,17 @@ 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; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.IetfYangUtil; +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.protocol.rev130731.OfHeader; /** Class for common operations on ByteBuf @@ -129,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 @@ -219,7 +235,7 @@ private static int hexValue(final char c) { /** * Converts macAddress to byte array. - * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}. + * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress}. * * @param macAddress * @return byte representation of mac address @@ -275,7 +291,7 @@ private static void appendHexUnsignedShort(final StringBuilder sb, final int val /** * Converts a MAC address represented in bytes to String. - * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress}. + * See also {@link org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress}. * * @param address * @return String representation of a MAC address @@ -324,6 +340,7 @@ public static String readIpv4Address(final ByteBuf buf) { return sb.toString(); } + /** * Read an IPv6 address from a buffer and format it into a string of eight groups of four * hexadecimal digits separated by colons. @@ -342,4 +359,30 @@ public static String readIpv6Address(final ByteBuf buf) { return sb.toString(); } + + public static Ipv4Address readIetfIpv4Address(final ByteBuf buf) { + final byte[] tmp = new byte[4]; + buf.readBytes(tmp); + return IetfInetUtil.INSTANCE.ipv4AddressFor(tmp); + } + + public static Ipv6Address readIetfIpv6Address(final ByteBuf buf) { + final byte[] tmp = new byte[16]; + buf.readBytes(tmp); + return IetfInetUtil.INSTANCE.ipv6AddressFor(tmp); + } + + public static MacAddress readIetfMacAddress(final ByteBuf buf) { + final byte[] tmp = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + 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 6c65deed..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 @@ -18,7 +18,6 @@ /** * @author michal.polkorab - * */ public abstract class ExperimenterDeserializerKeyFactory { @@ -107,4 +106,5 @@ public static ExperimenterIdDeserializerKey createMeterBandDeserializerKey( short version, Long experimenterId) { return new ExperimenterIdDeserializerKey(version, experimenterId, MeterBandExperimenterCase.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 old mode 100644 new mode 100755 index edc6f25e..ea0a69ce --- a/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java @@ -8,15 +8,16 @@ package org.opendaylight.openflowjava.util; +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.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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; /** * @author michal.polkorab - * */ public abstract class ExperimenterSerializerKeyFactory { @@ -59,6 +60,12 @@ public static ExperimenterIdSerializerKey createMultipar */ public static ExperimenterIdSerializerKey createMeterBandSerializerKey( short msgVersion, long experimenterId) { - return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, MeterBandExperimenterCase.class); + return new ExperimenterIdMeterSubTypeSerializerKey<>(msgVersion, experimenterId, MeterBandExperimenterCase.class, null); } + + public static ExperimenterIdSerializerKey createMeterBandSerializerKey( + short msgVersion, long experimenterId, Class meterSubType) { + return new ExperimenterIdMeterSubTypeSerializerKey<>(msgVersion, experimenterId, MeterBandExperimenterCase.class, meterSubType); + } + } \ 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/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java old mode 100644 new mode 100755 index 211186d7..471e4133 --- a/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java +++ b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java @@ -10,9 +10,11 @@ import org.junit.Assert; import org.junit.Test; +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.openflowjava.protocol.api.util.EncodeConstants; +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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; @@ -71,4 +73,32 @@ public void testCreateMeterBandSerializerKey() throws Exception { 43L, MeterBandExperimenterCase.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); } + + @Test + public void testCreateMeterBandSubTypeSerializerKey() throws Exception { + ExperimenterIdSerializerKey createdKey; + ExperimenterIdSerializerKey comparationKey1; + ExperimenterIdSerializerKey comparationKey2; + ExperimenterIdSerializerKey comparationKey3; + ExperimenterIdSerializerKey comparationKey4; + ExperimenterIdSerializerKey comparationKey5; + + createdKey = ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( + EncodeConstants.OF10_VERSION_ID, 43L, ExperimenterMeterBandSubType.class); + comparationKey1 = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF13_VERSION_ID, + 43L, MeterBandExperimenterCase.class, ExperimenterMeterBandSubType.class); + comparationKey2 = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 42L, MeterBandExperimenterCase.class, ExperimenterMeterBandSubType.class); + comparationKey3 = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 43L, null, ExperimenterMeterBandSubType.class); + comparationKey4 = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 43L, MeterBandExperimenterCase.class, null); + comparationKey5 = new ExperimenterIdMeterSubTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 43L, MeterBandExperimenterCase.class, ExperimenterMeterBandSubType.class); + Assert.assertNotEquals("Wrong key created", comparationKey1, createdKey); + Assert.assertNotEquals("Wrong key created", comparationKey2, createdKey); + Assert.assertNotEquals("Wrong key created", comparationKey3, createdKey); + Assert.assertNotEquals("Wrong key created", comparationKey4, createdKey); + Assert.assertEquals("Wrong key created", comparationKey5, createdKey); + } } \ No newline at end of file diff --git a/parent/pom.xml b/parent/pom.xml index 59048b9a..4238e080 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -4,15 +4,17 @@ org.opendaylight.odlparent odlparent - 1.6.0-SNAPSHOT + 2.0.0 org.opendaylight.openflowjava openflowjava-parent - 0.7.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. @@ -49,15 +51,15 @@ - dav:http://nexus.opendaylight.org/content/sites/site UTF-8 ${project.build.directory}/yang-gen-config - 1.6.0-SNAPSHOT ${project.build.directory}/yang-gen-sal - 0.4.0-SNAPSHOT - 1.3.0-SNAPSHOT - 0.8.0-SNAPSHOT + 0.7.0-SNAPSHOT + 1.6.0-SNAPSHOT + 0.11.0-SNAPSHOT + 1.2.0-SNAPSHOT + 0.7.0 @@ -86,10 +88,15 @@ org.opendaylight.controller mdsal-artifacts - ${mdsal.version} + ${controller.mdsal.version} 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 56e8b447..e3eda8b0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.0-SNAPSHOT + 0.10.0-SNAPSHOT parent @@ -15,6 +15,7 @@ artifacts features openflowjava-config + openflowjava-blueprint-config openflow-protocol-api openflow-protocol-impl openflow-protocol-it diff --git a/simple-client/pom.xml b/simple-client/pom.xml index 484b3759..b399646e 100644 --- a/simple-client/pom.xml +++ b/simple-client/pom.xml @@ -3,12 +3,14 @@ org.opendaylight.openflowjava openflowjava-parent - 0.7.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 @@ -44,7 +46,10 @@ org.slf4j slf4j-log4j12 - ${slf4j.version} + + + 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/ListeningSimpleClient.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java index 559c2279..5afb039f 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java @@ -29,7 +29,7 @@ */ public class ListeningSimpleClient implements OFClient { - private static final Logger LOGGER = LoggerFactory.getLogger(ListeningSimpleClient.class); + private static final Logger LOG = LoggerFactory.getLogger(ListeningSimpleClient.class); private int port; private boolean securedClient = false; private EventLoopGroup workerGroup; @@ -73,21 +73,21 @@ public void run() { isOnlineFuture.set(true); synchronized (scenarioHandler) { - LOGGER.debug("WAITING FOR SCENARIO"); + LOG.debug("WAITING FOR SCENARIO"); while (! scenarioHandler.isScenarioFinished()) { scenarioHandler.wait(); } } } catch (Exception ex) { - LOGGER.error(ex.getMessage(), ex); + LOG.error(ex.getMessage(), ex); } finally { - LOGGER.debug("listening client shutting down"); + LOG.debug("listening client shutting down"); try { workerGroup.shutdownGracefully().get(); bossGroup.shutdownGracefully().get(); - LOGGER.debug("listening client shutdown succesful"); + LOG.debug("listening client shutdown succesful"); } catch (InterruptedException | ExecutionException e) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } scenarioDone.set(true); @@ -97,7 +97,7 @@ public void run() { * @return close future */ public Future disconnect() { - LOGGER.debug("disconnecting client"); + LOG.debug("disconnecting client"); return workerGroup.shutdownGracefully(); } 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 57865d88..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 @@ -25,60 +25,74 @@ */ public class ScenarioHandler extends Thread { - private static final Logger LOGGER = LoggerFactory.getLogger(ScenarioHandler.class); + 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; while (!scenario.isEmpty()) { - LOGGER.debug("Running event #{}", eventNumber); + LOG.debug("Running event #{}", eventNumber); ClientEvent peek = scenario.peekLast(); if (peek instanceof WaitForMessageEvent) { - LOGGER.debug("WaitForMessageEvent"); + LOG.debug("WaitForMessageEvent"); try { WaitForMessageEvent event = (WaitForMessageEvent) peek; event.setHeaderReceived(ofMsg.poll(2000, TimeUnit.MILLISECONDS)); } catch (InterruptedException e) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); break; } } else if (peek instanceof SendEvent) { - LOGGER.debug("Proceed - sendevent"); + LOG.debug("Proceed - sendevent"); SendEvent event = (SendEvent) peek; 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) { - LOGGER.warn("Scenario frozen: {}", freezeCounter); + 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) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } - LOGGER.debug("Scenario finished"); + LOG.debug("Scenario finished"); synchronized (this) { scenarioFinished = true; this.notify(); @@ -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 3f456d12..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 @@ -22,7 +22,7 @@ */ public class SendEvent implements ClientEvent { - protected static final Logger LOGGER = LoggerFactory.getLogger(SendEvent.class); + private static final Logger LOG = LoggerFactory.getLogger(SendEvent.class); protected byte[] msgToSend; protected ChannelHandlerContext ctx; @@ -31,22 +31,20 @@ 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 public boolean eventExecuted() { - LOGGER.debug("sending message"); - LOGGER.debug("start of run"); + LOG.debug("sending message"); + LOG.debug("start of run"); ByteBuf buffer = ctx.alloc().buffer(); buffer.writeBytes(msgToSend); ctx.writeAndFlush(buffer); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(">> {}", ByteBufUtils.bytesToHexString(msgToSend)); - LOGGER.debug("message sent"); + if (LOG.isDebugEnabled()) { + LOG.debug(">> {}", ByteBufUtils.bytesToHexString(msgToSend)); + LOG.debug("message sent"); } return true; } diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java index 5e98e3d6..fb0fda09 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java @@ -29,7 +29,7 @@ */ public class SimpleClient implements OFClient { - private static final Logger LOGGER = LoggerFactory.getLogger(SimpleClient.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleClient.class); private final String host; private final int port; private boolean securedClient = false; @@ -72,20 +72,20 @@ public void run() { b.connect(host, port).sync(); synchronized (scenarioHandler) { - LOGGER.debug("WAITING FOR SCENARIO"); + LOG.debug("WAITING FOR SCENARIO"); while (! scenarioHandler.isScenarioFinished()) { scenarioHandler.wait(); } } } catch (Exception ex) { - LOGGER.error(ex.getMessage(), ex); + LOG.error(ex.getMessage(), ex); } finally { - LOGGER.debug("shutting down"); + LOG.debug("shutting down"); try { group.shutdownGracefully().get(); - LOGGER.debug("shutdown succesful"); + LOG.debug("shutdown succesful"); } catch (InterruptedException | ExecutionException e) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } scenarioDone.set(true); @@ -95,7 +95,7 @@ public void run() { * @return close future */ public Future disconnect() { - LOGGER.debug("disconnecting client"); + LOG.debug("disconnecting client"); return group.shutdownGracefully(); } @@ -115,8 +115,8 @@ public static void main(String[] args) throws Exception { int port; SimpleClient sc; if (args.length != 3) { - LOGGER.error("Usage: {} ", SimpleClient.class.getSimpleName()); - LOGGER.error("Trying to use default setting."); + LOG.error("Usage: {} ", SimpleClient.class.getSimpleName()); + LOG.error("Trying to use default setting."); InetAddress ia = InetAddress.getLocalHost(); InetAddress[] all = InetAddress.getAllByName(ia.getHostName()); host = all[0].getHostAddress(); diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java index 1420ad8d..02c9cd98 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java @@ -28,34 +28,34 @@ public class SimpleClientFramer extends ByteToMessageDecoder { /** Length of OpenFlow 1.3 header */ public static final byte LENGTH_OF_HEADER = 8; private static final byte LENGTH_INDEX_IN_HEADER = 2; - private static final Logger LOGGER = LoggerFactory.getLogger(SimpleClientFramer.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleClientFramer.class); /** * Constructor of class. */ public SimpleClientFramer() { - LOGGER.trace("Creating OFFrameDecoder"); + LOG.trace("Creating OFFrameDecoder"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - LOGGER.warn("Unexpected exception from downstream.", cause); + LOG.warn("Unexpected exception from downstream.", cause); ctx.close(); } @Override protected void decode(ChannelHandlerContext chc, ByteBuf bb, List list) throws Exception { if (bb.readableBytes() < LENGTH_OF_HEADER) { - LOGGER.debug("skipping bb - too few data for header: {}", bb.readableBytes()); + LOG.debug("skipping bb - too few data for header: {}", bb.readableBytes()); return; } int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); if (bb.readableBytes() < length) { - LOGGER.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); + LOG.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); return; } - LOGGER.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); list.add(messageBuffer); diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java index acc53834..863f9aeb 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java @@ -25,7 +25,7 @@ */ public class SimpleClientHandler extends ChannelInboundHandlerAdapter { - protected static final Logger LOGGER = LoggerFactory.getLogger(SimpleClientHandler.class); + private static final Logger LOG = LoggerFactory.getLogger(SimpleClientHandler.class); private static final int LENGTH_INDEX_IN_HEADER = 2; private SettableFuture isOnlineFuture; protected ScenarioHandler scenarioHandler; @@ -42,20 +42,20 @@ public SimpleClientHandler(SettableFuture isOnlineFuture, ScenarioHandl @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf bb = (ByteBuf) msg; - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("<< {}", ByteBufUtils.byteBufToHexString(bb)); + if (LOG.isDebugEnabled()) { + LOG.debug("<< {}", ByteBufUtils.byteBufToHexString(bb)); } int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); - LOGGER.trace("SimpleClientHandler - start of read"); + LOG.trace("SimpleClientHandler - start of read"); byte[] message = new byte[length]; bb.readBytes(message); scenarioHandler.addOfMsg(message); - LOGGER.trace("end of read"); + LOG.trace("end of read"); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { - LOGGER.debug("Client is active"); + LOG.debug("Client is active"); if (isOnlineFuture != null) { isOnlineFuture.set(true); isOnlineFuture = null; 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 a2fe3a11..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 @@ -11,7 +11,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; -import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.channel.socket.SocketChannel; import io.netty.handler.ssl.SslHandler; import javax.net.ssl.SSLEngine; @@ -22,10 +22,10 @@ * * @author michal.polkorab */ -public class SimpleClientInitializer extends ChannelInitializer { +public class SimpleClientInitializer extends ChannelInitializer { private SettableFuture isOnlineFuture; - private boolean secured; + private final boolean secured; private ScenarioHandler scenarioHandler; /** @@ -38,7 +38,7 @@ public SimpleClientInitializer(SettableFuture isOnlineFuture, boolean s } @Override - public void initChannel(NioSocketChannel ch) throws Exception { + public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); if (secured) { SSLEngine engine = ClientSslContextFactory.getClientContext() diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java index b1e1a50c..19229abc 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java @@ -18,7 +18,7 @@ */ public class SleepEvent implements ClientEvent { - private static final Logger LOGGER = LoggerFactory.getLogger(SleepEvent.class); + private static final Logger LOG = LoggerFactory.getLogger(SleepEvent.class); private long sleepTime; /** @@ -33,10 +33,10 @@ public SleepEvent(long sleepTime) { public boolean eventExecuted() { try { Thread.sleep(sleepTime); - LOGGER.debug("Sleeping"); + LOG.debug("Sleeping"); return true; } catch (InterruptedException e) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } return false; } 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/UdpSimpleClient.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java index e9d4644e..f7ff0a61 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java @@ -30,7 +30,7 @@ */ public class UdpSimpleClient implements OFClient { - private static final Logger LOGGER = LoggerFactory.getLogger(UdpSimpleClient.class); + private static final Logger LOG = LoggerFactory.getLogger(UdpSimpleClient.class); private final String host; private final int port; private EventLoopGroup group; @@ -73,20 +73,20 @@ public void run() { b.connect(host, port).sync(); synchronized (scenarioHandler) { - LOGGER.debug("WAITING FOR SCENARIO"); + LOG.debug("WAITING FOR SCENARIO"); while (! scenarioHandler.isScenarioFinished()) { scenarioHandler.wait(); } } } catch (Exception ex) { - LOGGER.error(ex.getMessage(), ex); + LOG.error(ex.getMessage(), ex); } finally { - LOGGER.debug("shutting down"); + LOG.debug("shutting down"); try { group.shutdownGracefully().get(); - LOGGER.debug("shutdown succesful"); + LOG.debug("shutdown succesful"); } catch (InterruptedException | ExecutionException e) { - LOGGER.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } scenarioDone.set(true); @@ -96,7 +96,7 @@ public void run() { * @return close future */ public Future disconnect() { - LOGGER.debug("disconnecting client"); + LOG.debug("disconnecting client"); return group.shutdownGracefully(); } @@ -111,8 +111,8 @@ public static void main(String[] args) throws Exception { int port; UdpSimpleClient sc; if (args.length != 2) { - LOGGER.error("Usage: {} ", UdpSimpleClient.class.getSimpleName()); - LOGGER.error("Trying to use default setting."); + LOG.error("Usage: {} ", UdpSimpleClient.class.getSimpleName()); + LOG.error("Trying to use default setting."); InetAddress ia = InetAddress.getLocalHost(); InetAddress[] all = InetAddress.getAllByName(ia.getHostName()); host = all[0].getHostAddress(); diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java index be73d27c..b893a8f3 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java @@ -29,18 +29,18 @@ public class UdpSimpleClientFramer extends MessageToMessageDecoder list) throws Exception { ByteBuf bb = msg.content(); if (bb.readableBytes() < LENGTH_OF_HEADER) { - LOGGER.debug("skipping bb - too few data for header: {}", bb.readableBytes()); + LOG.debug("skipping bb - too few data for header: {}", bb.readableBytes()); return; } int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); if (bb.readableBytes() < length) { - LOGGER.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); + LOG.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); return; } - LOGGER.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); list.add(messageBuffer); diff --git a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java index 11444427..a68b6ab7 100644 --- a/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java +++ b/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java @@ -11,7 +11,7 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; -import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.channel.socket.DatagramChannel; import com.google.common.util.concurrent.SettableFuture; @@ -19,7 +19,7 @@ * * @author michal.polkorab */ -public class UdpSimpleClientInitializer extends ChannelInitializer { +public class UdpSimpleClientInitializer extends ChannelInitializer { private SettableFuture isOnlineFuture; private ScenarioHandler scenarioHandler; @@ -32,7 +32,7 @@ public UdpSimpleClientInitializer(SettableFuture isOnlineFuture) { } @Override - public void initChannel(NioDatagramChannel ch) throws Exception { + public void initChannel(DatagramChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); SimpleClientHandler simpleClientHandler = new SimpleClientHandler(isOnlineFuture, scenarioHandler); simpleClientHandler.setScenario(scenarioHandler); 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 b448111a..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 @@ -20,7 +20,7 @@ */ public class WaitForMessageEvent implements ClientEvent { - private static final Logger LOGGER = LoggerFactory.getLogger(WaitForMessageEvent.class); + private static final Logger LOG = LoggerFactory.getLogger(WaitForMessageEvent.class); private byte[] headerExpected; private byte[] headerReceived; @@ -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 @@ -40,13 +38,13 @@ public boolean eventExecuted() { return false; } if (!Arrays.equals(headerExpected, headerReceived)) { - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("expected msg: {}", ByteBufUtils.bytesToHexString(headerExpected)); - LOGGER.debug("received msg: {}", ByteBufUtils.bytesToHexString(headerReceived)); + if (LOG.isDebugEnabled()) { + LOG.debug("expected msg: {}", ByteBufUtils.bytesToHexString(headerExpected)); + LOG.debug("received msg: {}", ByteBufUtils.bytesToHexString(headerReceived)); } return false; } - LOGGER.debug("Headers OK"); + LOG.debug("Headers OK"); return true; } @@ -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