diff --git a/.gitignore b/.gitignore index 1e44f73b..87966d5f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ -target/ -.classpath -.project -.settings/ -.externalToolBuilders/ -maven-eclipse.xml -.checkstyle +target/ +target-ide/ +.classpath +.project +.settings/ +.externalToolBuilders/ +maven-eclipse.xml +.checkstyle +.idea +*.iws +*.iml diff --git a/.gitreview b/.gitreview index 599a6c42..8968f7fe 100644 --- a/.gitreview +++ b/.gitreview @@ -2,3 +2,4 @@ host=git.opendaylight.org port=29418 project=openflowjava.git +defaultbranch=master diff --git a/artifacts/pom.xml b/artifacts/pom.xml index 5b452b21..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 @@ -46,7 +71,7 @@ ${project.groupId} - util + openflowjava-util ${project.version} @@ -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 771afeb0..44633fb4 100644 --- a/features/pom.xml +++ b/features/pom.xml @@ -3,126 +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 - 0.8.0-SNAPSHOT - - - - - - - org.opendaylight.openflowjava - openflowjava-artifacts - ${project.version} - import - pom - - - - - org.opendaylight.yangtools - yangtools-artifacts - ${yangtools.version} - import - pom - - - - - org.opendaylight.controller - config-artifacts - ${config.version} - import - pom - - - org.opendaylight.controller - mdsal-artifacts - ${mdsal.version} - import - pom - - - - - - - - - org.opendaylight.yangtools - features-yangtools - features - xml - - - org.opendaylight.controller - features-config - features - xml - - - org.opendaylight.controller - features-mdsal - ${mdsal.version} - features - xml - - - - - org.opendaylight.openflowjava - openflow-protocol-api - - - org.opendaylight.openflowjava - openflow-protocol-spi - - - org.opendaylight.openflowjava - openflow-protocol-impl - - - org.opendaylight.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 1db95530..00000000 --- a/features/src/main/features/features.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - mvn:org.opendaylight.yangtools/features-yangtools/${yangtools.version}/xml/features - mvn:org.opendaylight.controller/features-config/${config.version}/xml/features - mvn:org.opendaylight.controller/features-mdsal/${mdsal.version}/xml/features - - odl-openflowjava-protocol - - - odl-yangtools-common - odl-yangtools-binding - odl-yangtools-models - odl-config-api - odl-mdsal-common - mvn:io.netty/netty-buffer/{{VERSION}} - mvn:io.netty/netty-common/{{VERSION}} - mvn:io.netty/netty-transport/{{VERSION}} - mvn:io.netty/netty-codec/{{VERSION}} - mvn:io.netty/netty-handler/{{VERSION}} - 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/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 888ed68f..5a2777d0 100644 --- a/openflow-protocol-api/pom.xml +++ b/openflow-protocol-api/pom.xml @@ -2,141 +2,52 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + org.opendaylight.mdsal + binding-parent + 0.11.0-SNAPSHOT + + org.opendaylight.openflowjava openflow-protocol-api + 0.10.0-SNAPSHOT bundle - Openflow Protocol Library - API + + ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD - - - - org.opendaylight.yangtools - yang-maven-plugin - - - - generate-sources - - - src/main/yang - - - - org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl - - - ${salGeneratorPath} - - - - org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl - target/site/restconf - - - true - - - + + 2.3.0-SNAPSHOT + 0.11.0-SNAPSHOT + - - - org.opendaylight.yangtools - maven-sal-api-gen-plugin - ${yangtools.version} - jar - - - + + + + + org.opendaylight.mdsal + mdsal-artifacts + ${mdsal.version} + import + pom + - - - org.apache.maven.plugins - maven-antrun-plugin - - - prepare-package - - run - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.opendaylight.yangtools - - - yang-maven-plugin - - - (0.5.6,) - - - - generate-sources - - - - - - - - - - - - - - - org.opendaylight.yangtools + org.opendaylight.mdsal yang-binding @@ -144,15 +55,15 @@ yang-common - org.opendaylight.yangtools.model - ietf-inet-types + org.opendaylight.mdsal.model + ietf-inet-types-2013-07-15 - org.opendaylight.yangtools.model - ietf-yang-types + org.opendaylight.mdsal.model + ietf-yang-types-20130715 - org.opendaylight.yangtools.model + org.opendaylight.mdsal.model yang-ext @@ -166,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 443dea57..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 */ @@ -57,13 +65,15 @@ public interface ConnectionAdapter extends OpenflowProtocolService { /** * set listener for connection became ready-to-use event - * @param connectionReadyListener + * @param connectionReadyListener listens to connection ready event */ void setConnectionReadyListener(ConnectionReadyListener connectionReadyListener); /** * sets option for automatic channel reading; * if set to false, incoming messages won't be read + * + * @param autoRead target value to be switched to */ void setAutoRead(boolean autoRead); @@ -74,9 +84,10 @@ public interface ConnectionAdapter extends OpenflowProtocolService { /** * Registers a new bypass outbound queue - * @param handler - * @param maxQueueDepth - * @param maxBarrierNanos + * @param handler type + * @param handler queue handler + * @param maxQueueDepth max amount of not confirmed messaged in queue (i.e. edge for barrier message) + * @param maxBarrierNanos regular base for barrier message * @return An {@link OutboundQueueHandlerRegistration} */ @Beta 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 afe5b056..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; @@ -30,10 +31,10 @@ public interface OutboundQueue { * 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) + * 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) + * 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. @@ -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/SwitchConnectionHandler.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java index 363e3245..8b4fddf6 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java @@ -24,7 +24,7 @@ public interface SwitchConnectionHandler { void onSwitchConnected(ConnectionAdapter connection); /** - * @param switchAddress + * @param switchAddress address of incoming connection (address + port) * @return true, if connection from switch having given address shell be accepted; false otherwise */ boolean accept(InetAddress switchAddress); 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 b38b5cfa..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,9 +13,10 @@ 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.ExperimenterMessage; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +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.queue.property.header.QueueProperty; @@ -34,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 @@ -80,7 +95,7 @@ void registerErrorDeserializer(ExperimenterIdDeserializerKey key, * @param deserializer deserializer instance */ void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer); + OFDeserializer deserializer); /** * Registers multipart-reply (stats) message deserializer @@ -88,7 +103,7 @@ void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key, * @param deserializer deserializer instance */ void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer); + OFDeserializer deserializer); /** * Registers multipart-reply table-features message deserializer @@ -113,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/DeserializerRegistry.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java index 6970a1dc..27660398 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java @@ -22,6 +22,7 @@ public interface DeserializerRegistry { void init(); /** + * @param type of particular deserializer * @param key used for deserializer lookup * @return deserializer found */ diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java index 0b291af3..98e83633 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java @@ -15,7 +15,7 @@ public interface DeserializerRegistryInjector { /** * Injects deserializer registry into deserializer - * @param deserializerRegistry + * @param deserializerRegistry registry of deserializers */ void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry); } diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java index ec578c6b..3a9fffc2 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java @@ -21,9 +21,9 @@ public class EnhancedMessageTypeKey extends MessageTypeKey { private final Class msgType2; /** - * @param msgVersion - * @param msgType - * @param msgType2 + * @param msgVersion protocol version + * @param msgType main type + * @param msgType2 subtype */ public EnhancedMessageTypeKey(short msgVersion, Class msgType, Class msgType2) { super(msgVersion, msgType); 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 1d105f39..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,14 +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 + * @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 1e047c09..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 @@ -7,16 +7,15 @@ */ package org.opendaylight.openflowjava.protocol.api.extensibility; -import org.opendaylight.yangtools.yang.binding.DataObject; - import io.netty.buffer.ByteBuf; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * Does only-header serialization (such as oxm_ids, action_ids, instruction_ids) * @author michal.polkorab - * @param + * @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/OFDeserializer.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java index a49d84c3..06c54f9d 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java @@ -9,8 +9,7 @@ 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; /** * Uniform interface for deserializing factories @@ -18,7 +17,7 @@ * @author timotej.kubas * @param message code type */ -public interface OFDeserializer extends OFGeneralDeserializer { +public interface OFDeserializer extends OFGeneralDeserializer { /** * Transforms byte message into POJO/DTO (of type E). diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java index 6b2ef473..ec63be53 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java @@ -8,9 +8,8 @@ package org.opendaylight.openflowjava.protocol.api.extensibility; -import org.opendaylight.yangtools.yang.binding.DataObject; - import io.netty.buffer.ByteBuf; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * Uniform interface for serializers @@ -18,7 +17,7 @@ * @author timotej.kubas * @param message type */ -public interface OFSerializer extends OFGeneralSerializer { +public interface OFSerializer extends OFGeneralSerializer { /** * Transforms POJO/DTO into byte message (ByteBuf). 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 7d83cd82..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,15 +9,16 @@ 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.ExperimenterInput; +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.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; @@ -34,6 +35,21 @@ */ public interface SerializerExtensionProvider { + /** + * Registers serializer + * Throws IllegalStateException when there is + * a serializer already registered under given key. + * + * If the serializer implements {@link SerializerRegistryInjector} interface, + * the serializer is injected with SerializerRegistry instance. + * + * @param serializer key type + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerSerializer(MessageTypeKey key, + OFGeneralSerializer serializer); + /** * Unregisters custom serializer * @param key used for serializer lookup @@ -60,6 +76,8 @@ void registerInstructionSerializer(InstructionSerializerKey key, /** * Registers match entry serializer + * @param oxm type + * @param match field type * @param key used for serializer lookup * @param serializer serializer implementation */ @@ -71,16 +89,16 @@ void registerMatchEntrySerializer * @param key used for serializer lookup * @param serializer serializer implementation */ - void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer); + void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer); /** * Registers multipart-request (stats-request) serializer * @param key used for serializer lookup * @param serializer serializer implementation */ - void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer); + void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer); /** * Registers multipart-request table-features serializer @@ -91,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/extensibility/SerializerRegistry.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java index 7fb39bbd..1ddc4856 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java @@ -23,6 +23,8 @@ public interface SerializerRegistry { void init(); /** + * @param input key type + * @param type of resulting serializer * @param msgTypeKey lookup key * @return serializer or NullPointerException if no serializer was found */ @@ -36,6 +38,7 @@ public interface SerializerRegistry { * 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 */ @@ -44,6 +47,7 @@ void registerSerializer(MessageTypeKey key, /** * Unregisters serializer + * @param serializer key type * @param key used for serializer lookup * @return true if serializer was removed, * false if no serializer was found under specified key 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 bc16e523..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 @@ -9,34 +9,36 @@ package org.opendaylight.openflowjava.protocol.api.keys; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * @author michal.polkorab - * */ -public final class ExperimenterIdDeserializerKey extends MessageCodeKey - implements ExperimenterDeserializerKey { +public class ExperimenterIdDeserializerKey extends MessageCodeKey implements ExperimenterDeserializerKey { - private Long experimenterId; + private long experimenterId; /** + * @param type of target experimenter object * @param version protocol wire version * @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; } + protected int hashCodeOfLong(long longValue) { + return (int) (longValue ^ (longValue >>> 32)); + } @Override public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + result = prime * result + hashCodeOfLong(experimenterId); return result; } @@ -52,11 +54,7 @@ public boolean equals(Object obj) { return false; } ExperimenterIdDeserializerKey other = (ExperimenterIdDeserializerKey) obj; - if (experimenterId == null) { - if (other.experimenterId != null) { - return false; - } - } else if (!experimenterId.equals(other.experimenterId)) { + if (experimenterId != other.experimenterId) { return false; } return true; 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/ExperimenterIdSerializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java index 89525282..8a900e34 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java @@ -8,16 +8,16 @@ package org.opendaylight.openflowjava.protocol.api.keys; -import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.DataContainer; /** * @author michal.polkorab * @param class of object to be serialized */ -public class ExperimenterIdSerializerKey extends MessageTypeKey +public class ExperimenterIdSerializerKey extends MessageTypeKey implements ExperimenterSerializerKey { - private Long experimenterId; + private long experimenterId; /** * @param msgVersion protocol wire version @@ -25,7 +25,7 @@ public class ExperimenterIdSerializerKey extends MessageTy * @param objectClass class of object to be serialized */ public ExperimenterIdSerializerKey(short msgVersion, - Long experimenterId, Class objectClass) { + long experimenterId, Class objectClass) { super(msgVersion, objectClass); this.experimenterId = experimenterId; } @@ -34,10 +34,14 @@ public ExperimenterIdSerializerKey(short msgVersion, public int hashCode() { final int prime = 31; int result = super.hashCode(); - result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + result = prime * result + hashCodeOfLong(experimenterId); return result; } + protected int hashCodeOfLong(long longValue) { + return (int) (longValue ^ (longValue >>> 32)); + } + @Override public boolean equals(Object obj) { if (this == obj) { @@ -50,11 +54,7 @@ public boolean equals(Object obj) { return false; } ExperimenterIdSerializerKey other = (ExperimenterIdSerializerKey) obj; - if (experimenterId == null) { - if (other.experimenterId != null) { - return false; - } - } else if (!experimenterId.equals(other.experimenterId)) { + if (experimenterId != other.experimenterId) { 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 new file mode 100644 index 00000000..c956feb0 --- /dev/null +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java @@ -0,0 +1,60 @@ +/* + * 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.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * @author michal.polkorab + */ +public class ExperimenterIdTypeDeserializerKey extends ExperimenterIdDeserializerKey { + + private long type; + + /** + * @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(final short version, final long experimenterId, + final long type, Class objectClass) { + super(version, experimenterId, objectClass); + this.type = type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + hashCodeOfLong(type); + return result; + } + + @Override + public boolean equals(Object obj) { + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof ExperimenterIdTypeDeserializerKey)) { + return false; + } + ExperimenterIdTypeDeserializerKey other = (ExperimenterIdTypeDeserializerKey) obj; + if (type != other.type) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + "; type: " + type; + } +} \ No newline at end of file diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java new file mode 100644 index 00000000..b8f6ac93 --- /dev/null +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java @@ -0,0 +1,60 @@ +/* + * 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.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * @param class of object to be serialized + * @author michal.polkorab + */ +public class ExperimenterIdTypeSerializerKey extends ExperimenterIdSerializerKey { + + private long type; + + /** + * @param msgVersion 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 ExperimenterIdTypeSerializerKey(short msgVersion, + long experimenterId, long type, Class objectClass) { + super(msgVersion, experimenterId, objectClass); + this.type = type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + hashCodeOfLong(type); + return result; + } + + @Override + public boolean equals(Object obj) { + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof ExperimenterIdTypeSerializerKey)) { + return false; + } + ExperimenterIdTypeSerializerKey other = (ExperimenterIdTypeSerializerKey) obj; + if (type != other.type) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + "; type: " + type; + } +} \ No newline at end of file diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java index 45232a66..eea3e4ef 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java @@ -19,7 +19,7 @@ public final class ExperimenterInstructionDeserializerKey extends InstructionDes /** * @param version protocol wire version - * @param experimenterId + * @param experimenterId experimenter (vendor) identifier */ public ExperimenterInstructionDeserializerKey(short version, Long experimenterId) { super(version, EncodeConstants.EXPERIMENTER_VALUE, experimenterId); diff --git a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java index 3a0bf982..8482f6ef 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java @@ -20,7 +20,7 @@ public class InstructionDeserializerKey extends MessageCodeKey { /** * @param version protocol wire version * @param type instruction type - * @param experimenterId + * @param experimenterId experimenter (vendor) identifier */ public InstructionDeserializerKey(short version, int type, Long experimenterId) { 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/BinContent.java b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java index 700fdf4d..995fd350 100644 --- a/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java +++ b/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java @@ -19,15 +19,15 @@ private BinContent() { } /** - * @param value - * @return int part wrapped in long + * @param value input integer value (might be negative) + * @return int part wrapped in long (always positive) */ public static long intToUnsignedLong(int value) { return value & 0x00000000ffffffffL; } /** - * @param value + * @param value input long value * @return long cut into int */ public static int longToSignedInt(long value) { 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-action.yang b/openflow-protocol-api/src/main/yang/openflow-action.yang index 576a7f45..d2ae42f6 100644 --- a/openflow-protocol-api/src/main/yang/openflow-action.yang +++ b/openflow-protocol-api/src/main/yang/openflow-action.yang @@ -17,7 +17,7 @@ import openflow-extensible-match { prefix oxm;} revision "2015-02-03" { - description "OpenFlow 1.3 - action model"; + description "#NOT_PUBLISHED# OpenFlow 1.3 - action model"; } identity experimenter-action-sub-type { 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 34ca8c43..4a60c37e --- a/openflow-protocol-api/src/main/yang/openflow-augments.yang +++ b/openflow-protocol-api/src/main/yang/openflow-augments.yang @@ -21,7 +21,7 @@ import openflow-extensible-match {prefix oxm;} revision "2015-02-25" { - description "OpenFlow 1.3 - augments model. + description "#NOT_PUBLISHED# OpenFlow 1.3 - augments model. Please visit https://wiki.opendaylight.org/view/File:OpenFlow_Protocol_Library_-_Project_documentation.pdf - Augmentation Tables chapter"; @@ -121,31 +121,16 @@ } } -// OFP_MULTIPART AUGMENTS - augment "/ofproto:multipart-request/input/ofproto:multipart-request-body/ofproto:multipart-request-experimenter-case/ofproto:multipart-request-experimenter" { - ext:augment-identifier "experimenter-id-multipart-request"; - leaf experimenter { - type oft:experimenter-id; - } - leaf exp-type { - type uint32; - } - } - augment "/ofproto:multipart-reply-message/ofproto:multipart-reply-body/ofproto:multipart-reply-experimenter-case/ofproto:multipart-reply-experimenter" { - ext:augment-identifier "experimenter-id-multipart-reply"; - leaf experimenter { - type oft:experimenter-id; - } - leaf exp-type { - type uint32; - } - } - // OFP_METER_BAND AUGMENTS augment "/ofproto:meter-band-container/ofproto:meter-band/ofproto:meter-band-experimenter-case/ofproto:meter-band-experimenter" { ext:augment-identifier "experimenter-id-meter-band"; leaf experimenter { type oft:experimenter-id; } + leaf sub-type { + type identityref { + base oft:experimenter-meter-band-sub-type; + } + } } -} \ No newline at end of file +} diff --git a/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang b/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang index f9d3f6c3..f1f9e9b9 100644 --- a/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang +++ b/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang @@ -15,7 +15,7 @@ import openflow-types {prefix oft;} revision "2015-02-25" { - description "OpenFlow 1.3 - match model"; + description "#NOT_PUBLISHED# OpenFlow 1.3 - match model"; } identity oxm-match-type { diff --git a/openflow-protocol-api/src/main/yang/openflow-instruction.yang b/openflow-protocol-api/src/main/yang/openflow-instruction.yang index a58fc349..b9e515b3 100644 --- a/openflow-protocol-api/src/main/yang/openflow-instruction.yang +++ b/openflow-protocol-api/src/main/yang/openflow-instruction.yang @@ -14,7 +14,7 @@ import openflow-action {prefix ofaction;} revision "2013-07-31" { - description "OpenFlow 1.3 - instruction model"; + description "#NOT_PUBLISHED# OpenFlow 1.3 - instruction model"; } container instruction-container { diff --git a/openflow-protocol-api/src/main/yang/openflow-protocol.yang b/openflow-protocol-api/src/main/yang/openflow-protocol.yang index 9c9dbf0e..7e42a2b9 100644 --- a/openflow-protocol-api/src/main/yang/openflow-protocol.yang +++ b/openflow-protocol-api/src/main/yang/openflow-protocol.yang @@ -18,7 +18,7 @@ import openflow-action {prefix ofaction;} revision "2013-07-31" { - description "OpenFlow 1.3 - protocol objects model"; + description "#NOT_PUBLISHED# OpenFlow 1.3 - protocol objects model"; } // Generic Structures @@ -207,18 +207,26 @@ type binary; } } - grouping experimenter { - reference "OFPT_EXPERIMENTER message in Openflow Switch 1.3 Spec"; - /* Symmetric message */ - uses ofHeader; + grouping experimenter-core { + description "General experimenter message content suitable for symmetric and multipart message"; leaf experimenter { type oft:experimenter-id; } leaf exp_type { type uint32; } + choice experimenter-data-of-choice { + // to be augmented by vendors + } } + grouping experimenter-of-message { + reference "OFPT_EXPERIMENTER message in Openflow Switch 1.3 Spec"; + /* Symmetric message */ + uses ofHeader; + uses experimenter-core; + } + /* Switch configuration messages. */ grouping features-request { reference "OFPT_FEATURES_REQUEST message in Openflow Switch 1.3 Spec"; @@ -678,7 +686,7 @@ } case multipart-request-experimenter-case { container multipart-request-experimenter { - // empty body - used for experimenter augmentation + uses experimenter-core; } } } @@ -1045,7 +1053,7 @@ } case multipart-reply-experimenter-case { container multipart-reply-experimenter { - // empty body - used for experimenter augmentation + uses experimenter-core; } } } @@ -1250,7 +1258,8 @@ /* Symmetric message */ } notification experimenter-message { - uses experimenter; + description "Experimenter request message from device."; + uses experimenter-of-message; reference "OFPT_EXPERIMENTER message in Openflow Switch 1.3 Spec"; // TODO:: does switch send this when understood experimenter msg from lib? /* Symmetric message */ @@ -1280,8 +1289,9 @@ } rpc experimenter { + description "Send experimenter message to device, reply is not solicitated."; input { - uses experimenter; + uses experimenter-of-message; } } 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 be0e9f5d..7d11bafa --- a/openflow-protocol-api/src/main/yang/openflow-types.yang +++ b/openflow-protocol-api/src/main/yang/openflow-types.yang @@ -11,7 +11,7 @@ prefix "oft"; revision "2013-07-31" { - description "OpenFlow 1.3 - common types model"; + description "#NOT_PUBLISHED# OpenFlow 1.3 - common types model"; } typedef port-number { @@ -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/main/yang/system-notifications.yang b/openflow-protocol-api/src/main/yang/system-notifications.yang index b31dd02b..5bd805c3 100644 --- a/openflow-protocol-api/src/main/yang/system-notifications.yang +++ b/openflow-protocol-api/src/main/yang/system-notifications.yang @@ -11,7 +11,7 @@ prefix "ofs"; revision "2013-09-27" { - description "Model of system messages used in OpenFlow Protocol Library"; + description "#NOT_PUBLISHED# Model of system messages used in OpenFlow Protocol Library"; } notification disconnect-event { 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-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java index eb71029a..d7f61084 100644 --- a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java @@ -36,7 +36,7 @@ public void test() { key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF13_VERSION_ID, 42L, ExperimenterMessage.class); Assert.assertFalse("Wrong equals", key1.equals(key2)); Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); - key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, null, ExperimenterMessage.class); + key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0L, ExperimenterMessage.class); Assert.assertFalse("Wrong equals", key1.equals(key2)); Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, ExperimenterMessage.class); @@ -56,7 +56,7 @@ public void test() { @Test public void testEquals() { ExperimenterIdDeserializerKey key1 = - new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, null, ExperimenterMessage.class); + new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0L, ExperimenterMessage.class); Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); MessageCodeKey mk = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID,EncodeConstants.EXPERIMENTER_VALUE, ExperimenterMessage.class); Assert.assertFalse("Wrong equal to different class.", key1.equals(mk)); diff --git a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java index aa5d1275..a3bf7891 100644 --- a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java @@ -26,7 +26,7 @@ public class ExperimenterIdSerializerKeyTest { * Test ExperimenterIdSerializerKey equals and hashCode */ @Test - public void test() { + public void testHashCodeAndEquals() { ExperimenterIdSerializerKey key1 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); ExperimenterIdSerializerKey key2 = @@ -36,9 +36,6 @@ public void test() { key2 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF13_VERSION_ID, 42L, ExperimenterMessage.class); Assert.assertFalse("Wrong equals", key1.equals(key2)); Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); - key2 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, ExperimenterMessage.class); - Assert.assertFalse("Wrong equals", key1.equals(key2)); - Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); key2 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 55L, ExperimenterMessage.class); Assert.assertFalse("Wrong equals", key1.equals(key2)); Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); @@ -56,7 +53,7 @@ public void test() { @Test public void testEquals() { ExperimenterIdSerializerKey key1 = - new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, ExperimenterMessage.class); + new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 41L, ExperimenterMessage.class); Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); MessageTypeKeymk = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID,ExperimenterMessage.class); Assert.assertFalse("Wrong equal to different class.", key1.equals(mk)); diff --git a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java new file mode 100644 index 00000000..7405b773 --- /dev/null +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java @@ -0,0 +1,72 @@ +/* + * 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.experimenter; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; + +/** + * @author michal.polkorab + */ +public class ExperimenterIdTypeDeserializerKeyTest { + + /** + * Test ExperimenterIdTypeDeserializerKey equals and hashCode + */ + @Test + public void testHashCodeAndEquals() { + ExperimenterIdTypeDeserializerKey key1 = + new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + ExperimenterIdTypeDeserializerKey key2 = + new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF13_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, 1L, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, 1L, ErrorMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + + key2 = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, 2L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ExperimenterIdTypeDeserializerKey equals - additional test + */ + @Test + public void testEquals() { + ExperimenterIdTypeDeserializerKey key1 = + new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 41L, 1L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + ExperimenterIdSerializerKey mk = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal to different class.", key1.equals(mk)); + ExperimenterIdTypeDeserializerKey key2 = + new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by experimenterId.", key1.equals(key2)); + + ExperimenterIdTypeDeserializerKey key3 = + new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, 41L, 2L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by type.", key1.equals(key3)); + } + +} \ No newline at end of file diff --git a/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java new file mode 100644 index 00000000..a613d0d8 --- /dev/null +++ b/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java @@ -0,0 +1,72 @@ +/* + * 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.experimenter; + +import org.junit.Assert; +import org.junit.Test; +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.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; + +/** + * @author michal.polkorab + */ +public class ExperimenterIdTypeSerializerKeyTest { + + /** + * Test ExperimenterIdTypeSerializerKey equals and hashCode + */ + @Test + public void testHashCodeAndEquals() { + ExperimenterIdTypeSerializerKey key1 = + new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + ExperimenterIdTypeSerializerKey key2 = + new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF13_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 55L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 55L, 1L, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 55L, 1L, ErrorMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + + key2 = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, 2L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ExperimenterIdTypeSerializerKey equals - additional test + */ + @Test + public void testEquals() { + ExperimenterIdTypeSerializerKey key1 = + new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 41L, 1L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + ExperimenterIdSerializerKey mk = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal to different class.", key1.equals(mk)); + ExperimenterIdTypeSerializerKey key2 = + new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, 1L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by experimenterId.", key1.equals(key2)); + + ExperimenterIdTypeSerializerKey key3 = + new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 41L, 2L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by type.", key1.equals(key3)); + } + +} \ No newline at end of file diff --git a/openflow-protocol-impl/pom.xml b/openflow-protocol-impl/pom.xml index 0a4f2fe8..62c2ddd3 100644 --- a/openflow-protocol-impl/pom.xml +++ b/openflow-protocol-impl/pom.xml @@ -2,12 +2,15 @@ 4.0.0 org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 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 @@ -51,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 @@ -71,9 +74,9 @@ ${config.version} - org.opendaylight.yangtools + org.opendaylight.mdsal maven-sal-api-gen-plugin - ${yangtools.version} + ${mdsal.model.version} jar @@ -103,7 +106,7 @@ org.opendaylight.openflowjava - util + openflowjava-util org.opendaylight.controller @@ -143,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 075b99da..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 @@ -12,7 +12,6 @@ import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToByteEncoder; import io.netty.util.concurrent.Future; - import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; import org.opendaylight.openflowjava.statistics.CounterEventTypes; @@ -22,37 +21,39 @@ import org.slf4j.LoggerFactory; /** - * Transforms OpenFlow Protocol messages to POJOs + * Transforms OpenFlow Protocol messages to POJOs. * @author michal.polkorab * @author timotej.kubas */ public class OFEncoder extends MessageToByteEncoder { - private static final Logger LOGGER = LoggerFactory.getLogger(OFEncoder.class); + private static final Logger LOG = LoggerFactory.getLogger(OFEncoder.class); private SerializationFactory serializationFactory; - private StatisticsCounters statisticsCounters; + private final StatisticsCounters statisticsCounters; /** Constructor of class */ public OFEncoder() { statisticsCounters = StatisticsCounters.getInstance(); - LOGGER.trace("Creating OF13Encoder"); + LOG.trace("Creating OFEncoder"); } @Override - protected void encode(ChannelHandlerContext ctx, MessageListenerWrapper wrapper, ByteBuf out) + protected void encode(final ChannelHandlerContext ctx, final MessageListenerWrapper wrapper, final ByteBuf out) throws Exception { - LOGGER.trace("Encoding"); + LOG.trace("Encoding"); try { serializationFactory.messageToBuffer(wrapper.getMsg().getVersion(), out, wrapper.getMsg()); if(wrapper.getMsg() instanceof FlowModInput){ statisticsCounters.incrementCounter(CounterEventTypes.DS_FLOW_MODS_SENT); } statisticsCounters.incrementCounter(CounterEventTypes.DS_ENCODE_SUCCESS); - } catch(Exception e) { - LOGGER.warn("Message serialization failed ", e); + } catch(final Exception e) { + LOG.warn("Message serialization failed ", e); statisticsCounters.incrementCounter(CounterEventTypes.DS_ENCODE_FAIL); - Future newFailedFuture = ctx.newFailedFuture(e); - wrapper.getListener().operationComplete(newFailedFuture); + if (wrapper.getListener() != null) { + final Future newFailedFuture = ctx.newFailedFuture(e); + wrapper.getListener().operationComplete(newFailedFuture); + } out.clear(); return; } @@ -61,7 +62,7 @@ protected void encode(ChannelHandlerContext ctx, MessageListenerWrapper wrapper, /** * @param serializationFactory */ - public void setSerializationFactory(SerializationFactory serializationFactory) { + public void setSerializationFactory(final SerializationFactory serializationFactory) { this.serializationFactory = serializationFactory; } 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 c2b4890d..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 @@ -9,8 +9,10 @@ package org.opendaylight.openflowjava.protocol.impl.core; -import io.netty.channel.nio.NioEventLoopGroup; - +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +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; @@ -23,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; @@ -35,24 +38,19 @@ 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; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; 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.MultipartReplyMessage; +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.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; - /** * Exposed class for server handling
* C - {@link MatchEntrySerializerKey} parameter representing oxm_class (see specification)
@@ -62,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 */ @@ -86,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(); @@ -108,7 +106,7 @@ public ListenableFuture shutdown() { @Override public ListenableFuture startup() { - LOGGER.debug("Startup summoned"); + LOG.debug("Startup summoned"); ListenableFuture result = null; try { serverFacade = createAndConfigureServer(); @@ -117,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; } @@ -129,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); @@ -171,114 +176,149 @@ 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); } @Override public void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer) { + OFDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @Override public void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializerKey key, - OFDeserializer deserializer) { + OFDeserializer deserializer) { deserializerRegistry.registerDeserializer(key, deserializer); } @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); } @Override - public void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer) { + public void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer) { + public void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void registerMultipartRequestTFSerializer(ExperimenterIdSerializerKey key, - OFGeneralSerializer serializer) { + public void registerMultipartRequestTFSerializer(final ExperimenterIdSerializerKey key, + final OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + /** + * @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 registerMeterBandSerializer(ExperimenterIdSerializerKey key, - OFSerializer serializer) { + public void registerMeterBandSerializer(final ExperimenterIdMeterSubTypeSerializerKey key, + final OFSerializer serializer) { serializerRegistry.registerSerializer(key, serializer); } @Override - public void initiateConnection(String host, int port) { + 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 43277eaa..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,13 +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 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; @@ -26,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 ; } @@ -55,53 +53,71 @@ 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); - ch.pipeline().addLast(PipelineHandlers.SSL_HANDLER.name(), new SslHandler(engine)); + 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(final Future future) throws Exception { + finalConnectionFacade.fireConnectionReadyNotification(); + } + }); + ch.pipeline().addLast(PipelineHandlers.SSL_HANDLER.name(), ssl); } 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 ded62f57..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 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, OutboundQueueCache.getInstance().getSlice(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/OutboundQueueCache.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueCache.java deleted file mode 100644 index f65c5a86..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueCache.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.connection; - -import java.util.HashMap; -import java.util.Map; - -final class OutboundQueueCache { - private static final OutboundQueueCache INSTANCE = new OutboundQueueCache(); - - private final Map slices = new HashMap<>(); - - private OutboundQueueCache() { - - } - - static OutboundQueueCache getInstance() { - return INSTANCE; - } - - synchronized OutboundQueueCacheSlice getSlice(final int queueSize) { - final OutboundQueueCacheSlice oldSlice = slices.get(queueSize); - if (oldSlice != null) { - oldSlice.incRef(); - return oldSlice; - } - - final OutboundQueueCacheSlice newSlice = new OutboundQueueCacheSlice(queueSize); - slices.put(queueSize, newSlice); - return newSlice; - } - - synchronized void putSlice(final OutboundQueueCacheSlice slice) { - if (slice.decRef()) { - slices.remove(slice.getQueueSize()); - } - } -} diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueCacheSlice.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueCacheSlice.java deleted file mode 100644 index a5145890..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueCacheSlice.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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.connection; - -import com.google.common.base.FinalizableReferenceQueue; -import com.google.common.base.FinalizableSoftReference; -import com.google.common.base.Preconditions; -import java.lang.ref.Reference; -import java.util.Collection; -import java.util.concurrent.ConcurrentLinkedDeque; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class OutboundQueueCacheSlice { - private static final class QueueRef extends FinalizableSoftReference { - private final Collection cache; - - protected QueueRef(final FinalizableReferenceQueue queue, final Collection cache, final OutboundQueueImpl referent) { - super(referent, queue); - this.cache = Preconditions.checkNotNull(cache); - } - - @Override - public void finalizeReferent() { - cache.remove(this); - } - } - - private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueCacheSlice.class); - private final FinalizableReferenceQueue refQueue = new FinalizableReferenceQueue(); - - private final ConcurrentLinkedDeque cache = new ConcurrentLinkedDeque<>(); - private final int queueSize; - private int refCount = 1; - - OutboundQueueCacheSlice(final int queueSize) { - Preconditions.checkArgument(queueSize >= 1); - this.queueSize = queueSize; - } - - void remove(final QueueRef queueRef) { - cache.remove(queueRef); - } - - boolean decRef() { - if (--refCount == 0) { - refQueue.close(); - return true; - } else { - return false; - } - } - - void incRef() { - refCount++; - } - - int getQueueSize() { - return queueSize; - } - - OutboundQueueImpl getQueue(final OutboundQueueManager manager, final long baseXid) { - final OutboundQueueImpl ret; - OutboundQueueImpl cached = null; - for (;;) { - final Reference item = cache.pollLast(); - if (item == null) { - break; - } - - cached = item.get(); - if (cached != null) { - ret = cached.reuse(manager, baseXid); - LOG.trace("Reusing queue {} as {} on manager {}", cached, ret, manager); - return ret; - } - } - - ret = new OutboundQueueImpl(manager, baseXid, queueSize + 1); - LOG.trace("Allocated new queue {} on manager {}", ret, manager); - return ret; - } - - void putQueue(final OutboundQueueImpl queue) { - queue.retire(); - if (cache.offer(new QueueRef(refQueue, cache, queue))) { - LOG.trace("Saving queue {} for later reuse", queue); - } else { - LOG.trace("Queue {} thrown away", queue); - } - } -} 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/OutboundQueueImpl.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueImpl.java deleted file mode 100644 index c4feb26a..00000000 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueImpl.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * 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.connection; - -import com.google.common.base.Preconditions; -import com.google.common.base.Verify; -import com.google.common.util.concurrent.FutureCallback; -import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import javax.annotation.Nonnull; -import org.opendaylight.openflowjava.protocol.api.connection.DeviceRequestFailedException; -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.Error; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -final class OutboundQueueImpl implements OutboundQueue { - private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueImpl.class); - private static final AtomicIntegerFieldUpdater CURRENT_OFFSET_UPDATER = - AtomicIntegerFieldUpdater.newUpdater(OutboundQueueImpl.class, "reserveOffset"); - private static final AtomicIntegerFieldUpdater BARRIER_OFFSET_UPDATER = - AtomicIntegerFieldUpdater.newUpdater(OutboundQueueImpl.class, "barrierOffset"); - private final OutboundQueueManager manager; - private final OutboundQueueEntry[] queue; - private final long baseXid; - private final long endXid; - private final int reserve; - - // Updated concurrently - private volatile int barrierOffset = -1; - private volatile int reserveOffset = 0; - - // Updated from Netty only - private int flushOffset; - private int completeCount; - private int lastBarrierOffset = -1; - - OutboundQueueImpl(final OutboundQueueManager manager, final long baseXid, final int maxQueue) { - /* - * We use the last entry as an emergency should a timeout-triggered - * flush request race with normal users for the last entry in this - * queue. In that case the flush request will take the last entry and - * schedule a flush, which means that we will get around sending the - * message as soon as the user finishes the reservation. - */ - Preconditions.checkArgument(maxQueue > 1); - this.baseXid = baseXid; - this.endXid = baseXid + maxQueue; - this.reserve = maxQueue - 1; - this.manager = Preconditions.checkNotNull(manager); - queue = new OutboundQueueEntry[maxQueue]; - for (int i = 0; i < maxQueue; ++i) { - queue[i] = new OutboundQueueEntry(); - } - } - - private OutboundQueueImpl(final OutboundQueueManager manager, final long baseXid, final OutboundQueueEntry[] queue) { - this.manager = Preconditions.checkNotNull(manager); - this.queue = Preconditions.checkNotNull(queue); - this.baseXid = baseXid; - this.endXid = baseXid + queue.length; - this.reserve = queue.length - 1; - } - - void retire() { - for (OutboundQueueEntry element : queue) { - element.reset(); - } - } - - OutboundQueueImpl reuse(final OutboundQueueManager manager, final long baseXid) { - return new OutboundQueueImpl(manager, baseXid, queue); - } - - @Override - public Long reserveEntry() { - return reserveEntry(false); - } - - @Override - public void commitEntry(final Long xid, final OfHeader message, final FutureCallback callback) { - final int offset = (int)(xid - baseXid); - if (message != null) { - Preconditions.checkArgument(xid.equals(message.getXid()), "Message %s has wrong XID %s, expected %s", message, message.getXid(), xid); - } - - final int ro = reserveOffset; - Preconditions.checkArgument(offset < ro, "Unexpected commit to offset %s reserved %s message %s", offset, ro, message); - - final OutboundQueueEntry entry = queue[offset]; - entry.commit(message, callback); - LOG.debug("Queue {} XID {} at offset {} (of {}) committed", this, xid, offset, ro); - - if (entry.isBarrier()) { - int my = offset; - for (;;) { - final int prev = BARRIER_OFFSET_UPDATER.getAndSet(this, my); - if (prev < my) { - LOG.debug("Queue {} recorded pending barrier offset {}", this, my); - break; - } - - // We have traveled back, recover - LOG.debug("Queue {} retry pending barrier {} >= {}", this, prev, my); - my = prev; - } - } - - manager.ensureFlushing(this); - } - - private Long reserveEntry(final boolean forBarrier) { - final int offset = CURRENT_OFFSET_UPDATER.getAndIncrement(this); - if (offset >= reserve) { - if (forBarrier) { - LOG.debug("Queue {} offset {}/{}, using emergency slot", this, offset, queue.length); - return endXid; - } else { - LOG.debug("Queue {} offset {}/{}, not allowing reservation", this, offset, queue.length); - return null; - } - } - - final Long xid = baseXid + offset; - LOG.debug("Queue {} allocated XID {} at offset {}", this, xid, offset); - return xid; - } - - Long reserveBarrierIfNeeded() { - final int bo = barrierOffset; - if (bo >= flushOffset) { - LOG.debug("Barrier found at offset {} (currently at {})", bo, flushOffset); - return null; - } else { - return reserveEntry(true); - } - } - - int startShutdown() { - // Increment the offset by the queue size, hence preventing any normal - // allocations. We should not be seeing a barrier reservation after this - // and if there is one issued, we can disregard it. - final int offset = CURRENT_OFFSET_UPDATER.getAndAdd(this, queue.length); - - // If this offset is larger than reserve, trim it. That is not an accurate - // view of which slot was actually "reserved", but it indicates at which - // entry we can declare the queue flushed (e.g. at the emergency slot). - return offset > reserve ? reserve : offset; - } - - boolean isShutdown(final int offset) { - // This queue is shutdown if the flushOffset (e.g. the next entry to - // be flushed) points to the offset 'reserved' in startShutdown() - return flushOffset >= offset; - } - - /** - * An empty queue is a queue which has no further unflushed entries. - * - * @return True if this queue does not have unprocessed entries. - */ - private boolean isEmpty() { - int ro = reserveOffset; - if (ro >= reserve) { - if (queue[reserve].isCommitted()) { - ro = reserve + 1; - } else { - ro = reserve; - } - } - - LOG.debug("Effective flush/reserve offset {}/{}", flushOffset, ro); - return ro <= flushOffset; - } - - /** - * A queue is finished when all of its entries have been completed. - * - * @return False if there are any uncompleted requests. - */ - boolean isFinished() { - if (completeCount < reserve) { - return false; - } - - // We need to check if the last entry was used - final OutboundQueueEntry last = queue[reserve]; - return !last.isCommitted() || last.isCompleted(); - } - - boolean isFlushed() { - LOG.debug("Check queue {} for completeness (offset {}, reserve {})", this, flushOffset, reserve); - if (flushOffset < reserve) { - return false; - } - - // flushOffset implied == reserve - return flushOffset >= queue.length || !queue[reserve].isCommitted(); - } - - boolean needsFlush() { - if (flushOffset < reserve) { - return queue[flushOffset].isCommitted(); - } - - if (isFlushed()) { - LOG.trace("Queue {} is flushed, schedule a replace", this); - return true; - } - if (isFinished()) { - LOG.trace("Queue {} is finished, schedule a cleanup", this); - return true; - } - - return false; - } - - OfHeader flushEntry() { - for (;;) { - // No message ready - if (isEmpty()) { - LOG.trace("Flushed all reserved entries up to {}", flushOffset); - return null; - } - - final OutboundQueueEntry entry = queue[flushOffset]; - if (!entry.isCommitted()) { - LOG.trace("Request at offset {} not ready yet, giving up", flushOffset); - return null; - } - - final OfHeader msg = entry.takeMessage(); - flushOffset++; - if (msg != null) { - return msg; - } - - LOG.trace("Null message, skipping to offset {}", flushOffset); - } - } - - // Argument is 'long' to explicitly convert before performing operations - private boolean xidInRange(final long xid) { - return xid < endXid && (xid >= baseXid || baseXid > endXid); - } - - private static boolean completeEntry(final OutboundQueueEntry entry, final OfHeader response) { - if (response instanceof Error) { - final Error err = (Error)response; - 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 the request entry corresponding to a response. Returns null - * if there is no request matching the response. - * - * @param response Response message - * @return Matching request entry, or null if no match is found. - */ - OutboundQueueEntry pairRequest(@Nonnull final OfHeader response) { - final Long xid = response.getXid(); - if (!xidInRange(xid)) { - LOG.debug("Queue {} {}/{} ignoring XID {}", this, baseXid, queue.length, xid); - return null; - } - - final int offset = (int)(xid - baseXid); - final OutboundQueueEntry entry = queue[offset]; - if (entry.isCompleted()) { - LOG.debug("Entry {} already is completed, not accepting response {}", entry, response); - return null; - } - - if (entry.isBarrier()) { - // This has been a barrier -- make sure we complete all preceding requests. - // XXX: Barriers are expected to complete in one message. - // If this assumption is changed, this logic will need to be expanded - // to ensure that the requests implied by the barrier are reported as - // completed *after* the barrier. - LOG.trace("Barrier XID {} completed, cascading completion to XIDs {} to {}", xid, baseXid + lastBarrierOffset + 1, xid - 1); - completeRequests(offset); - lastBarrierOffset = offset; - - final boolean success = completeEntry(entry, response); - Verify.verify(success, "Barrier request failed to complete"); - completeCount++; - } else if (completeEntry(entry, response)) { - completeCount++; - } - - return entry; - } - - private void completeRequests(final int toOffset) { - for (int i = lastBarrierOffset + 1; i < toOffset; ++i) { - final OutboundQueueEntry entry = queue[i]; - if (!entry.isCompleted() && entry.complete(null)) { - completeCount++; - } - } - } - - void completeAll() { - completeRequests(queue.length); - } - - int failAll(final OutboundQueueException cause) { - int ret = 0; - for (int i = lastBarrierOffset + 1; i < queue.length; ++i) { - final OutboundQueueEntry entry = queue[i]; - if (!entry.isCommitted()) { - break; - } - - if (!entry.isCompleted()) { - entry.fail(cause); - ret++; - } - } - - return ret; - } -} 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 b3b7b8c3..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,65 +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 java.net.InetSocketAddress; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Queue; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; 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 { +final class OutboundQueueManager extends + AbstractOutboundQueueManager { private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueManager.class); - /** - * This is the default upper bound we place on the flush task running - * a single iteration. We relinquish control after about this amount - * of time. - */ - private static final long DEFAULT_WORKTIME_MICROS = TimeUnit.MILLISECONDS.toMicros(100); - - /** - * We re-check the time spent flushing every this many messages. We do this because - * checking after each message may prove to be CPU-intensive. Set to Integer.MAX_VALUE - * or similar to disable the feature. - */ - private static final int WORKTIME_RECHECK_MSGS = 64; - - private final Queue activeQueues = new LinkedList<>(); - private final AtomicBoolean flushScheduled = new AtomicBoolean(); - private final ConnectionAdapterImpl parent; - private final InetSocketAddress address; + private final int maxNonBarrierMessages; private final long maxBarrierNanos; - private final long maxWorkTime; - private final T handler; // Updated from netty only - private long lastBarrierNanos = System.nanoTime(); - private OutboundQueueCacheSlice slice; - private OutboundQueueImpl currentQueue; private boolean barrierTimerEnabled; + private long lastBarrierNanos = System.nanoTime(); private int nonBarrierMessages; - private long lastXid = 0; - private Integer shutdownOffset; - - // 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() { @@ -77,40 +37,17 @@ public void run() { }; OutboundQueueManager(final ConnectionAdapterImpl parent, final InetSocketAddress address, final T handler, - final OutboundQueueCacheSlice slice, final long maxBarrierNanos) { - this.parent = Preconditions.checkNotNull(parent); - this.handler = Preconditions.checkNotNull(handler); - this.slice = Preconditions.checkNotNull(slice); + final int maxNonBarrierMessages, final long maxBarrierNanos) { + super(parent, address, handler); + Preconditions.checkArgument(maxNonBarrierMessages > 0); + this.maxNonBarrierMessages = maxNonBarrierMessages; Preconditions.checkArgument(maxBarrierNanos > 0); this.maxBarrierNanos = maxBarrierNanos; - this.address = address; - this.maxWorkTime = TimeUnit.MICROSECONDS.toNanos(DEFAULT_WORKTIME_MICROS); - - LOG.debug("Queue manager instantiated with queue slice {}", slice); - createQueue(); - } - - T getHandler() { - return handler; } @Override - public void close() { - handler.onConnectionQueueChanged(null); - if (slice != null) { - slice.decRef(); - slice = null; - } - } - - private void createQueue() { - final long baseXid = lastXid; - lastXid += slice.getQueueSize() + 1; - - final OutboundQueueImpl queue = slice.getQueue(this, baseXid); - activeQueues.add(queue); - currentQueue = queue; - handler.onConnectionQueueChanged(queue); + protected StackedOutboundQueue initializeStackedOutboudnqueue() { + return new StackedOutboundQueue(this); } private void scheduleBarrierTimer(final long now) { @@ -133,12 +70,32 @@ private void scheduleBarrierMessage() { return; } - currentQueue.commitEntry(xid, handler.createBarrierRequest(xid), null); + currentQueue.commitEntry(xid, getHandler().createBarrierRequest(xid), null); LOG.trace("Barrier XID {} scheduled", xid); } + + /** + * Periodic barrier check. + */ + protected void barrier() { + LOG.debug("Channel {} barrier timer expired", parent.getChannel()); + barrierTimerEnabled = false; + if (shuttingDown) { + LOG.trace("Channel shut down, not processing barrier"); + return; + } + + if (currentQueue.isBarrierNeeded()) { + LOG.trace("Sending a barrier message"); + scheduleBarrierMessage(); + } else { + LOG.trace("Barrier not needed, not issuing one"); + } + } + /** - * Flush an entry from the queue. + * Write a message into the underlying channel. * * @param now Time reference for 'now'. We take this as an argument, as * we need a timestamp to mark barrier messages we see swinging @@ -146,309 +103,22 @@ private void scheduleBarrierMessage() { * hence we use the flush start time. Alternative would be to * measure System.nanoTime() for each barrier -- needlessly * adding overhead. - * - * @return Entry which was flushed, null if no entry is ready. */ - OfHeader flushEntry(final long now) { - final OfHeader message = currentQueue.flushEntry(); - if (currentQueue.isFlushed()) { - LOG.debug("Queue {} is fully flushed", currentQueue); - createQueue(); - } - - if (message == null) { - return null; - } - + @Override + void writeMessage(final OfHeader message, final long now) { + super.writeMessage(message, now); if (message instanceof BarrierInput) { LOG.trace("Barrier message seen, resetting counters"); nonBarrierMessages = 0; lastBarrierNanos = now; } else { nonBarrierMessages++; - if (nonBarrierMessages >= slice.getQueueSize()) { + if (nonBarrierMessages >= maxNonBarrierMessages) { LOG.trace("Scheduled barrier request after {} non-barrier messages", nonBarrierMessages); scheduleBarrierMessage(); } else if (!barrierTimerEnabled) { scheduleBarrierTimer(now); } } - - return message; - } - - /** - * 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); - - Iterator it = activeQueues.iterator(); - while (it.hasNext()) { - final OutboundQueueImpl 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() && activeQueues.size() > 1) { - LOG.trace("Queue {} indicated request was a barrier", queue); - - it = activeQueues.iterator(); - while (it.hasNext()) { - final OutboundQueueImpl 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(); - slice.putQueue(q); - } else { - break; - } - } - } - - if (queue.isFinished()) { - LOG.trace("Queue {} is finished", queue); - it.remove(); - slice.putQueue(queue); - } - - return true; - } - - LOG.debug("Failed to find completion for message {}", message); - return false; - } - - 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()); - } - } - - void ensureFlushing(final OutboundQueueImpl queue) { - Preconditions.checkState(currentQueue.equals(queue)); - scheduleFlush(); - } - - /** - * Periodic barrier check. - */ - protected void barrier() { - LOG.debug("Channel {} barrier timer expired", parent.getChannel()); - barrierTimerEnabled = false; - if (shutdownOffset != null) { - LOG.trace("Channel shut down, not processing 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 shutdownFlush() { - long entries = 0; - - // Fail all queues - final Iterator it = activeQueues.iterator(); - while (it.hasNext()) { - final OutboundQueueImpl queue = it.next(); - - entries += queue.failAll(OutboundQueueException.DEVICE_DISCONNECTED); - if (queue.isFinished()) { - LOG.trace("Cleared queue {}", queue); - it.remove(); - } - } - - LOG.debug("Cleared {} queue entries from channel {}", entries, parent.getChannel()); - - Preconditions.checkNotNull(currentQueue, "Current queue should not be null yet"); - if (currentQueue.isShutdown(shutdownOffset)) { - currentQueue = null; - handler.onConnectionQueueChanged(null); - LOG.debug("Channel {} shutdown complete", parent.getChannel()); - } else { - LOG.trace("Channel {} current queue not completely flushed yet", parent.getChannel()); - rescheduleFlush(); - } - } - - /** - * Perform a single flush operation. - */ - protected void flush() { - // If the channel is gone, just flush whatever is not completed - if (shutdownOffset != null) { - shutdownFlush(); - return; - } - - final long start = System.nanoTime(); - final long deadline = start + maxWorkTime; - - LOG.debug("Dequeuing messages to channel {}", parent.getChannel()); - - long messages = 0; - for (;; ++messages) { - if (!parent.getChannel().isWritable()) { - LOG.debug("Channel {} is no longer writable", parent.getChannel()); - break; - } - - final OfHeader message = flushEntry(start); - if (message == null) { - LOG.trace("The queue is completely drained"); - break; - } - - final Object wrapper; - if (address == null) { - wrapper = new MessageListenerWrapper(message, null); - } else { - wrapper = new UdpMessageListenerWrapper(message, null, address); - } - parent.getChannel().write(wrapper); - - /* - * Check every WORKTIME_RECHECK_MSGS for exceeded time. - * - * XXX: given we already measure our flushing throughput, we - * should be able to perform dynamic adjustments here. - * is that additional complexity needed, though? - */ - if ((messages % WORKTIME_RECHECK_MSGS) == 0 && System.nanoTime() >= deadline) { - LOG.trace("Exceeded allotted work time {}us", - TimeUnit.NANOSECONDS.toMicros(maxWorkTime)); - break; - } - } - - if (messages > 0) { - LOG.debug("Flushing {} message(s) to channel {}", messages, parent.getChannel()); - parent.getChannel().flush(); - } - - final long stop = System.nanoTime(); - LOG.debug("Flushed {} messages in {}us to channel {}", - messages, TimeUnit.NANOSECONDS.toMicros(stop - start), parent.getChannel()); - - rescheduleFlush(); - } - - /** - * 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 (shutdownOffset != null || 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"); - } - } - - private void conditionalFlush(final ChannelHandlerContext ctx) { - Preconditions.checkState(ctx.channel().equals(parent.getChannel()), "Inconsistent channel %s with context %s", parent.getChannel(), ctx); - conditionalFlush(); - } - - @Override - public void channelActive(final ChannelHandlerContext ctx) throws Exception { - super.channelActive(ctx); - conditionalFlush(ctx); - } - - @Override - public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception { - super.channelWritabilityChanged(ctx); - - if (flushScheduled.compareAndSet(false, true)) { - LOG.debug("Channel {} writability changed, invoking flush", parent.getChannel()); - flush(); - } else { - LOG.debug("Channel {} Writability changed, but task is already scheduled", parent.getChannel()); - } - } - - @Override - public void channelInactive(final ChannelHandlerContext ctx) throws Exception { - super.channelInactive(ctx); - - LOG.debug("Channel {} initiating shutdown...", parent.getChannel()); - - /* - * 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. - */ - shutdownOffset = currentQueue.startShutdown(); - if (slice != null) { - slice.decRef(); - slice = null; - } - - LOG.trace("Channel {} reserved all entries at offset {}", parent.getChannel(), shutdownOffset); - scheduleFlush(); - } - - @Override - public String toString() { - return String.format("Channel %s queue [flushing=%s]", parent.getChannel(), flushScheduled.get()); - } - - void onEchoRequest(final EchoRequestMessage message) { - final EchoReplyInput reply = new EchoReplyInputBuilder().setData(message.getData()).setVersion(message.getVersion()).setXid(message.getXid()).build(); - parent.getChannel().writeAndFlush(reply); } } 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 new file mode 100644 index 00000000..dd1e9520 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java @@ -0,0 +1,79 @@ +/* + * 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.connection; + +import com.google.common.util.concurrent.FutureCallback; + +import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import java.util.function.Function; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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 volatile long barrierXid = -1; + + 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 Function isCompletedFunction) { + final OutboundQueueEntry entry = getEntry(xid); + + entry.commit(message, callback, isCompletedFunction); + if (entry.isBarrier()) { + long my = xid; + for (;;) { + final long prev = BARRIER_XID_UPDATER.getAndSet(this, my); + if (prev < my) { + LOG.debug("Queue {} recorded pending barrier XID {}", this, my); + break; + } + + // We have traveled back, recover + LOG.debug("Queue {} retry pending barrier {} >= {}", this, prev, my); + my = prev; + } + } + + LOG.trace("Queue {} committed XID {}", this, xid); + manager.ensureFlushing(); + } + + Long reserveBarrierIfNeeded() { + if (isBarrierNeeded()) { + return reserveEntry(); + } + return null; + } + + /** + * 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 false; + } + 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 new file mode 100644 index 00000000..43aa002a --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java @@ -0,0 +1,202 @@ +/* + * 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.connection; + +import com.google.common.base.FinalizableReferenceQueue; +import com.google.common.base.FinalizableSoftReference; +import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; +import com.google.common.base.Verify; +import java.lang.ref.Reference; +import java.util.concurrent.ConcurrentLinkedDeque; +import org.opendaylight.openflowjava.protocol.api.connection.DeviceRequestFailedException; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class StackedSegment { + private static final class QueueRef extends FinalizableSoftReference { + QueueRef(final FinalizableReferenceQueue queue, final OutboundQueueEntry[] referent) { + super(referent, queue); + } + + @Override + public void finalizeReferent() { + CACHE.remove(this); + } + } + + /** + * Size of each individual segment + */ + static final int SEGMENT_SIZE = 4096; + + private static final Logger LOG = LoggerFactory.getLogger(StackedSegment.class); + private static final FinalizableReferenceQueue REF_QUEUE = new FinalizableReferenceQueue(); + private static final ConcurrentLinkedDeque CACHE = new ConcurrentLinkedDeque<>(); + + private final OutboundQueueEntry[] entries; + private final long baseXid; + private final long endXid; + + // Updated from netty only + private int lastBarrierOffset = -1; + private int completeCount; + + StackedSegment(final long baseXid, final OutboundQueueEntry[] entries) { + this.baseXid = baseXid; + this.endXid = baseXid + SEGMENT_SIZE; + this.entries = Preconditions.checkNotNull(entries); + } + + static StackedSegment create(final long baseXid) { + final StackedSegment ret; + for (;;) { + final Reference item = CACHE.pollLast(); + if (item == null) { + break; + } + + final OutboundQueueEntry[] cached = item.get(); + if (cached != null) { + ret = new StackedSegment(baseXid, cached); + LOG.trace("Reusing array {} in segment {}", cached, ret); + return ret; + } + } + + final OutboundQueueEntry[] entries = new OutboundQueueEntry[SEGMENT_SIZE]; + for (int i = 0; i < SEGMENT_SIZE; ++i) { + entries[i] = new OutboundQueueEntry(); + } + + ret = new StackedSegment(baseXid, entries); + LOG.trace("Allocated new segment {}", ret); + return ret; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("baseXid", baseXid).add("endXid", endXid).add("completeCount", completeCount).toString(); + } + + long getBaseXid() { + return baseXid; + } + + long getEndXid() { + return endXid; + } + + OutboundQueueEntry getEntry(final int offset) { + return entries[offset]; + } + + private boolean xidInRange(final long xid) { + return xid < endXid && (xid >= baseXid || baseXid > endXid); + } + + private static boolean completeEntry(final OutboundQueueEntry entry, final OfHeader response) { + if (response instanceof Error) { + final Error err = (Error)response; + LOG.debug("Device-reported request XID {} failed {}:{}", response.getXid(), err.getTypeString(), err.getCodeString()); + entry.fail(new DeviceRequestFailedException("Device-side failure", err)); + return true; + } + 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) { + // Explicitly 'long' to force unboxing before performing operations + final long xid = response.getXid(); + if (!xidInRange(xid)) { + LOG.debug("Queue {} {}/{} ignoring XID {}", this, baseXid, entries.length, xid); + return null; + } + + 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); + return null; + } + + if (entry.isBarrier()) { + // This has been a barrier -- make sure we complete all preceding requests. + // XXX: Barriers are expected to complete in one message. + // If this assumption is changed, this logic will need to be expanded + // to ensure that the requests implied by the barrier are reported as + // completed *after* the barrier. + LOG.trace("Barrier XID {} completed, cascading completion to XIDs {} to {}", xid, baseXid + lastBarrierOffset + 1, xid - 1); + completeRequests(offset); + lastBarrierOffset = offset; + + final boolean success = completeEntry(entry, response); + Verify.verify(success, "Barrier request failed to complete"); + completeCount++; + } else if (completeEntry(entry, response)) { + completeCount++; + } + + return entry; + } + + private void completeRequests(final int toOffset) { + for (int i = lastBarrierOffset + 1; i < toOffset; ++i) { + final OutboundQueueEntry entry = entries[i]; + if (!entry.isCompleted() && entry.complete(null)) { + completeCount++; + } + } + } + + void completeAll() { + completeRequests(entries.length); + } + + int failAll(final OutboundQueueException cause) { + int ret = 0; + for (int i = lastBarrierOffset + 1; i < entries.length; ++i) { + final OutboundQueueEntry entry = entries[i]; + if (!entry.isCommitted()) { + break; + } + + if (!entry.isCompleted()) { + entry.fail(cause); + completeCount++; + ret++; + } + } + + return ret; + } + + boolean isComplete() { + return completeCount >= entries.length; + } + + void recycle() { + for (final OutboundQueueEntry e : entries) { + e.reset(); + } + + CACHE.offer(new QueueRef(REF_QUEUE, entries)); + } +} 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 3479bcc0..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 @@ -10,7 +10,6 @@ import java.util.HashMap; import java.util.Map; - import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; @@ -25,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; /** @@ -38,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); @@ -57,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 @@ -68,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 c82408bf..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 @@ -8,23 +8,21 @@ 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.BarrierReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoRequestMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.ErrorMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.ExperimenterMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.FeaturesReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.FlowRemovedMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetAsyncReplyMessageFactory; 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; @@ -34,12 +32,13 @@ import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.PortStatusMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.QueueGetConfigReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.RoleReplyMessageFactory; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.VendorMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.SimpleDeserializerRegistryHelper; 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; @@ -52,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 { @@ -62,40 +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(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(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/ExperimenterMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java index 269976ff..244b4bfa 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java @@ -9,13 +9,15 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab @@ -24,17 +26,26 @@ public class ExperimenterMessageFactory implements OFDeserializer, DeserializerRegistryInjector { - /** Experimenter ID index after version, message type and length were read */ - private static final byte EXPERIMENTER_ID_INDEX = 4; private DeserializerRegistry deserializerRegistry; @Override public ExperimenterMessage deserialize(ByteBuf message) { - long expId = message.getUnsignedInt(message.readerIndex() + EXPERIMENTER_ID_INDEX); - OFDeserializer deserializer = deserializerRegistry.getDeserializer( + final long xid = message.readUnsignedInt(); + final long expId = message.readUnsignedInt(); + final long expType = message.readUnsignedInt(); + + OFDeserializer deserializer = deserializerRegistry.getDeserializer( ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey( - EncodeConstants.OF13_VERSION_ID, expId)); - return deserializer.deserialize(message); + EncodeConstants.OF13_VERSION_ID, expId, expType)); + final ExperimenterDataOfChoice vendorData = deserializer.deserialize(message); + + ExperimenterMessageBuilder messageBld = new ExperimenterMessageBuilder() + .setVersion((short) EncodeConstants.OF13_VERSION_ID) + .setXid(xid) + .setExperimenter(new ExperimenterId(expId)) + .setExpType(expType) + .setExperimenterDataOfChoice(vendorData); + return messageBld.build(); } @Override 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 b6e24b45..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 @@ -9,11 +9,9 @@ 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; @@ -24,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; @@ -38,6 +35,7 @@ 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.ExperimenterId; 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.GroupCapabilities; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupId; @@ -61,6 +59,7 @@ 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.experimenter.core.ExperimenterDataOfChoice; 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.MeterBandExperimenterCase; @@ -71,6 +70,7 @@ 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.MultipartReplyExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCaseBuilder; 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; @@ -97,6 +97,7 @@ 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.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.experimenter._case.MultipartReplyExperimenterBuilder; 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; @@ -140,6 +141,7 @@ /** * Translates MultipartReply messages + * * @author timotej.kubas * @author michal.polkorab */ @@ -179,7 +181,7 @@ public class MultipartReplyMessageFactory implements OFDeserializer flowStatsList = new ArrayList<>(); @@ -294,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; @@ -303,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]; @@ -318,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<>(); @@ -340,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<>(); @@ -367,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) { @@ -447,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<>(); @@ -500,8 +517,8 @@ private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) { return caseBuilder.build(); } - private static MultipartReplyQueueCase setQueue(ByteBuf input) { - MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder(); + private static MultipartReplyQueueCase setQueue(final ByteBuf input) { + MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder(); MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder(); List queueStatsList = new ArrayList<>(); while (input.readableBytes() > 0) { @@ -526,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<>(); @@ -566,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()); @@ -579,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; @@ -587,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<>(); @@ -632,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<>(); @@ -649,7 +666,7 @@ private MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) { int bandType = input.readUnsignedShort(); switch (bandType) { case 1: - MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder(); MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder(); bandDropBuilder.setType(MeterBandType.forValue(bandType)); actualLength += input.readUnsignedShort(); @@ -660,7 +677,7 @@ private MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) { bandsBuilder.setMeterBand(bandDropCaseBuilder.build()); break; case 2: - MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); + MeterBandDscpRemarkCaseBuilder bandDscpRemarkCaseBuilder = new MeterBandDscpRemarkCaseBuilder(); MeterBandDscpRemarkBuilder bandDscpRemarkBuilder = new MeterBandDscpRemarkBuilder(); bandDscpRemarkBuilder.setType(MeterBandType.forValue(bandType)); actualLength += input.readUnsignedShort(); @@ -693,12 +710,24 @@ private MultipartReplyMeterConfigCase setMeterConfig(ByteBuf input) { return caseBuilder.build(); } - private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) { - return registry.getDeserializer(ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey( - EncodeConstants.OF13_VERSION_ID, input.readUnsignedInt())); + private MultipartReplyExperimenterCase setExperimenter(final ByteBuf input) { + final long expId = input.readUnsignedInt(); + final long expType = input.readUnsignedInt(); + + final OFDeserializer deserializer = registry.getDeserializer( + ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey( + EncodeConstants.OF13_VERSION_ID, expId, expType)); + + final MultipartReplyExperimenterBuilder mpExperimenterBld = new MultipartReplyExperimenterBuilder() + .setExperimenter(new ExperimenterId(expId)) + .setExpType(expType) + .setExperimenterDataOfChoice(deserializer.deserialize(input)); + final MultipartReplyExperimenterCaseBuilder mpReplyExperimenterCaseBld = new MultipartReplyExperimenterCaseBuilder() + .setMultipartReplyExperimenter(mpExperimenterBld.build()); + 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<>(); @@ -706,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())); @@ -726,54 +753,54 @@ private static MultipartReplyPortDescCase setPortDesc(ByteBuf input) { return caseBuilder.build(); } - private static PortConfig createPortConfig(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; + 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 PortState createPortState(long input){ - final Boolean psLinkDown = ((input) & (1<<0)) != 0; - final Boolean psBlocked = ((input) & (1<<1)) != 0; - final Boolean psLive = ((input) & (1<<2)) != 0; + 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){ - 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; + 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); } - 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())); featuresBuilder.setCapabilities(createCapabilities(rawMessage.readUnsignedInt())); List maxGroupsList = new ArrayList<>(); - for (int i = 0; i < GROUP_TYPES ; i++) { + for (int i = 0; i < GROUP_TYPES; i++) { maxGroupsList.add(rawMessage.readUnsignedInt()); } featuresBuilder.setMaxGroups(maxGroupsList); List actionBitmaps = new ArrayList<>(); - for (int i = 0; i < GROUP_TYPES ; i++) { + for (int i = 0; i < GROUP_TYPES; i++) { actionBitmaps.add(createActionBitmap(rawMessage.readUnsignedInt())); } featuresBuilder.setActionsBitmap(actionBitmaps); @@ -781,23 +808,23 @@ private static MultipartReplyGroupFeaturesCase setGroupFeatures(ByteBuf rawMessa return caseBuilder.build(); } - private static ActionType createActionBitmap(long input) { - final Boolean atOutput = ((input) & (1<<0)) != 0; - final Boolean atCopyTTLout = ((input) & (1<<11)) != 0; - final Boolean atCopyTTLin = ((input) & (1<<12)) != 0; - final Boolean atSetMplsTTL = ((input) & (1<<15)) != 0; - final Boolean atDecMplsTTL = ((input) & (1<<16)) != 0; - final Boolean atPushVLAN = ((input) & (1<<17)) != 0; - final Boolean atPopVLAN = ((input) & (1<<18)) != 0; - final Boolean atPushMPLS = ((input) & (1<<19)) != 0; - final Boolean atPopMPLS = ((input) & (1<<20)) != 0; - final Boolean atSetQueue = ((input) & (1<<21)) != 0; - final Boolean atGroup = ((input) & (1<<22)) != 0; - final Boolean atSetNWTTL = ((input) & (1<<23)) != 0; - final Boolean atDecNWTTL = ((input) & (1<<24)) != 0; - final Boolean atSetField = ((input) & (1<<25)) != 0; - final Boolean atPushPBB = ((input) & (1<<26)) != 0; - final Boolean atPopPBB = ((input) & (1<<27)) != 0; + 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; + final Boolean atSetMplsTTL = ((input) & (1 << 15)) != 0; + final Boolean atDecMplsTTL = ((input) & (1 << 16)) != 0; + final Boolean atPushVLAN = ((input) & (1 << 17)) != 0; + final Boolean atPopVLAN = ((input) & (1 << 18)) != 0; + final Boolean atPushMPLS = ((input) & (1 << 19)) != 0; + final Boolean atPopMPLS = ((input) & (1 << 20)) != 0; + final Boolean atSetQueue = ((input) & (1 << 21)) != 0; + final Boolean atGroup = ((input) & (1 << 22)) != 0; + final Boolean atSetNWTTL = ((input) & (1 << 23)) != 0; + final Boolean atDecNWTTL = ((input) & (1 << 24)) != 0; + final Boolean atSetField = ((input) & (1 << 25)) != 0; + final Boolean atPushPBB = ((input) & (1 << 26)) != 0; + final Boolean atPopPBB = ((input) & (1 << 27)) != 0; final Boolean atExperimenter = false; return new ActionType(atCopyTTLin, atCopyTTLout, atDecMplsTTL, atDecNWTTL, atExperimenter, atGroup, atOutput, atPopMPLS, @@ -805,23 +832,23 @@ private static ActionType createActionBitmap(long input) { atSetField, atSetMplsTTL, atSetNWTTL, atSetQueue); } - private static GroupCapabilities createCapabilities(long input) { - final Boolean gcSelectWeight = ((input) & (1<<0)) != 0; - final Boolean gcSelectLiveness = ((input) & (1<<1)) != 0; - final Boolean gcChaining = ((input) & (1<<2)) != 0; - final Boolean gcChainingChecks = ((input) & (1<<3)) != 0; + 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; + final Boolean gcChainingChecks = ((input) & (1 << 3)) != 0; return new GroupCapabilities(gcChaining, gcChainingChecks, gcSelectLiveness, gcSelectWeight); } - private static GroupTypes createGroupType(long input) { - final Boolean gtAll = ((input) & (1<<0)) != 0; - final Boolean gtSelect = ((input) & (1<<1)) != 0; - final Boolean gtIndirect = ((input) & (1<<2)) != 0; - final Boolean gtFF = ((input) & (1<<3)) != 0; + 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; + final Boolean gtFF = ((input) & (1 << 3)) != 0; 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<>(); @@ -857,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, @@ -88,22 +91,29 @@ public MultipartReplyMessage deserialize(ByteBuf rawMessage) { builder.setType(MultipartType.forValue(type)); builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0)); switch (MultipartType.forValue(type)) { - case OFPMPDESC: builder.setMultipartReplyBody(setDesc(rawMessage)); - break; - case OFPMPFLOW: builder.setMultipartReplyBody(setFlow(rawMessage)); - break; - case OFPMPAGGREGATE: builder.setMultipartReplyBody(setAggregate(rawMessage)); - break; - case OFPMPTABLE: builder.setMultipartReplyBody(setTable(rawMessage)); - break; - case OFPMPPORTSTATS: builder.setMultipartReplyBody(setPortStats(rawMessage)); - break; - case OFPMPQUEUE: builder.setMultipartReplyBody(setQueue(rawMessage)); - break; - case OFPMPEXPERIMENTER: builder.setMultipartReplyBody(setExperimenter(rawMessage)); - break; - default: - break; + case OFPMPDESC: + builder.setMultipartReplyBody(setDesc(rawMessage)); + break; + case OFPMPFLOW: + builder.setMultipartReplyBody(setFlow(rawMessage)); + break; + case OFPMPAGGREGATE: + builder.setMultipartReplyBody(setAggregate(rawMessage)); + break; + case OFPMPTABLE: + builder.setMultipartReplyBody(setTable(rawMessage)); + break; + case OFPMPPORTSTATS: + builder.setMultipartReplyBody(setPortStats(rawMessage)); + break; + case OFPMPQUEUE: + builder.setMultipartReplyBody(setQueue(rawMessage)); + break; + case OFPMPEXPERIMENTER: + builder.setMultipartReplyBody(setExperimenter(rawMessage)); + break; + default: + break; } return builder.build(); } @@ -295,8 +305,16 @@ private static MultipartReplyQueueCase setQueue(ByteBuf input) { } private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) { - return registry.getDeserializer(ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey( - EncodeConstants.OF10_VERSION_ID, input.readUnsignedInt())); + final long expId = input.readUnsignedInt(); + final OFDeserializer deserializer = registry.getDeserializer(ExperimenterDeserializerKeyFactory.createMultipartReplyVendorMessageDeserializerKey( + EncodeConstants.OF10_VERSION_ID, expId)); + + final MultipartReplyExperimenterBuilder mpExperimenterBld = new MultipartReplyExperimenterBuilder() + .setExperimenter(new ExperimenterId(expId)) + .setExperimenterDataOfChoice(deserializer.deserialize(input)); + final MultipartReplyExperimenterCaseBuilder mpReplyExperimenterCaseBld = new MultipartReplyExperimenterCaseBuilder() + .setMultipartReplyExperimenter(mpExperimenterBld.build()); + return mpReplyExperimenterCaseBld.build(); } @Override diff --git a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java new file mode 100644 index 00000000..4f49f195 --- /dev/null +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java @@ -0,0 +1,170 @@ +/* + * 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.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.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.oxm.rev150225.match.v10.grouping.MatchV10; +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.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.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.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; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10StatsRequestInputFactory + 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/factories/VendorMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java index be6d0004..9461da1c 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java @@ -9,31 +9,39 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab - * */ public class VendorMessageFactory implements OFDeserializer, DeserializerRegistryInjector { - private static final byte VENDOR_ID_INDEX = 8; private DeserializerRegistry deserializerRegistry; @Override public ExperimenterMessage deserialize(ByteBuf message) { - long expId = message.getUnsignedInt(message.readerIndex() + VENDOR_ID_INDEX); - OFDeserializer deserializer = deserializerRegistry.getDeserializer( - ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey( + final long xid = message.readUnsignedInt(); + final long expId = message.readUnsignedInt(); + OFDeserializer deserializer = deserializerRegistry.getDeserializer( + ExperimenterDeserializerKeyFactory.createVendorMessageDeserializerKey( EncodeConstants.OF10_VERSION_ID, expId)); - return deserializer.deserialize(message); + final ExperimenterDataOfChoice vendorData = deserializer.deserialize(message); + + final ExperimenterMessageBuilder messageBld = new ExperimenterMessageBuilder() + .setVersion((short) EncodeConstants.OF10_VERSION_ID) + .setXid(xid) + .setExperimenter(new ExperimenterId(expId)) + .setExperimenterDataOfChoice(vendorData); + return messageBld.build(); } @Override 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 c3610c13..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 @@ -35,6 +35,7 @@ import org.opendaylight.openflowjava.protocol.impl.serialization.factories.SetAsyncInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.SetConfigMessageFactory; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.TableModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.VendorInputMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.CommonMessageRegistryHelper; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput; @@ -57,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 { @@ -67,17 +68,18 @@ 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()); - registryHelper.registerSerializer(ExperimenterInput.class, new ExperimenterInputMessageFactory()); + registryHelper.registerSerializer(ExperimenterInput.class, new VendorInputMessageFactory()); registryHelper.registerSerializer(FlowModInput.class, new OF10FlowModInputMessageFactory()); registryHelper.registerSerializer(GetConfigInput.class, new GetConfigInputMessageFactory()); registryHelper.registerSerializer(GetFeaturesInput.class, new GetFeaturesInputMessageFactory()); @@ -87,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()); @@ -107,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/ExperimenterInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java index 6dd5f663..b544a8ff 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java @@ -9,30 +9,41 @@ 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.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterOfMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** - * Translates Experimenter messages + * Translates Experimenter messages (both: symmetric request and single reply) * @author michal.polkorab */ -public class ExperimenterInputMessageFactory implements OFSerializer, +public class ExperimenterInputMessageFactory implements OFSerializer, SerializerRegistryInjector { private SerializerRegistry registry; + /** Code type of symmetric Experimenter message */ + private static final byte MESSAGE_TYPE = 4; + @Override - public void serialize(ExperimenterInput message, ByteBuf outBuffer) { + public void serialize(ExperimenterOfMessage message, ByteBuf outBuffer) { long expId = message.getExperimenter().getValue(); - OFSerializer serializer = registry.getSerializer( + OFSerializer serializer = registry.getSerializer( ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( - EncodeConstants.OF10_VERSION_ID, expId)); - serializer.serialize(message, outBuffer); + EncodeConstants.OF13_VERSION_ID, expId, message.getExpType().longValue())); + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + + // write experimenterId and type + outBuffer.writeInt(message.getExperimenter().getValue().intValue()); + outBuffer.writeInt(message.getExpType().intValue()); + + serializer.serialize(message.getExperimenterDataOfChoice(), outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer); } @Override 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 7afb253b..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 @@ -9,9 +9,7 @@ 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; @@ -23,7 +21,6 @@ import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ActionRelatedTableFeatureProperty; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequest; 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; @@ -37,6 +34,7 @@ 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.experimenter.core.ExperimenterDataOfChoice; 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.MultipartRequestAggregateCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.MultipartRequestDescCase; @@ -66,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 */ @@ -144,61 +142,44 @@ private void serializeExperimenterBody(final MultipartRequestInput message, MultipartRequestExperimenterCase expCase = (MultipartRequestExperimenterCase) message.getMultipartRequestBody(); MultipartRequestExperimenter experimenter = expCase.getMultipartRequestExperimenter(); - long expId = experimenter.getAugmentation(ExperimenterIdMultipartRequest.class).getExperimenter().getValue(); - OFSerializer serializer = registry.getSerializer( + final long expId = experimenter.getExperimenter().getValue().longValue(); + final long expType = experimenter.getExpType().longValue(); + + // write experimenterId and type + outBuffer.writeInt((int) expId); + outBuffer.writeInt((int) expType); + + // serialize experimenter data + OFSerializer serializer = registry.getSerializer( ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( - EncodeConstants.OF13_VERSION_ID, expId)); - serializer.serialize(expCase, outBuffer); + EncodeConstants.OF13_VERSION_ID, expId, expType)); + serializer.serialize(experimenter.getExperimenterDataOfChoice(), outBuffer); } private static int createMultipartRequestFlagsBitmask(final MultipartRequestFlags flags) { 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/OF10StatsRequestInputFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java index ca81ef13..fa01f6d8 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.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; @@ -17,10 +16,10 @@ import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequest; 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.MultipartRequestInput; +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.multipart.request.MultipartRequestBody; 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.MultipartRequestDescCase; @@ -132,11 +131,16 @@ private static void serializeQueueBody(final MultipartRequestBody multipartReque private void serializeExperimenterBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { MultipartRequestExperimenterCase expCase = (MultipartRequestExperimenterCase) multipartRequestBody; MultipartRequestExperimenter experimenter = expCase.getMultipartRequestExperimenter(); - long expId = experimenter.getAugmentation(ExperimenterIdMultipartRequest.class).getExperimenter().getValue(); - OFSerializer serializer = registry.getSerializer( + final long expId = experimenter.getExperimenter().getValue().longValue(); + + // write experimenterId + output.writeInt((int) expId); + + OFSerializer serializer = registry.getSerializer( ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( - EncodeConstants.OF10_VERSION_ID, expId)); - serializer.serialize(expCase, output); + EncodeConstants.OF10_VERSION_ID, expId, + -1 /* in order not to collide with OF >= 1.3 codecs*/)); + serializer.serialize(experimenter.getExperimenterDataOfChoice(), output); } @Override 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/factories/VendorInputMessageFactory.java b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java index 1cf2adc3..2cc7148e 100644 --- a/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java +++ b/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java @@ -9,30 +9,34 @@ 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.util.EncodeConstants; import org.opendaylight.openflowjava.util.ExperimenterSerializerKeyFactory; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterOfMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** - * Translates Vendor messages + * Translates Vendor messages (OF-1.0 limited version - skipping experimenter type) * @author michal.polkorab */ -public class VendorInputMessageFactory implements OFSerializer, +public class VendorInputMessageFactory implements OFSerializer, SerializerRegistryInjector { private SerializerRegistry registry; @Override - public void serialize(ExperimenterInput message, ByteBuf outBuffer) { + public void serialize(ExperimenterOfMessage message, ByteBuf outBuffer) { long expId = message.getExperimenter().getValue(); - OFSerializer serializer = registry.getSerializer( + OFSerializer serializer = registry.getSerializer( ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( - EncodeConstants.OF10_VERSION_ID, expId)); - serializer.serialize(message, outBuffer); + EncodeConstants.OF10_VERSION_ID, expId, message.getExpType().longValue())); + + // write experimenterId + outBuffer.writeInt(message.getExperimenter().getValue().intValue()); + + serializer.serialize(message.getExperimenterDataOfChoice(), outBuffer); } @Override 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 93d3c3e2..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 @@ -16,13 +16,18 @@ import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; 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.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author michal.polkorab * */ public final class ListDeserializer { + private static final Logger LOG = LoggerFactory.getLogger(ListDeserializer.class); private ListDeserializer() { throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); @@ -53,7 +58,7 @@ public static List deserializeList(short version, int } /** - * Deserializes headers of items into list + * Deserializes headers of items into list (used in MultipartReplyMessage - Table features) * @param version openflow wire version * @param length length of list in ByteBuf (bytes) * @param input input buffer @@ -67,8 +72,31 @@ 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 = registry.getDeserializer(keyMaker.make(input)); + HeaderDeserializer deserializer; + MessageCodeKey key = keyMaker.make(input); + try { + deserializer = registry.getDeserializer(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; + } E item = deserializer.deserializeHeader(input); items.add(item); } 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 a770e853..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 @@ -8,15 +8,18 @@ package org.opendaylight.openflowjava.protocol.impl.core.connection; 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.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPipeline; import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.socket.SocketChannel; - import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; - import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -57,11 +60,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; - /** * Test counters in ConnectionAdapter (at least DS_ENTERED_OFJAVA, DS_FLOW_MODS_ENTERED and US_MESSAGE_PASS counters have to be enabled) * @author madamjak @@ -143,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); @@ -200,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 c83e60c5..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 java.net.InetAddress; -import java.net.UnknownHostException; - +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ListenableFuture; 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; @@ -40,15 +42,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; 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.MultipartReplyMessage; +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.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; 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 com.google.common.util.concurrent.ListenableFuture; +import java.net.InetAddress; +import java.net.UnknownHostException; /** * @author madamjak @@ -59,12 +61,12 @@ public class SwitchConnectionProviderImpl02Test { @Mock OFGeneralSerializer serializer; @Mock OFGeneralDeserializer deserializer; @Mock OFDeserializer deserializerError; - @Mock OFDeserializer deserializerExpMsg; - @Mock OFDeserializer deserializerMultipartRplMsg; + @Mock OFDeserializer deserializerExpMsg; + @Mock OFDeserializer deserializerMultipartRplMsg; @Mock OFDeserializer deserializerQueueProperty; @Mock OFDeserializer deserializerMeterBandExpCase; - @Mock OFSerializer serializerExperimenterInput; - @Mock OFSerializer serializerMultipartRequestExpCase; + @Mock OFSerializer serializerExperimenterInput; + @Mock OFSerializer serializerMultipartRequestExpCase; @Mock OFSerializer serializerMeterBandExpCase; private static final int SWITCH_IDLE_TIMEOUT = 2000; private InetAddress startupAddress; @@ -76,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) { @@ -85,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); } @@ -109,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); } @@ -129,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)); } @@ -145,101 +148,107 @@ 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)); Assert.assertFalse("Wrong -- unregister MeterBandDeserializer by not existing key", provider.unregisterDeserializer(key11)); // -- registerExperimenterMessageSerializer - ExperimenterIdSerializerKey key12 - = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID,42L,ExperimenterInput.class); + ExperimenterIdSerializerKey key12 + = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterDataOfChoice.class); provider.registerExperimenterMessageSerializer(key12, serializerExperimenterInput); Assert.assertTrue("Wrong -- unregister ExperimenterMessageSerializer", provider.unregisterSerializer(key12)); Assert.assertFalse("Wrong -- unregister ExperimenterMessageSerializer by not existing key", provider.unregisterSerializer(key12)); //registerMultipartRequestSerializer - ExperimenterIdSerializerKey key13 - = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID,42L,MultipartRequestExperimenterCase.class); + ExperimenterIdSerializerKey key13 + = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterDataOfChoice.class); provider.registerMultipartRequestSerializer(key13, serializerMultipartRequestExpCase); 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/ExperimenterMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java index d25137ca..37dd6dde 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java @@ -10,35 +10,39 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.when; -import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBuf; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; +import org.mockito.runners.MockitoJUnitRunner; import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; import org.opendaylight.openflowjava.util.ByteBufUtils; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab * */ +@RunWith(MockitoJUnitRunner.class) public class ExperimenterMessageFactoryTest { @Mock DeserializerRegistry registry; - @Mock OFDeserializer deserializer; - @Mock ExperimenterMessage message; + @Mock OFDeserializer deserializer; + @Mock ExperimenterDataOfChoice message; + private ExperimenterMessageFactory factory; /** * Initializes mocks */ @Before public void startUp() { - MockitoAnnotations.initMocks(this); + factory = new ExperimenterMessageFactory(); } /** @@ -49,11 +53,10 @@ public void test() { when(registry.getDeserializer(any(ExperimenterIdDeserializerKey.class))).thenReturn(deserializer); when(deserializer.deserialize(any(ByteBuf.class))).thenReturn(message); - ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 01 02 03 00 00 00 10"); - ExperimenterMessageFactory factory = new ExperimenterMessageFactory(); + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 01 02 03 00 00 00 10 00 00 00 20"); factory.injectDeserializerRegistry(registry); ExperimenterMessage deserializedMessage = factory.deserialize(buffer); - Assert.assertEquals("Wrong return value", message, deserializedMessage); - Assert.assertEquals("ByteBuf index moved", 0, buffer.readerIndex()); + Assert.assertEquals("Wrong return value", message, deserializedMessage.getExperimenterDataOfChoice()); + Assert.assertEquals("ByteBuf index moved", 0, buffer.readableBytes()); } } \ 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/VendorMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java index 050eee0e..aaa94680 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories; import io.netty.buffer.ByteBuf; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,13 +35,13 @@ public class VendorMessageFactoryTest { */ @Test public void test() { - Mockito.when(registry.getDeserializer(Matchers.any(MessageCodeKey.class))).thenReturn(deserializer); - ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("04 04 00 10 01 02 03 04 FF FF FF FF 80 00 00 00"); + Mockito.when(registry.getDeserializer(Matchers.any())).thenReturn(deserializer); + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("01 02 03 04 FF FF FF FF 80 00 00 00"); VendorMessageFactory factory = new VendorMessageFactory(); factory.injectDeserializerRegistry(registry); factory.deserialize(buffer); Mockito.verify(deserializer, Mockito.times(1)).deserialize(buffer); - Assert.assertEquals("Buffer index modified", 16, buffer.readableBytes()); + Assert.assertEquals("Buffer index modified", 4, buffer.readableBytes()); } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java index 1e989ed3..5acb3f32 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories.multipart; import io.netty.buffer.ByteBuf; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -18,10 +17,12 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; 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.factories.MultipartReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab @@ -33,12 +34,15 @@ public class MultipartReplyExperimenterTest { @Mock DeserializerRegistry registry; private MultipartReplyMessageFactory factory = new MultipartReplyMessageFactory(); + @Mock + private OFDeserializer vendorDeserializer; /** * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO */ @Test public void testMultipartReplyExperimenter() { + Mockito.when(registry.getDeserializer(Matchers.any())).thenReturn(vendorDeserializer); factory.injectDeserializerRegistry(registry); ByteBuf bb = BufferHelper.buildBuffer("FF FF 00 01 00 00 00 00 " + "00 00 00 01 00 00 00 02"); // expID, expType @@ -48,6 +52,6 @@ public void testMultipartReplyExperimenter() { Assert.assertEquals("Wrong type", 65535, builtByFactory.getType().getIntValue()); Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); - Mockito.verify(registry, Mockito.times(1)).getDeserializer(Matchers.any(MessageCodeKey.class)); + Mockito.verify(vendorDeserializer).deserialize(bb); } } \ No newline at end of file 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/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java index 8986f5c8..69d420fe 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.deserialization.factories.multipart; import io.netty.buffer.ByteBuf; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -18,10 +17,12 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; 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.factories.OF10StatsReplyMessageFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab @@ -31,12 +32,14 @@ public class OF10StatsReplyExperimenterTest { @Mock DeserializerRegistry registry; + @Mock private OFDeserializer vendorDeserializer; /** * Tests {@link OF10StatsReplyMessageFactory} for experimenter body translation */ @Test public void test() { + Mockito.when(registry.getDeserializer(Matchers.any())).thenReturn(vendorDeserializer); OF10StatsReplyMessageFactory factory = new OF10StatsReplyMessageFactory(); factory.injectDeserializerRegistry(registry); @@ -47,6 +50,7 @@ public void test() { BufferHelper.checkHeaderV10(builtByFactory); Assert.assertEquals("Wrong type", 65535, builtByFactory.getType().getIntValue()); Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); - Mockito.verify(registry, Mockito.times(1)).getDeserializer(Matchers.any(MessageCodeKey.class)); + + Mockito.verify(vendorDeserializer).deserialize(bb); } } \ 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/ExperimenterInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java index 89e0f958..9b6720e4 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java @@ -9,8 +9,6 @@ package org.opendaylight.openflowjava.protocol.impl.serialization.factories; import io.netty.buffer.ByteBuf; -import io.netty.buffer.UnpooledByteBufAllocator; - import org.junit.Test; import org.mockito.Matchers; import org.mockito.Mock; @@ -26,6 +24,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterOfMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab @@ -34,8 +34,13 @@ public class ExperimenterInputMessageFactoryTest { @Mock SerializerRegistry registry; - @Mock OFSerializer serializer; - private OFSerializer expFactory; + @Mock + private OFSerializer serializer; + private OFSerializer expFactory; + @Mock + private ExperimenterDataOfChoice vendorData; + @Mock + private ByteBuf out; /** * Sets up ExperimenterInputMessageFactory @@ -64,9 +69,10 @@ public void testV10Real() throws Exception { ExperimenterInputBuilder builder = new ExperimenterInputBuilder(); BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); builder.setExperimenter(new ExperimenterId(42L)); + builder.setExpType(21L); + builder.setExperimenterDataOfChoice(vendorData); ExperimenterInput input = builder.build(); - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); expFactory.serialize(input, out); } @@ -81,9 +87,10 @@ public void testV13Real() throws Exception { ExperimenterInputBuilder builder = new ExperimenterInputBuilder(); BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); builder.setExperimenter(new ExperimenterId(42L)); + builder.setExpType(22L); + builder.setExperimenterDataOfChoice(vendorData); ExperimenterInput input = builder.build(); - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); expFactory.serialize(input, out); } @@ -98,13 +105,15 @@ public void testV10() throws Exception { ExperimenterInputBuilder builder = new ExperimenterInputBuilder(); BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); builder.setExperimenter(new ExperimenterId(42L)); + builder.setExpType(21L); + builder.setExperimenterDataOfChoice(vendorData); ExperimenterInput input = builder.build(); Mockito.when(registry.getSerializer( (ExperimenterIdSerializerKey) Matchers.any())).thenReturn(serializer); - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); expFactory.serialize(input, out); + Mockito.verify(serializer, Mockito.times(1)).serialize(input.getExperimenterDataOfChoice(), out); } /** @@ -118,12 +127,14 @@ public void testV13() throws Exception { ExperimenterInputBuilder builder = new ExperimenterInputBuilder(); BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); builder.setExperimenter(new ExperimenterId(42L)); + builder.setExpType(21L); + builder.setExperimenterDataOfChoice(vendorData); ExperimenterInput input = builder.build(); Mockito.when(registry.getSerializer( (ExperimenterIdSerializerKey) Matchers.any())).thenReturn(serializer); - ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); expFactory.serialize(input, out); + Mockito.verify(serializer, Mockito.times(1)).serialize(input.getExperimenterDataOfChoice(), out); } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java index edf21a2c..a3a72a27 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java @@ -154,8 +154,19 @@ public void testFlowModInputMessageFactory() throws Exception { FlowModInput message = builder.build(); ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + // simulate parent message + out.writeInt(1); + out.writeZero(2); + out.writeShort(3); + flowModFactory.serialize(message, out); + // read parent message + out.readInt(); + out.skipBytes(2); + out.readShort(); + BufferHelper.checkHeaderV13(out,(byte) 14, 128); cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; out.readBytes(cookie); diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java 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/VendorInputMessageFactoryTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java index 15496598..f299e818 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java @@ -10,19 +10,21 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.PooledByteBufAllocator; - import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; /** * @author michal.polkorab @@ -32,14 +34,16 @@ public class VendorInputMessageFactoryTest { @Mock SerializerRegistry registry; - @Mock ExperimenterInputMessageFactory serializer; + @Mock OFSerializer foundSerializer; + @Mock ExperimenterDataOfChoice vendorData; + VendorInputMessageFactory serializer; /** - * Tests {@link VendorInputMessageFactory#serialize(ExperimenterInput, ByteBuf)} + * Tests {@link VendorInputMessageFactory#serialize(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterOfMessage, ByteBuf)} */ @Test public void test() { - Mockito.when(registry.getSerializer((MessageTypeKey) Matchers.any(MessageTypeKey.class))) + Mockito.when(registry.getSerializer(Matchers.>any())) .thenReturn(serializer); VendorInputMessageFactory factory = new VendorInputMessageFactory(); factory.injectSerializerRegistry(registry); @@ -49,9 +53,12 @@ public void test() { builder.setXid(12345L); builder.setExperimenter(new ExperimenterId(42L)); builder.setExpType(84L); + builder.setExperimenterDataOfChoice(vendorData); ExperimenterInput experimenterInput = builder.build(); + Mockito.when(registry.getSerializer(Matchers.>any())) + .thenReturn(foundSerializer); factory.serialize(experimenterInput, buffer); - Mockito.verify(serializer, Mockito.times(1)).serialize(experimenterInput, buffer); + Mockito.verify(foundSerializer, Mockito.times(1)).serialize(experimenterInput.getExperimenterDataOfChoice(), buffer); } } \ No newline at end of file diff --git a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java index c4d58dc9..ce94f426 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java @@ -10,7 +10,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,18 +19,16 @@ import org.mockito.runners.MockitoJUnitRunner; import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; -import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequest; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequestBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.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.MultipartRequestInputBuilder; -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.experimenter.core.ExperimenterDataOfChoice; 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.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; @@ -43,7 +40,9 @@ public class MultipartRequestExperimenterTest { @Mock SerializerRegistry mockRegistry; - @Mock OFSerializer serializer; + @Mock OFSerializer serializer; + + @Mock ExperimenterDataOfChoice vendorData; /** * Testing OF10StatsRequestInputFactory (Experimenter) for correct serialization @@ -51,7 +50,7 @@ public class MultipartRequestExperimenterTest { */ @Test public void testExperimenter() throws Exception { - Mockito.when(mockRegistry.getSerializer(Matchers.any(ExperimenterIdSerializerKey.class))) + Mockito.when(mockRegistry.getSerializer(Matchers.>any())) .thenReturn(serializer); MultipartRequestInputFactory multipartFactory = new MultipartRequestInputFactory(); multipartFactory.injectSerializerRegistry(mockRegistry); @@ -61,9 +60,9 @@ public void testExperimenter() throws Exception { builder.setFlags(new MultipartRequestFlags(false)); MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); MultipartRequestExperimenterBuilder expBuilder = new MultipartRequestExperimenterBuilder(); - ExperimenterIdMultipartRequestBuilder expIdBuilder = new ExperimenterIdMultipartRequestBuilder(); - expIdBuilder.setExperimenter(new ExperimenterId(42L)); - expBuilder.addAugmentation(ExperimenterIdMultipartRequest.class, expIdBuilder.build()); + expBuilder.setExperimenter(new ExperimenterId(42L)); + expBuilder.setExpType(21L); + expBuilder.setExperimenterDataOfChoice(vendorData); caseBuilder.setMultipartRequestExperimenter(expBuilder.build()); builder.setMultipartRequestBody(caseBuilder.build()); MultipartRequestInput message = builder.build(); @@ -71,9 +70,9 @@ public void testExperimenter() throws Exception { ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); multipartFactory.serialize(message, out); - BufferHelper.checkHeaderV13(out, (byte) 18, 16); + BufferHelper.checkHeaderV13(out, (byte) 18, 24); Assert.assertEquals("Wrong type", 65535, out.readUnsignedShort()); Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); - Mockito.verify(serializer, Mockito.times(1)).serialize(Matchers.any(MultipartRequestExperimenterCase.class), Matchers.any(ByteBuf.class)); + Mockito.verify(serializer, Mockito.times(1)).serialize(vendorData, out); } } \ No newline at end of file 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/factories/multipart/OF10StatsRequestExperimenterTest.java b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java index 0fcacef1..15430aa6 100644 --- a/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java +++ b/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java @@ -10,7 +10,6 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.UnpooledByteBufAllocator; - import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -20,18 +19,16 @@ import org.mockito.runners.MockitoJUnitRunner; import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; -import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10StatsRequestInputFactory; import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequest; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdMultipartRequestBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.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.MultipartRequestInputBuilder; -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.experimenter.core.ExperimenterDataOfChoice; 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.multipart.request.experimenter._case.MultipartRequestExperimenterBuilder; @@ -43,7 +40,9 @@ public class OF10StatsRequestExperimenterTest { @Mock SerializerRegistry mockRegistry; - @Mock OFSerializer serializer; + @Mock OFSerializer serializer; + @Mock + private ExperimenterDataOfChoice vendorData; /** * Testing OF10StatsRequestInputFactory (Experimenter) for correct serialization @@ -51,7 +50,7 @@ public class OF10StatsRequestExperimenterTest { */ @Test public void testExperimenter() throws Exception { - Mockito.when(mockRegistry.getSerializer(Matchers.any(ExperimenterIdSerializerKey.class))) + Mockito.when(mockRegistry.getSerializer(Matchers.>any())) .thenReturn(serializer); OF10StatsRequestInputFactory multipartFactory = new OF10StatsRequestInputFactory(); multipartFactory.injectSerializerRegistry(mockRegistry); @@ -61,9 +60,9 @@ public void testExperimenter() throws Exception { builder.setFlags(new MultipartRequestFlags(false)); MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); MultipartRequestExperimenterBuilder expBuilder = new MultipartRequestExperimenterBuilder(); - ExperimenterIdMultipartRequestBuilder expIdBuilder = new ExperimenterIdMultipartRequestBuilder(); - expIdBuilder.setExperimenter(new ExperimenterId(42L)); - expBuilder.addAugmentation(ExperimenterIdMultipartRequest.class, expIdBuilder.build()); + expBuilder.setExperimenter(new ExperimenterId(42L)); + expBuilder.setExpType(21L); + expBuilder.setExperimenterDataOfChoice(vendorData); caseBuilder.setMultipartRequestExperimenter(expBuilder.build()); builder.setMultipartRequestBody(caseBuilder.build()); MultipartRequestInput message = builder.build(); @@ -71,9 +70,9 @@ public void testExperimenter() throws Exception { ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); multipartFactory.serialize(message, out); - BufferHelper.checkHeaderV10(out, (byte) 16, 12); + BufferHelper.checkHeaderV10(out, (byte) 16, 16); Assert.assertEquals("Wrong type", 65535, out.readUnsignedShort()); Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); - Mockito.verify(serializer, Mockito.times(1)).serialize(Matchers.any(MultipartRequestExperimenterCase.class), Matchers.any(ByteBuf.class)); + Mockito.verify(serializer, Mockito.times(1)).serialize(vendorData, out); } } \ 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 54f586df..58628b30 100644 --- a/openflow-protocol-it/pom.xml +++ b/openflow-protocol-it/pom.xml @@ -2,12 +2,15 @@ 4.0.0 org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 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 5a7432aa..67a9aa90 100644 --- a/openflow-protocol-spi/pom.xml +++ b/openflow-protocol-spi/pom.xml @@ -2,13 +2,16 @@ 4.0.0 org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 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 @@ -22,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,* @@ -52,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 @@ -72,9 +72,9 @@ ${config.version} - org.opendaylight.yangtools + 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 ccdb859c..419a0609 100644 --- a/openflowjava-config/pom.xml +++ b/openflowjava-config/pom.xml @@ -10,13 +10,16 @@ org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 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/util/pom.xml b/openflowjava-util/pom.xml similarity index 63% rename from util/pom.xml rename to openflowjava-util/pom.xml index a05f694a..c296e5a7 100644 --- a/util/pom.xml +++ b/openflowjava-util/pom.xml @@ -4,11 +4,15 @@ 4.0.0 org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent bundle - util + openflowjava-util + + ODL :: openflowjava :: ${project.artifactId} diff --git a/util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java similarity index 86% rename from util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java rename to openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java index d68f6f9c..5d6869cf 100644 --- a/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/util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java similarity index 69% rename from util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java rename to openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java index 36f44ff2..6e285f95 100644 --- a/util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java @@ -9,16 +9,15 @@ package org.opendaylight.openflowjava.util; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeDeserializerKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.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.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.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase; 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; /** * @author michal.polkorab - * */ public abstract class ExperimenterDeserializerKeyFactory { @@ -39,21 +38,43 @@ public static ExperimenterIdDeserializerKey createExperimenterErrorDeserializerK /** * @param version openflow wire version * @param experimenterId experimenter / vendor ID + * @param type experimenter type according to vendor implementation * @return key instance */ - public static ExperimenterIdDeserializerKey createExperimenterMessageDeserializerKey( - short version, Long experimenterId) { - return new ExperimenterIdDeserializerKey(version, experimenterId, ExperimenterMessage.class); + public static ExperimenterIdTypeDeserializerKey createExperimenterMessageDeserializerKey( + short version, long experimenterId, long type) { + return new ExperimenterIdTypeDeserializerKey(version, experimenterId, type, ExperimenterDataOfChoice.class); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createVendorMessageDeserializerKey( + short version, long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, ExperimenterDataOfChoice.class); } /** * @param version openflow wire version * @param experimenterId experimenter / vendor ID + * @param type * @return key instance */ - public static ExperimenterIdDeserializerKey createMultipartReplyMessageDeserializerKey( - short version, Long experimenterId) { - return new ExperimenterIdDeserializerKey(version, experimenterId, MultipartReplyExperimenterCase.class); + public static ExperimenterIdTypeDeserializerKey createMultipartReplyMessageDeserializerKey( + short version, long experimenterId, long type) { + return new ExperimenterIdTypeDeserializerKey(version, experimenterId, type, ExperimenterDataOfChoice.class); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createMultipartReplyVendorMessageDeserializerKey( + short version, long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, ExperimenterDataOfChoice.class); } /** @@ -85,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/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 similarity index 51% rename from util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java rename to openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java index 36033d07..ea0a69ce --- a/util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java +++ b/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java @@ -8,36 +8,39 @@ package org.opendaylight.openflowjava.util; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; +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.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; /** * @author michal.polkorab - * */ public abstract class ExperimenterSerializerKeyFactory { /** * @param msgVersion openflow wire version * @param experimenterId experimenter / vendor ID + * @param type experimenter type according to vendor implementation * @return key instance */ - public static ExperimenterIdSerializerKey createExperimenterMessageSerializerKey( - short msgVersion, Long experimenterId) { - return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, ExperimenterInput.class); + public static ExperimenterIdSerializerKey createExperimenterMessageSerializerKey( + short msgVersion, long experimenterId, long type) { + return new ExperimenterIdTypeSerializerKey<>(msgVersion, experimenterId, type, ExperimenterDataOfChoice.class); } /** * @param msgVersion openflow wire version * @param experimenterId experimenter / vendor ID + * @param type experimenter type according to vendor implementation * @return key instance */ - public static ExperimenterIdSerializerKey createMultipartRequestSerializerKey( - short msgVersion, Long experimenterId) { - return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, MultipartRequestExperimenterCase.class); + public static ExperimenterIdSerializerKey createMultipartRequestSerializerKey( + short msgVersion, long experimenterId, long type) { + return new ExperimenterIdTypeSerializerKey<>(msgVersion, experimenterId, type, ExperimenterDataOfChoice.class); } /** @@ -46,7 +49,7 @@ public static ExperimenterIdSerializerKey crea * @return key instance */ public static ExperimenterIdSerializerKey createMultipartRequestTFSerializerKey( - short msgVersion, Long experimenterId) { + short msgVersion, long experimenterId) { return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, TableFeatureProperties.class); } @@ -56,7 +59,13 @@ public static ExperimenterIdSerializerKey createMultipar * @return key instance */ public static ExperimenterIdSerializerKey createMeterBandSerializerKey( - short msgVersion, Long experimenterId) { - return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, MeterBandExperimenterCase.class); + short msgVersion, long experimenterId) { + 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/util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java similarity index 91% rename from util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java rename to openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java index 7113eb06..b7f0f593 100644 --- a/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/util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java similarity index 54% rename from util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java rename to openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java index 1b422d31..a8cc8368 100644 --- a/util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java +++ b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java @@ -11,84 +11,111 @@ import org.junit.Assert; import org.junit.Test; import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeDeserializerKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; 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.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.multipart.reply.multipart.reply.body.MultipartReplyExperimenterCase; 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; /** * @author michal.polkorab - * */ public class ExperimenterDeserializerKeyFactoryTest { - /** - * Test ExperimenterDeserializerKeyFactory key creation - */ @Test - public void test() { - ExperimenterIdDeserializerKey createdKey = ExperimenterDeserializerKeyFactory + public void testCreateExperimenterErrorDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory .createExperimenterErrorDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); - ExperimenterIdDeserializerKey comparationKey = - new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ErrorMessage.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, ErrorMessage.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey( - EncodeConstants.OF10_VERSION_ID, 43L); - comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - 43L, ExperimenterMessage.class); + comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ErrorMessage.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @Test + public void testCreateExperimenterMessageDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + createdKey = ExperimenterDeserializerKeyFactory.createExperimenterMessageDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, ExperimenterMessage.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createMeterBandDeserializerKey( - EncodeConstants.OF10_VERSION_ID, 44L); - comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - 44L, MeterBandExperimenterCase.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createMeterBandDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, MeterBandExperimenterCase.class); + EncodeConstants.OF10_VERSION_ID, 43L, 1L); + comparationKey = new ExperimenterIdTypeDeserializerKey(EncodeConstants.OF10_VERSION_ID, + 43L, 1L, ExperimenterDataOfChoice.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @Test + public void testCreateMultipartReplyMessageDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey( - EncodeConstants.OF10_VERSION_ID, 45L); + EncodeConstants.OF10_VERSION_ID, 45L, 1L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - 45L, MultipartReplyExperimenterCase.class); + 45L, ExperimenterDataOfChoice.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyMessageDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); + } + + @Test + public void testCreateMultipartReplyTFDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyTFDeserializerKey( + EncodeConstants.OF10_VERSION_ID, 46L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, MultipartReplyExperimenterCase.class); + 46L, TableFeatureProperties.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyTFDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); + } + + @Test + public void testCreateQueuePropertyDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory.createQueuePropertyDeserializerKey( + EncodeConstants.OF10_VERSION_ID, 47L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, TableFeatureProperties.class); + 47L, QueueProperty.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyTFDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); + } + + @Test + public void testCreateMeterBandDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory.createMeterBandDeserializerKey( + EncodeConstants.OF10_VERSION_ID, 44L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, TableFeatureProperties.class); + 44L, MeterBandExperimenterCase.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createQueuePropertyDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); + } + + @Test + public void testCreateVendorMessageDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory.createVendorMessageDeserializerKey( + EncodeConstants.OF10_VERSION_ID, 43L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, QueueProperty.class); + 43L, ExperimenterDataOfChoice.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterDeserializerKeyFactory.createQueuePropertyDeserializerKey( - EncodeConstants.OF10_VERSION_ID, null); + } + + @Test + public void testCreateMultipartReplyVendorMessageDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory.createMultipartReplyVendorMessageDeserializerKey( + EncodeConstants.OF10_VERSION_ID, 43L); comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, - null, QueueProperty.class); + 43L, ExperimenterDataOfChoice.class); Assert.assertEquals("Wrong key created", comparationKey, createdKey); } } \ No newline at end of file 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 new file mode 100755 index 00000000..471e4133 --- /dev/null +++ b/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java @@ -0,0 +1,104 @@ +/* + * 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.util; + +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; + +/** + * Test ExperimenterSerializerKeyFactory key creation + * @author michal.polkorab + * + */ +public class ExperimenterSerializerKeyFactoryTest { + + @Test + public void testCreateExperimenterMessageSerializerKey() throws Exception { + ExperimenterIdSerializerKey createdKey; + ExperimenterIdSerializerKey comparationKey; + + createdKey = ExperimenterSerializerKeyFactory + .createExperimenterMessageSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, 1L); + comparationKey = new ExperimenterIdTypeSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 42L, 1L, ExperimenterDataOfChoice.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @Test + public void testCreateMultipartRequestSerializerKey() throws Exception { + ExperimenterIdSerializerKey createdKey; + ExperimenterIdSerializerKey comparationKey; + + createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( + EncodeConstants.OF10_VERSION_ID, 44L, 1L); + comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 44L, ExperimenterDataOfChoice.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @Test + public void testCreateMultipartRequestTFSerializerKey() throws Exception { + ExperimenterIdSerializerKey createdKey; + ExperimenterIdSerializerKey comparationKey; + + createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestTFSerializerKey( + EncodeConstants.OF10_VERSION_ID, 45L); + comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 45L, TableFeatureProperties.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @Test + public void testCreateMeterBandSerializerKey() throws Exception { + ExperimenterIdSerializerKey createdKey; + ExperimenterIdSerializerKey comparationKey; + + createdKey = ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( + EncodeConstants.OF10_VERSION_ID, 43L); + comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + 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 new file mode 100644 index 00000000..4238e080 --- /dev/null +++ b/parent/pom.xml @@ -0,0 +1,392 @@ + + + 4.0.0 + + org.opendaylight.odlparent + odlparent + 2.0.0 + + + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + pom + + ODL :: openflowjava :: ${project.artifactId} + + Openflow protocol library - serializes and deserializes openflow messages + handles connections with openflow devices. + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + + + + The Eclipse Public License v1.0 + http://www.eclipse.org/legal/epl-v10.html + repo + + + + + scm:git:ssh://git.opendaylight.org:29418/openflowjava.git + scm:git:ssh://git.opendaylight.org:29418/openflowjava.git + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + Michal Polkorab + michal.polkorab@pantheon.sk + Pantheon Technologies + https://www.pantheon.sk/en/ + + + Michal Rehak + mirehak@cisco.com + Cisco Systems + www.cisco.com + + + + + UTF-8 + ${project.build.directory}/yang-gen-config + ${project.build.directory}/yang-gen-sal + + 0.7.0-SNAPSHOT + 1.6.0-SNAPSHOT + 0.11.0-SNAPSHOT + 1.2.0-SNAPSHOT + 0.7.0 + + + + + + org.opendaylight.openflowjava + openflowjava-artifacts + ${project.version} + pom + import + + + org.opendaylight.yangtools + yangtools-artifacts + ${yangtools.version} + pom + import + + + org.opendaylight.controller + config-artifacts + ${config.version} + pom + import + + + org.opendaylight.controller + mdsal-artifacts + ${controller.mdsal.version} + import + pom + + + net.sourceforge.argparse4j + argparse4j + ${argparse4j.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + maven-source-plugin + + + attach-sources + deploy + + jar-no-fork + + + + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.groupId}.${project.artifactId} + + ${project.build.directory}/META-INF + + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle.version} + + false + checkstyle-logging.xml + true + true + ${project.basedir} + **\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang + **\/target\/,**\/bin\/,**\/target-ide\/,**\/src/main/yang-gen-config\/,**\/src/main/yang-gen-sal\/ + + + + org.opendaylight.yangtools + checkstyle-logging + ${yangtools.version} + + + + + + check + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-yang-sources + generate-sources + + add-source + + + + ${jmxGeneratorPath} + ${salGeneratorPath} + + + + + + + + + + org.opendaylight.yangtools + yang-maven-plugin + ${yangtools.version} + + + org.codehaus.mojo + build-helper-maven-plugin + 1.8 + + + add-source + + add-source + + generate-sources + + + src/main/yang + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.codehaus.mojo + properties-maven-plugin + [0.0,) + + set-system-properties + + + + + + + + + org.jacoco + jacoco-maven-plugin + [0.0,) + + prepare-agent + pre-test + post-test + + + + + + + + + org.ops4j.pax.exam + maven-paxexam-plugin + [1.2.4,) + + generate-depends-file + + + + + false + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + [2.0,) + + check + + + + + + + + + org.codehaus.groovy.maven + gmaven-plugin + 1.0 + + execute + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + ${enforcer.version} + + enforce + + + + + + + + + + + + + + + + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.2 + + Max + Low + site + + + + maven-jxr-plugin + 2.3 + + true + true + + + + + org.codehaus.mojo + jdepend-maven-plugin + 2.0-beta-2 + + + + + + viewbuild + + true + + + ${project.version} + + + + jenkins + + + BUILDSUFFIX + + + + ${BUILDSUFFIX} + + + + repoBuild + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.8.1 + + + + aggregate + + site + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + package + + jar-no-fork + + + + + + + + + diff --git a/pom.xml b/pom.xml index 6ebe3748..e3eda8b0 100644 --- a/pom.xml +++ b/pom.xml @@ -2,445 +2,26 @@ 4.0.0 - org.opendaylight.odlparent - odlparent - 1.6.0-SNAPSHOT - + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + parent - org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT - openflowjava + openflowjava-aggregator pom artifacts features openflowjava-config + openflowjava-blueprint-config openflow-protocol-api openflow-protocol-impl openflow-protocol-it openflow-protocol-spi + parent simple-client - util + openflowjava-util - - scm:git:ssh://git.opendaylight.org:29418/openflowjava.git - scm:git:ssh://git.opendaylight.org:29418/openflowjava.git - https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main - HEAD - - - - 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 - - - 2.4 - jacoco - target/code-coverage/jacoco.exec - target/code-coverage/jacoco-it.exec - - - - - - org.opendaylight.openflowjava - openflowjava-artifacts - ${project.version} - pom - import - - - org.opendaylight.yangtools - yangtools-artifacts - ${yangtools.version} - pom - import - - - org.opendaylight.controller - config-artifacts - ${config.version} - pom - import - - - org.opendaylight.controller - mdsal-artifacts - ${mdsal.version} - import - pom - - - - - - - - org.codehaus.sonar-plugins.java - sonar-jacoco-listeners - ${sonar-jacoco-listeners.version} - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - true - - 1.7 - 1.7 - - - - maven-source-plugin - - - attach-sources - deploy - - jar-no-fork - - - - - - org.apache.felix - maven-bundle-plugin - true - - - ${project.groupId}.${project.artifactId} - - ${project.build.directory}/META-INF - - - - org.apache.maven.plugins - maven-checkstyle-plugin - 2.12 - - false - checkstyle-logging.xml - true - true - ${project.basedir} - **\/*.java,**\/*.xml,**\/*.ini,**\/*.sh,**\/*.bat,**\/*.yang - **\/target\/,**\/bin\/,**\/target-ide\/,**\/src/main/yang-gen-config\/,**\/src/main/yang-gen-sal\/ - - - - org.opendaylight.yangtools - checkstyle-logging - ${yangtools.version} - - - - - - check - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - org.jacoco - jacoco-maven-plugin - - - prepare-ut-agent - process-test-classes - - prepare-agent - - - ${sonar.jacoco.reportPath} - jacoco.agent.ut.arg - - - - prepare-it-agent - pre-integration-test - - prepare-agent - - - ${sonar.jacoco.itReportPath} - jacoco.agent.it.arg - - - - - - - - - org.opendaylight.yangtools - yang-maven-plugin - ${yangtools.version} - - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 - - - add-source - - add-source - - generate-sources - - - src/main/yang - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - ${jacoco.agent.it.arg} - - - listener - org.sonar.java.jacoco.JUnitListener - - - - ${project.build.directory}/surefire-reports - - - - org.apache.maven.plugins - maven-surefire-plugin - - - ${jacoco.agent.ut.arg} - - - listener - org.sonar.java.jacoco.JUnitListener - - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.codehaus.mojo - properties-maven-plugin - [0.0,) - - set-system-properties - - - - - - - - - org.jacoco - jacoco-maven-plugin - [0.0,) - - prepare-agent - pre-test - post-test - - - - - - - - - org.ops4j.pax.exam - maven-paxexam-plugin - [1.2.4,) - - generate-depends-file - - - - - false - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - [2.0,) - - check - - - - - - - - - org.opendaylight.yangtools - yang-maven-plugin - [0.5,) - - generate-sources - - - - - - - - - org.codehaus.groovy.maven - gmaven-plugin - 1.0 - - execute - - - - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - ${enforcer.version} - - enforce - - - - - - - - - - - - - - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.5.2 - - Max - Low - site - - - - maven-jxr-plugin - 2.3 - - true - true - - - - - org.codehaus.mojo - jdepend-maven-plugin - 2.0-beta-2 - - - - - - viewbuild - - true - - - ${project.version} - - - - jenkins - - - BUILDSUFFIX - - - - ${BUILDSUFFIX} - - - - repoBuild - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.8.1 - - - - aggregate - - site - - - attach-javadocs - - jar - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - package - - jar-no-fork - - - - - - - - diff --git a/simple-client/pom.xml b/simple-client/pom.xml index 567cdaae..b399646e 100644 --- a/simple-client/pom.xml +++ b/simple-client/pom.xml @@ -2,12 +2,15 @@ 4.0.0 org.opendaylight.openflowjava - openflow-protocol-parent - 0.7.0-SNAPSHOT + openflowjava-parent + 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 @@ -43,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 diff --git a/util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java b/util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java deleted file mode 100644 index 91435929..00000000 --- a/util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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.util; - -import org.junit.Assert; -import org.junit.Test; -import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; -import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; -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.multipart.request.multipart.request.body.MultipartRequestExperimenterCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; - -/** - * @author michal.polkorab - * - */ -public class ExperimenterSerializerKeyFactoryTest { - - /** - * Test ExperimenterSerializerKeyFactory key creation - */ - @Test - public void test() { - ExperimenterIdSerializerKey createdKey = ExperimenterSerializerKeyFactory - .createExperimenterMessageSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L); - ExperimenterIdSerializerKey comparationKey = - new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterInput.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - null, ExperimenterInput.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( - EncodeConstants.OF10_VERSION_ID, 43L); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - 43L, MeterBandExperimenterCase.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMeterBandSerializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - null, MeterBandExperimenterCase.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( - EncodeConstants.OF10_VERSION_ID, 44L); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - 44L, MultipartRequestExperimenterCase.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - null, MultipartRequestExperimenterCase.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestTFSerializerKey( - EncodeConstants.OF10_VERSION_ID, 45L); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - 45L, TableFeatureProperties.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - createdKey = ExperimenterSerializerKeyFactory.createMultipartRequestTFSerializerKey( - EncodeConstants.OF10_VERSION_ID, null); - comparationKey = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, - null, TableFeatureProperties.class); - Assert.assertEquals("Wrong key created", comparationKey, createdKey); - } -} \ No newline at end of file