From 34a07eabaeccb03d834359b99694f79b89e37583 Mon Sep 17 00:00:00 2001 From: Tomas Slusny Date: Mon, 26 Jun 2017 13:41:54 +0200 Subject: [PATCH] Merge OpenFlowJava repository into OpenFlowPlugin Merge OpenFlowJava into OpenFlowPlugin repository to decrease the logistics related to the OpenFlow southbound development. Merged OpenFlowJava HEAD is https://git.opendaylight.org/gerrit/gitweb?p=openflowjava.git;a=commit;h=76c83901c7a265e0d00c537d34f3f093c636129c Old OpenFlowJava repo will serve just for archival purposes. Detailed informations about this change and mailing lists thread: https://lists.opendaylight.org/pipermail/openflowplugin-dev/2017-June/007276.html Resolves: bug 8747 Change-Id: Ic5202e1b3781bb9b02b04683df32468a9f0d8571 Signed-off-by: Tomas Slusny --- openflowjava/artifacts/pom.xml | 99 + .../features/features-openflowjava/pom.xml | 36 + .../features/odl-openflowjava-all/pom.xml | 33 + .../odl-openflowjava-protocol/pom.xml | 157 ++ .../src/main/feature/feature.xml | 9 + openflowjava/features/pom.xml | 25 + openflowjava/openflow-protocol-api/pom.xml | 83 + .../api/connection/ConnectionAdapter.java | 103 + .../connection/ConnectionConfiguration.java | 58 + .../connection/ConnectionReadyListener.java | 21 + .../DeviceRequestFailedException.java | 35 + .../connection/ListeningStatusProvider.java | 24 + .../api/connection/OutboundQueue.java | 82 + .../connection/OutboundQueueException.java | 29 + .../api/connection/OutboundQueueHandler.java | 37 + .../OutboundQueueHandlerRegistration.java | 23 + .../connection/StatisticsConfiguration.java | 27 + .../connection/SwitchConnectionHandler.java | 32 + .../api/connection/ThreadConfiguration.java | 26 + .../api/connection/TlsConfiguration.java | 72 + .../api/connection/TlsConfigurationImpl.java | 101 + .../extensibility/AlienMessageListener.java | 19 + .../DeserializerExtensionProvider.java | 145 ++ .../extensibility/DeserializerRegistry.java | 53 + .../DeserializerRegistryInjector.java | 21 + .../extensibility/EnhancedMessageCodeKey.java | 62 + .../extensibility/EnhancedMessageTypeKey.java | 68 + .../api/extensibility/HeaderDeserializer.java | 26 + .../api/extensibility/HeaderSerializer.java | 26 + .../api/extensibility/OFDeserializer.java | 29 + .../extensibility/OFGeneralDeserializer.java | 17 + .../extensibility/OFGeneralSerializer.java | 17 + .../api/extensibility/OFSerializer.java | 29 + .../SerializerExtensionProvider.java | 129 ++ .../api/extensibility/SerializerRegistry.java | 56 + .../SerializerRegistryInjector.java | 22 + .../api/keys/ActionDeserializerKey.java | 65 + .../api/keys/ActionSerializerKey.java | 78 + .../ExperimenterActionDeserializerKey.java | 28 + .../keys/ExperimenterActionSerializerKey.java | 61 + .../api/keys/ExperimenterDeserializerKey.java | 17 + .../keys/ExperimenterIdDeserializerKey.java | 67 + ...perimenterIdMeterSubTypeSerializerKey.java | 62 + .../api/keys/ExperimenterIdSerializerKey.java | 67 + .../ExperimenterIdTypeDeserializerKey.java | 60 + .../keys/ExperimenterIdTypeSerializerKey.java | 60 + ...xperimenterInstructionDeserializerKey.java | 28 + .../ExperimenterInstructionSerializerKey.java | 27 + .../api/keys/ExperimenterSerializerKey.java | 17 + .../api/keys/InstructionDeserializerKey.java | 65 + .../api/keys/InstructionSerializerKey.java | 79 + .../api/keys/MatchEntryDeserializerKey.java | 79 + .../api/keys/MatchEntrySerializerKey.java | 97 + .../protocol/api/keys/MessageCodeKey.java | 81 + .../protocol/api/keys/MessageTypeKey.java | 68 + .../protocol/api/keys/TypeToClassKey.java | 57 + .../protocol/api/util/BinContent.java | 36 + .../protocol/api/util/EncodeConstants.java | 75 + .../protocol/api/util/OxmMatchConstants.java | 120 + .../src/main/yang/openflow-action.yang | 211 ++ .../yang/openflow-approved-extensions.yang | 32 + .../src/main/yang/openflow-augments.yang | 136 ++ .../src/main/yang/openflow-configuration.yang | 59 + .../main/yang/openflow-extensible-match.yang | 662 ++++++ .../src/main/yang/openflow-instruction.yang | 75 + .../src/main/yang/openflow-protocol.yang | 1438 ++++++++++++ .../src/main/yang/openflow-types.yang | 1933 +++++++++++++++++ .../src/main/yang/system-notifications.yang | 31 + .../connection/TlsConfigurationImplTest.java | 46 + .../EnhancedMessageCodeKeyTest.java | 74 + .../EnhancedMessageTypeKeyTest.java | 86 + .../api/extensibility/MessageCodeKeyTest.java | 78 + .../api/extensibility/MessageTypeKeyTest.java | 77 + .../api/keys/ActionDeserializerKeyTest.java | 70 + .../api/keys/ActionSerializerKeyTest.java | 84 + .../keys/InstructionDeserializerKeyTest.java | 70 + .../keys/InstructionSerializerKeyTest.java | 85 + .../protocol/api/keys/KeysTest.java | 84 + .../keys/MatchEntryDeserializerKeyTest.java | 83 + .../api/keys/MatchEntrySerializerKeyTest.java | 108 + .../protocol/api/keys/TypeToClassKeyTest.java | 38 + ...ExperimenterActionDeserializerKeyTest.java | 43 + .../ExperimenterActionSerializerKeyTest.java | 77 + .../ExperimenterIdDeserializerKeyTest.java | 68 + .../ExperimenterIdSerializerKeyTest.java | 65 + ...ExperimenterIdTypeDeserializerKeyTest.java | 72 + .../ExperimenterIdTypeSerializerKeyTest.java | 72 + ...imenterInstructionDeserializerKeyTest.java | 43 + ...erimenterInstructionSerializerKeyTest.java | 44 + .../protocol/api/util/BinContentTest.java | 63 + openflowjava/openflow-protocol-impl/pom.xml | 162 ++ .../impl/core/ChannelInitializerFactory.java | 96 + .../impl/core/ConnectionInitializer.java | 24 + .../impl/core/DelegatingInboundHandler.java | 68 + .../protocol/impl/core/IdleHandler.java | 53 + .../impl/core/OFDatagramPacketDecoder.java | 60 + .../impl/core/OFDatagramPacketEncoder.java | 56 + .../impl/core/OFDatagramPacketHandler.java | 104 + .../protocol/impl/core/OFDecoder.java | 73 + .../protocol/impl/core/OFEncoder.java | 69 + .../protocol/impl/core/OFFrameDecoder.java | 92 + .../protocol/impl/core/OFVersionDetector.java | 73 + .../protocol/impl/core/OnlineProvider.java | 24 + .../protocol/impl/core/PipelineHandlers.java | 63 + .../impl/core/ProtocolChannelInitializer.java | 115 + .../protocol/impl/core/ServerFacade.java | 24 + .../protocol/impl/core/ShutdownProvider.java | 25 + .../protocol/impl/core/SslContextFactory.java | 88 + .../protocol/impl/core/SslKeyStore.java | 66 + .../SwitchConnectionProviderFactoryImpl.java | 178 ++ .../core/SwitchConnectionProviderImpl.java | 324 +++ .../impl/core/TcpChannelInitializer.java | 138 ++ .../impl/core/TcpConnectionInitializer.java | 94 + .../protocol/impl/core/TcpHandler.java | 269 +++ .../impl/core/UdpChannelInitializer.java | 31 + .../protocol/impl/core/UdpConnectionMap.java | 62 + .../protocol/impl/core/UdpHandler.java | 195 ++ .../impl/core/VersionMessageUdpWrapper.java | 38 + .../impl/core/VersionMessageWrapper.java | 45 + .../connection/AbstractConnectionAdapter.java | 331 +++ .../AbstractConnectionAdapterStatistics.java | 77 + .../AbstractOutboundQueueManager.java | 373 ++++ .../core/connection/AbstractRpcListener.java | 90 + .../AbstractStackedOutboundQueue.java | 356 +++ .../core/connection/ChannelOutboundQueue.java | 278 +++ .../connection/ConnectionAdapterFactory.java | 29 + .../ConnectionAdapterFactoryImpl.java | 31 + .../connection/ConnectionAdapterImpl.java | 238 ++ .../core/connection/ConnectionFacade.java | 20 + .../impl/core/connection/MessageConsumer.java | 24 + .../connection/MessageListenerWrapper.java | 50 + .../core/connection/OutboundQueueEntry.java | 149 ++ .../OutboundQueueHandlerRegistrationImpl.java | 18 + .../core/connection/OutboundQueueManager.java | 124 ++ .../OutboundQueueManagerNoBarrier.java | 30 + .../ResponseExpectedRpcListener.java | 46 + .../impl/core/connection/RpcResponseKey.java | 82 + .../core/connection/SimpleRpcListener.java | 19 + .../core/connection/StackedOutboundQueue.java | 79 + .../StackedOutboundQueueNoBarrier.java | 123 ++ .../impl/core/connection/StackedSegment.java | 202 ++ .../connection/UdpMessageListenerWrapper.java | 45 + .../ActionDeserializerInitializer.java | 92 + ...itionalMessageDeserializerInitializer.java | 109 + .../DeserializationFactory.java | 88 + .../DeserializerRegistryImpl.java | 102 + .../InstructionDeserializerInitializer.java | 46 + .../MatchEntryDeserializerInitializer.java | 120 + .../MessageDeserializerInitializer.java | 120 + .../deserialization/MessageTypeCodeKey.java | 74 + .../TypeToClassMapInitializer.java | 163 ++ .../action/AbstractActionDeserializer.java | 37 + .../action/OF10EnqueueActionDeserializer.java | 49 + .../action/OF10OutputActionDeserializer.java | 45 + .../OF10SetDlDstActionDeserializer.java | 45 + .../OF10SetDlSrcActionDeserializer.java | 45 + .../OF10SetNwDstActionDeserializer.java | 43 + .../OF10SetNwSrcActionDeserializer.java | 43 + .../OF10SetNwTosActionDeserializer.java | 45 + .../OF10SetTpDstActionDeserializer.java | 46 + .../OF10SetTpSrcActionDeserializer.java | 45 + .../OF10SetVlanPcpActionDeserializer.java | 45 + .../OF10SetVlanVidActionDeserializer.java | 45 + .../OF10StripVlanActionDeserializer.java | 40 + .../OF13CopyTtlInActionDeserializer.java | 40 + .../OF13CopyTtlOutActionDeserializer.java | 40 + .../OF13DecMplsTtlActionDeserializer.java | 40 + .../OF13DecNwTtlActionDeserializer.java | 40 + .../action/OF13GroupActionDeserializer.java | 43 + .../action/OF13OutputActionDeserializer.java | 47 + .../action/OF13PopMplsActionDeserializer.java | 46 + .../action/OF13PopPbbActionDeserializer.java | 40 + .../action/OF13PopVlanActionDeserializer.java | 40 + .../OF13PushMplsActionDeserializer.java | 46 + .../action/OF13PushPbbActionDeserializer.java | 46 + .../OF13PushVlanActionDeserializer.java | 46 + .../OF13SetFieldActionDeserializer.java | 78 + .../OF13SetMplsTtlActionDeserializer.java | 45 + .../OF13SetNwTtlActionDeserializer.java | 45 + .../OF13SetQueueActionDeserializer.java | 43 + .../factories/BarrierInputMessageFactory.java | 31 + .../factories/BarrierReplyMessageFactory.java | 32 + .../factories/EchoReplyMessageFactory.java | 39 + .../factories/EchoRequestMessageFactory.java | 35 + .../factories/ErrorMessageFactory.java | 254 +++ .../factories/ExperimenterMessageFactory.java | 55 + .../FeaturesReplyMessageFactory.java | 59 + .../factories/FlowModInputMessageFactory.java | 83 + .../factories/FlowRemovedMessageFactory.java | 67 + .../GetAsyncReplyMessageFactory.java | 127 ++ .../GetAsyncRequestMessageFactory.java | 29 + .../GetConfigInputMessageFactory.java | 31 + .../GetConfigReplyMessageFactory.java | 35 + .../GetFeaturesInputMessageFactory.java | 25 + .../GetQueueConfigInputMessageFactory.java | 32 + .../GroupModInputMessageFactory.java | 73 + .../factories/HelloMessageFactory.java | 79 + .../MeterModInputMessageFactory.java | 108 + .../MultipartReplyMessageFactory.java | 890 ++++++++ .../MultipartRequestInputMessageFactory.java | 433 ++++ .../factories/OF10ErrorMessageFactory.java | 146 ++ .../OF10FeaturesReplyMessageFactory.java | 100 + .../OF10FeaturesRequestMessageFactory.java | 29 + .../OF10FlowModInputMessageFactory.java | 75 + .../OF10FlowRemovedMessageFactory.java | 67 + ...OF10GetQueueConfigInputMessageFactory.java | 31 + .../factories/OF10HelloMessageFactory.java | 35 + .../factories/OF10PacketInMessageFactory.java | 44 + .../OF10PacketOutInputMessageFactory.java | 60 + .../OF10PortModInputMessageFactory.java | 67 + .../OF10PortStatusMessageFactory.java | 50 + ...OF10QueueGetConfigReplyMessageFactory.java | 85 + .../OF10StatsReplyMessageFactory.java | 324 +++ .../OF10StatsRequestInputFactory.java | 170 ++ .../factories/PacketInMessageFactory.java | 64 + .../PacketOutInputMessageFactory.java | 53 + .../factories/PortModInputMessageFactory.java | 74 + .../factories/PortStatusMessageFactory.java | 91 + .../QueueGetConfigReplyMessageFactory.java | 107 + .../factories/RoleReplyMessageFactory.java | 42 + .../RoleRequestInputMessageFactory.java | 38 + .../SetAsyncInputMessageFactory.java | 123 ++ .../SetConfigInputMessageFactory.java | 34 + .../TableModInputMessageFactory.java | 41 + .../factories/VendorMessageFactory.java | 51 + ...AbstractActionInstructionDeserializer.java | 51 + .../ApplyActionsInstructionDeserializer.java | 50 + .../ClearActionsInstructionDeserializer.java | 44 + .../GoToTableInstructionDeserializer.java | 49 + .../MeterInstructionDeserializer.java | 48 + .../WriteActionsInstructionDeserializer.java | 50 + .../WriteMetadataInstructionDeserializer.java | 54 + .../AbstractOxmMatchEntryDeserializer.java | 64 + .../match/OxmArpOpDeserializer.java | 53 + .../match/OxmArpShaDeserializer.java | 57 + .../match/OxmArpSpaDeserializer.java | 57 + .../match/OxmArpThaDeserializer.java | 57 + .../match/OxmArpTpaDeserializer.java | 57 + .../match/OxmDeserializerHelper.java | 47 + .../match/OxmEthDstDeserializer.java | 58 + .../match/OxmEthSrcDeserializer.java | 58 + .../match/OxmEthTypeDeserializer.java | 54 + .../match/OxmIcmpv4CodeDeserializer.java | 54 + .../match/OxmIcmpv4TypeDeserializer.java | 53 + .../match/OxmIcmpv6CodeDeserializer.java | 53 + .../match/OxmIcmpv6TypeDeserializer.java | 53 + .../match/OxmInPhyPortDeserializer.java | 54 + .../match/OxmInPortDeserializer.java | 54 + .../match/OxmIpDscpDeserializer.java | 54 + .../match/OxmIpEcnDeserializer.java | 53 + .../match/OxmIpProtoDeserializer.java | 53 + .../match/OxmIpv4DstDeserializer.java | 57 + .../match/OxmIpv4SrcDeserializer.java | 57 + .../match/OxmIpv6DstDeserializer.java | 57 + .../match/OxmIpv6ExtHdrDeserializer.java | 73 + .../match/OxmIpv6FlabelDeserializer.java | 60 + .../match/OxmIpv6NdSllDeserializer.java | 53 + .../match/OxmIpv6NdTargetDeserializer.java | 53 + .../match/OxmIpv6NdTllDeserializer.java | 54 + .../match/OxmIpv6SrcDeserializer.java | 57 + .../match/OxmMetadataDeserializer.java | 60 + .../match/OxmMplsBosDeserializer.java | 57 + .../match/OxmMplsLabelDeserializer.java | 53 + .../match/OxmMplsTcDeserializer.java | 53 + .../match/OxmPbbIsidDeserializer.java | 59 + .../match/OxmSctpDstDeserializer.java | 54 + .../match/OxmSctpSrcDeserializer.java | 54 + .../match/OxmTcpDstDeserializer.java | 55 + .../match/OxmTcpSrcDeserializer.java | 54 + .../match/OxmTunnelIdDeserializer.java | 60 + .../match/OxmUdpDstDeserializer.java | 54 + .../match/OxmUdpSrcDeserializer.java | 54 + .../match/OxmVlanPcpDeserializer.java | 53 + .../match/OxmVlanVidDeserializer.java | 60 + ...OxmExperimenterMatchEntryDeserializer.java | 30 + .../match/ext/OnfOxmTcpFlagsDeserializer.java | 68 + .../serialization/ActionsInitializer.java | 120 + .../AdditionalMessageFactoryInitializer.java | 105 + .../InstructionsInitializer.java | 52 + .../MatchEntriesInitializer.java | 162 ++ .../MessageFactoryInitializer.java | 115 + .../serialization/SerializationFactory.java | 45 + .../serialization/SerializerRegistryImpl.java | 105 + .../action/AbstractActionSerializer.java | 47 + .../action/OF10EnqueueActionSerializer.java | 43 + .../action/OF10OutputActionSerializer.java | 42 + .../action/OF10SetDlDstActionSerializer.java | 41 + .../action/OF10SetDlSrcActionSerializer.java | 41 + .../action/OF10SetNwDstActionSerializer.java | 39 + .../action/OF10SetNwSrcActionSerializer.java | 39 + .../action/OF10SetNwTosActionSerializer.java | 40 + .../action/OF10SetTpDstActionSerializer.java | 41 + .../action/OF10SetTpSrcActionSerializer.java | 41 + .../OF10SetVlanPcpActionSerializer.java | 40 + .../OF10SetVlanVidActionSerializer.java | 40 + .../action/OF10StripVlanActionSerializer.java | 39 + .../action/OF13CopyTtlInActionSerializer.java | 38 + .../OF13CopyTtlOutActionSerializer.java | 38 + .../OF13DecMplsTtlActionSerializer.java | 38 + .../action/OF13DecNwTtlActionSerializer.java | 39 + .../action/OF13GroupActionSerializer.java | 39 + .../action/OF13OutputActionSerializer.java | 42 + .../action/OF13PopMplsActionSerializer.java | 41 + .../action/OF13PopPbbActionSerializer.java | 38 + .../action/OF13PopVlanActionSerializer.java | 38 + .../action/OF13PushMplsActionSerializer.java | 41 + .../action/OF13PushPbbActionSerializer.java | 41 + .../action/OF13PushVlanActionSerializer.java | 42 + .../action/OF13SetFieldActionSerializer.java | 71 + .../OF13SetMplsTtlActionSerializer.java | 40 + .../action/OF13SetNwTtlActionSerializer.java | 40 + .../action/OF13SetQueueActionSerializer.java | 40 + .../factories/BarrierInputMessageFactory.java | 33 + .../factories/BarrierReplyMessageFactory.java | 30 + .../factories/EchoInputMessageFactory.java | 38 + .../factories/EchoOutputMessageFactory.java | 36 + .../EchoReplyInputMessageFactory.java | 38 + .../factories/EchoRequestMessageFactory.java | 35 + .../factories/ErrorMessageFactory.java | 37 + .../ExperimenterInputMessageFactory.java | 53 + .../factories/ExperimenterMessageFactory.java | 37 + .../factories/FlowModInputMessageFactory.java | 75 + .../factories/FlowRemovedMessageFactory.java | 54 + .../GetAsyncReplyMessageFactory.java | 107 + .../GetAsyncRequestMessageFactory.java | 31 + .../GetConfigInputMessageFactory.java | 33 + .../GetConfigReplyMessageFactory.java | 32 + .../GetFeaturesInputMessageFactory.java | 33 + .../factories/GetFeaturesOutputFactory.java | 62 + .../GetQueueConfigInputMessageFactory.java | 36 + .../GroupModInputMessageFactory.java | 68 + .../factories/HelloInputMessageFactory.java | 66 + .../factories/HelloMessageFactory.java | 29 + .../MeterModInputMessageFactory.java | 118 + .../MultipartReplyMessageFactory.java | 790 +++++++ .../MultipartRequestInputFactory.java | 414 ++++ .../OF10BarrierInputMessageFactory.java | 31 + .../OF10BarrierReplyMessageFactory.java | 29 + .../OF10FeaturesReplyMessageFactory.java | 142 ++ .../OF10FlowModInputMessageFactory.java | 67 + .../OF10FlowRemovedMessageFactory.java | 58 + .../OF10HelloInputMessageFactory.java | 31 + .../factories/OF10PacketInMessageFactory.java | 40 + .../OF10PacketOutInputMessageFactory.java | 54 + .../OF10PortModInputMessageFactory.java | 72 + .../OF10PortStatusMessageFactory.java | 110 + ...OF10QueueGetConfigInputMessageFactory.java | 35 + ...OF10QueueGetConfigReplyMessageFactory.java | 63 + .../OF10StatsReplyMessageFactory.java | 284 +++ .../OF10StatsRequestInputFactory.java | 150 ++ .../factories/PacketInMessageFactory.java | 54 + .../PacketOutInputMessageFactory.java | 58 + .../factories/PortModInputMessageFactory.java | 84 + .../factories/PortStatusMessageFactory.java | 113 + .../QueueGetConfigReplyMessageFactory.java | 88 + .../factories/RoleReplyMessageFactory.java | 33 + .../RoleRequestInputMessageFactory.java | 38 + .../SetAsyncInputMessageFactory.java | 110 + .../factories/SetConfigMessageFactory.java | 36 + .../TableModInputMessageFactory.java | 45 + .../factories/VendorInputMessageFactory.java | 46 + .../AbstractActionInstructionSerializer.java | 53 + .../AbstractInstructionSerializer.java | 36 + .../ApplyActionsInstructionSerializer.java | 45 + .../ClearActionsInstructionSerializer.java | 34 + .../GoToTableInstructionSerializer.java | 37 + .../MeterInstructionSerializer.java | 36 + .../WriteActionsInstructionSerializer.java | 45 + .../WriteMetadataInstructionSerializer.java | 40 + .../AbstractOxmIpv4AddressSerializer.java | 35 + .../AbstractOxmIpv6AddressSerializer.java | 28 + .../AbstractOxmMacAddressSerializer.java | 23 + .../AbstractOxmMatchEntrySerializer.java | 69 + .../match/OxmArpOpSerializer.java | 44 + .../match/OxmArpShaSerializer.java | 47 + .../match/OxmArpSpaSerializer.java | 47 + .../match/OxmArpThaSerializer.java | 47 + .../match/OxmArpTpaSerializer.java | 47 + .../match/OxmEthDstSerializer.java | 47 + .../match/OxmEthSrcSerializer.java | 47 + .../match/OxmEthTypeSerializer.java | 44 + .../match/OxmIcmpv4CodeSerializer.java | 44 + .../match/OxmIcmpv4TypeSerializer.java | 44 + .../match/OxmIcmpv6CodeSerializer.java | 44 + .../match/OxmIcmpv6TypeSerializer.java | 44 + .../match/OxmInPhyPortSerializer.java | 44 + .../match/OxmInPortSerializer.java | 44 + .../match/OxmIpDscpSerializer.java | 44 + .../match/OxmIpEcnSerializer.java | 44 + .../match/OxmIpProtoSerializer.java | 44 + .../match/OxmIpv4DstSerializer.java | 47 + .../match/OxmIpv4SrcSerializer.java | 47 + .../match/OxmIpv6DstSerializer.java | 48 + .../match/OxmIpv6ExtHdrSerializer.java | 60 + .../match/OxmIpv6FlabelSerializer.java | 47 + .../match/OxmIpv6NdSllSerializer.java | 44 + .../match/OxmIpv6NdTargetSerializer.java | 44 + .../match/OxmIpv6NdTllSerializer.java | 44 + .../match/OxmIpv6SrcSerializer.java | 48 + .../match/OxmMetadataSerializer.java | 48 + .../match/OxmMplsBosSerializer.java | 44 + .../match/OxmMplsLabelSerializer.java | 44 + .../match/OxmMplsTcSerializer.java | 44 + .../match/OxmPbbIsidSerializer.java | 47 + .../match/OxmSctpDstSerializer.java | 44 + .../match/OxmSctpSrcSerializer.java | 44 + .../match/OxmTcpDstSerializer.java | 44 + .../match/OxmTcpSrcSerializer.java | 44 + .../match/OxmTunnelIdSerializer.java | 48 + .../match/OxmUdpDstSerializer.java | 44 + .../match/OxmUdpSrcSerializer.java | 45 + .../match/OxmVlanPcpSerializer.java | 45 + .../match/OxmVlanVidSerializer.java | 54 + ...ctOxmExperimenterMatchEntrySerializer.java | 58 + .../match/ext/OnfOxmTcpFlagsSerializer.java | 65 + .../impl/util/AbstractCodeKeyMaker.java | 32 + .../impl/util/AbstractTypeKeyMaker.java | 35 + .../protocol/impl/util/ActionConstants.java | 107 + .../ActionDeserializerRegistryHelper.java | 40 + .../util/ActionSerializerRegistryHelper.java | 42 + .../protocol/impl/util/CodeKeyMaker.java | 26 + .../impl/util/CodeKeyMakerFactory.java | 93 + .../util/CommonMessageRegistryHelper.java | 42 + .../impl/util/InstructionConstants.java | 48 + ...InstructionDeserializerRegistryHelper.java | 40 + .../InstructionSerializerRegistryHelper.java | 42 + .../protocol/impl/util/ListDeserializer.java | 106 + .../protocol/impl/util/ListSerializer.java | 64 + .../protocol/impl/util/MatchDeserializer.java | 69 + .../MatchEntryDeserializerRegistryHelper.java | 55 + .../MatchEntrySerializerRegistryHelper.java | 63 + .../impl/util/OF10MatchDeserializer.java | 95 + .../impl/util/OF10MatchSerializer.java | 72 + .../impl/util/OF13MatchSerializer.java | 98 + .../protocol/impl/util/OpenflowUtils.java | 80 + .../SimpleDeserializerRegistryHelper.java | 47 + .../protocol/impl/util/TypeKeyMaker.java | 26 + .../impl/util/TypeKeyMakerFactory.java | 95 + .../impl/util/TypeToClassInitHelper.java | 41 + .../impl/util/VersionAssignableFactory.java | 36 + .../openflowjava/statistics/Counter.java | 84 + .../statistics/CounterEventTypes.java | 57 + .../statistics/StatisticsCounters.java | 248 +++ .../rev140328/StatisticsCollectionModule.java | 118 + .../StatisticsCollectionModuleFactory.java | 13 + .../SwitchConnectionProviderModule.java | 76 + ...SwitchConnectionProviderModuleFactory.java | 36 + .../src/main/resources/exemplary-cacert.pem | 70 + .../src/main/resources/exemplary-ctlKeystore | Bin 0 -> 2254 bytes .../main/resources/exemplary-ctlTrustStore | Bin 0 -> 957 bytes .../main/resources/exemplary-switch-cert.pem | 70 + .../resources/exemplary-switch-privkey.pem | 27 + .../src/main/resources/log4j.xml | 28 + .../blueprint/openflow-protocol-impl.xml | 9 + ...nflow-switch-connection-provider-impl.yang | 192 ++ .../core/DelegatingInboundHandlerTest.java | 72 + .../protocol/impl/core/DummyDecoder.java | 36 + .../protocol/impl/core/IdleHandlerTest.java | 110 + .../core/OFDatagramPacketDecoderTest.java | 53 + .../core/OFDatagramPacketEncoderTest.java | 88 + .../core/OFDatagramPacketHandlerTest.java | 70 + .../impl/core/OFDecoderStatisticsTest.java | 141 ++ .../protocol/impl/core/OFDecoderTest.java | 113 + .../impl/core/OFEncoderStatisticsTest.java | 142 ++ .../protocol/impl/core/OFEncoderTest.java | 115 + .../impl/core/OFFrameDecoderTest.java | 167 ++ .../impl/core/OFVersionDetectorTest.java | 73 + ...blishingChannelInitializerFactoryTest.java | 65 + .../PublishingChannelInitializerTest.java | 171 ++ .../impl/core/SslContextFactoryTest.java | 56 + .../protocol/impl/core/SslKeyStoreTest.java | 55 + .../protocol/impl/core/TcpHandlerTest.java | 265 +++ .../impl/core/UdpConnectionMapTest.java | 75 + .../core/VersionMessageUdpWrapperTest.java | 45 + .../ChannelOutboundQueue02Test.java | 160 ++ .../connection/ChannelOutboundQueueTest.java | 55 + .../ConnectionAdapterFactoryImplTest.java | 43 + .../ConnectionAdapterImp02lTest.java | 206 ++ .../ConnectionAdapterImpl02Test.java | 206 ++ .../ConnectionAdapterImplStatisticsTest.java | 239 ++ .../connection/ConnectionAdapterImplTest.java | 207 ++ .../ConnectionConfigurationImpl.java | 104 + .../MessageListenerWrapperTest.java | 36 + .../connection/OutboundQueueEntryTest.java | 147 ++ .../ResponseExpectedRpcListenerTest.java | 124 ++ .../core/connection/RpcResponseKeyTest.java | 61 + .../connection/SimpleRpcListenerTest.java | 102 + .../SwitchConnectionProviderImpl02Test.java | 257 +++ .../SwitchConnectionProviderImplTest.java | 182 ++ .../impl/core/connection/UdpHandlerTest.java | 151 ++ .../UdpMessageListenerWrapperTest.java | 53 + .../DeserializationFactoryTest.java | 56 + .../DeserializerRegistryImplTest.java | 86 + .../MessageTypeCodeKeyTest.java | 62 + .../TypeToClassMapInitializerTest.java | 154 ++ .../BarrierInputMessageFactoryTest.java | 53 + .../BarrierReplyMessageFactoryTest.java | 54 + .../EchoReplyMessageFactoryTest.java | 72 + .../EchoRequestMessageFactoryTest.java | 74 + .../factories/ErrorMessageFactoryTest.java | 399 ++++ .../ExperimenterMessageFactoryTest.java | 62 + .../FeaturesReplyMessageFactoryTest.java | 75 + .../FlowModInputMessageFactoryTest.java | 163 ++ .../FlowRemovedMessageFactoryTest.java | 67 + .../GetAsyncReplyMessageFactoryTest.java | 130 ++ .../GetAsyncRequestMessageFactoryTest.java | 43 + .../GetConfigInputMessageFactoryTest.java | 48 + .../GetConfigReplyMessageFactoryTest.java | 63 + .../GetFeaturesInputFactoryTest.java | 42 + ...GetQueueConfigInputMessageFactoryTest.java | 46 + .../GroupModInputMessageFactoryTest.java | 59 + .../factories/HelloMessageFactoryTest.java | 123 ++ .../MeterModInputMessageFactoryTest.java | 85 + .../MultipartReplyMessageFactoryTest.java | 985 +++++++++ ...questAggregateInputMessageFactoryTest.java | 71 + ...artRequestDescInputMessageFactoryTest.java | 62 + ...artRequestFlowInputMessageFactoryTest.java | 71 + ...rtRequestGroupInputMessageFactoryTest.java | 63 + ...estMeterConfigInputMessageFactoryTest.java | 63 + ...rtRequestMeterInputMessageFactoryTest.java | 61 + ...questPortStatsInputMessageFactoryTest.java | 61 + ...rtRequestQueueInputMessageFactoryTest.java | 62 + ...tTableFeaturesInputMessageFactoryTest.java | 184 ++ ...rtRequestTableInputMessageFactoryTest.java | 49 + .../OF10ErrorMessageFactoryTest.java | 222 ++ .../OF10FeaturesReplyMessageFactoryTest.java | 131 ++ ...OF10FeaturesRequestMessageFactoryTest.java | 42 + .../OF10FlowModInputMessageFactoryTest.java | 113 + .../OF10FlowRemovedMessageFactoryTest.java | 64 + ...GetQueueConfigInputMessageFactoryTest.java | 45 + .../OF10HelloMessageFactoryTest.java | 73 + .../OF10PacketInMessageFactoryTest.java | 69 + .../OF10PacketOutInputMessageFactoryTest.java | 77 + .../OF10PortModInputMessageFactoryTest.java | 57 + .../OF10PortStatusMessageFactoryTest.java | 76 + ...QueueGetConfigReplyMessageFactoryTest.java | 79 + .../OF10StatsReplyMessageFactoryTest.java | 314 +++ ...StatsRequestInputAggregateFactoryTest.java | 84 + .../OF10StatsRequestInputDescFactoryTest.java | 59 + .../OF10StatsRequestInputFlowFactoryTest.java | 83 + ...StatsRequestInputPortStatsFactoryTest.java | 59 + ...OF10StatsRequestInputQueueFactoryTest.java | 60 + ...OF10StatsRequestInputTableFactoryTest.java | 59 + .../factories/PacketInMessageFactoryTest.java | 64 + .../PacketOutInputMessageFactoryTest.java | 88 + .../PortModInputMessageFactoryTest.java | 58 + .../PortStatusMessageFactoryTest.java | 121 ++ ...GetConfigReplyMessageFactoryMultiTest.java | 114 + ...QueueGetConfigReplyMessageFactoryTest.java | 88 + .../RoleReplyMessageFactoryTest.java | 56 + .../RoleRequestInputMessageFactoryTest.java | 51 + .../SetAsyncInputMessageFactoryTest.java | 129 ++ .../SetConfigInputMessageFactoryTest.java | 61 + .../TableModInputMessageFactoryTest.java | 51 + .../factories/VendorMessageFactoryTest.java | 47 + .../MultipartReplyExperimenterTest.java | 57 + .../multipart/MultipartReplyFlowTest.java | 136 ++ .../MultipartReplyGroupFeaturesTest.java | 104 + .../MultipartReplyMeterFeaturesTest.java | 80 + .../multipart/MultipartReplyPortDescTest.java | 122 ++ .../MultipartReplyTableFeaturesTest.java | 187 ++ .../OF10StatsReplyExperimenterTest.java | 56 + .../AbstractInstructionDeserializerTest.java | 60 + .../match/OxmIpv6ExtHdrDeserializerTest.java | 49 + .../match/OxmIpv6FlabelDeserializerTest.java | 66 + .../match/OxmMetadataDeserializerTest.java | 45 + .../match/OxmMplsBosDeserializerTest.java | 44 + .../match/OxmPbbIsidDeserializerTest.java | 44 + .../match/OxmVlanVidDeserializerTest.java | 46 + .../SerializationFactoryTest.java | 60 + .../SerializerRegistryImplTest.java | 61 + .../OF13SetFieldActionSerializerTest.java | 97 + .../BarrierInputMessageFactoryTest.java | 62 + .../BarrierReplyMessageFactoryTest.java | 48 + .../EchoInputMessageFactoryTest.java | 94 + .../EchoOutputMessageFactoryTest.java | 54 + .../EchoReplyInputMessageFactoryTest.java | 95 + .../EchoRequestMessageFactoryTest.java | 56 + .../factories/ErrorMessageFactoryTest.java | 59 + .../ExperimenterInputMessageFactoryTest.java | 140 ++ .../FlowModInputMessageFactoryTest.java | 235 ++ .../FlowRemovedMessageFactoryTest.java | 139 ++ .../GetAsyncReplyMessageFactoryTest.java | 145 ++ .../GetConfigInputMessageFactoryTest.java | 78 + .../GetConfigReplyMessageFactoryTest.java | 55 + .../GetFeaturesInputMessageFactoryTest.java | 77 + .../GetFeaturesOutputFactoryTest.java | 76 + ...GetQueueConfigInputMessageFactoryTest.java | 65 + .../GetaAsyncRequestMessageFactoryTest.java | 61 + .../GroupModInputMessageFactoryTest.java | 143 ++ .../HelloInputMessageFactoryTest.java | 190 ++ .../factories/HelloMessageFactoryTest.java | 49 + .../MeterModInputMessageFactoryTest.java | 160 ++ .../MultipartReplyMessageFactoryTest.java | 1496 +++++++++++++ .../MultipartRequestInputFactoryTest.java | 454 ++++ .../OF10BarrierInputMessageFactoryTest.java | 61 + .../OF10BarrierReplyMessageFactoryTest.java | 48 + .../OF10FeaturesReplyMessageFactoryTest.java | 188 ++ .../OF10FlowModInputMessageFactoryTest.java | 158 ++ .../OF10FlowRemovedMessageFactoryTest.java | 114 + .../OF10HelloInputMessageFactoryTest.java | 61 + .../OF10PacketInMessageFactoryTest.java | 65 + .../OF10PacketOutInputMessageFactoryTest.java | 125 ++ .../OF10PortModInputMessageFactoryTest.java | 81 + .../OF10PortStatusMessageFactoryTest.java | 129 ++ ...QueueGetConfigInputMessageFactoryTest.java | 65 + ...QueueGetConfigReplyMessageFactoryTest.java | 98 + .../OF10StatsReplyMessageFactoryTest.java | 413 ++++ .../OF10StatsRequestInputFactoryTest.java | 303 +++ .../factories/PacketInMessageFactoryTest.java | 129 ++ .../PacketOutInputMessageFactoryTest.java | 126 ++ .../PortModInputMessageFactoryTest.java | 129 ++ .../PortStatusMessageFactoryTest.java | 135 ++ ...QueueGetConfigReplyMessageFactoryTest.java | 123 ++ .../RoleReplyMessageFactoryTest.java | 61 + .../RoleRequestInputMessageFactoryTest.java | 74 + .../SetAsyncInputMessageFactoryTest.java | 161 ++ .../SetConfigMessageFactoryTest.java | 89 + .../TableModInputMessageFactoryTest.java | 69 + .../VendorInputMessageFactoryTest.java | 64 + .../MultipartRequestExperimenterTest.java | 78 + .../MultipartRequestGroupDescTest.java | 77 + .../MultipartRequestGroupFeaturesTest.java | 77 + .../MultipartRequestMeterFeaturesTest.java | 77 + .../MultipartRequestPortDescTest.java | 77 + .../MultipartRequestTableFeaturesTest.java | 467 ++++ .../multipart/MultipartRequestTableTest.java | 77 + .../OF10StatsRequestAggregateTest.java | 102 + .../OF10StatsRequestExperimenterTest.java | 78 + .../match/OxmArpOpSerializerTest.java | 111 + .../match/OxmArpShaSerializerTest.java | 157 ++ .../match/OxmArpSpaSerializerTest.java | 157 ++ .../match/OxmArpThaSerializerTest.java | 157 ++ .../match/OxmArpTpaSerializerTest.java | 157 ++ .../match/OxmEthDstSerializerTest.java | 157 ++ .../match/OxmEthSrcSerializerTest.java | 157 ++ .../match/OxmEthTypeSerializerTest.java | 112 + .../match/OxmIcmpv4CodeSerializerTest.java | 111 + .../match/OxmIcmpv4TypeSerializerTest.java | 111 + .../match/OxmIcmpv6CodeSerializerTest.java | 111 + .../match/OxmIcmpv6TypeSerializerTest.java | 111 + .../match/OxmIpDscpSerializerTest.java | 112 + .../match/OxmIpProtoSerializerTest.java | 111 + .../match/OxmIpv4DstSerializerTest.java | 157 ++ .../match/OxmIpv4SrcSerializerTest.java | 157 ++ .../match/OxmIpv6ExtHdrSerializerTest.java | 154 ++ .../match/OxmIpv6NdSllSerializerTest.java | 115 + .../match/OxmIpv6NdTllSerializerTest.java | 115 + .../match/OxmIpv6SrcSerializerTest.java | 112 + .../match/OxmMetadataSerializerTest.java | 156 ++ .../match/OxmMplsBosSerializerTest.java | 111 + .../match/OxmMplsLabelSerializerTest.java | 111 + .../match/OxmMplsTcSerializerTest.java | 111 + .../match/OxmPbbIsidSerializerTest.java | 151 ++ .../match/OxmSctpDstSerializerTest.java | 112 + .../match/OxmSctpSrcSerializerTest.java | 112 + .../match/OxmTcpDstSerializerTest.java | 112 + .../match/OxmTcpSrcSerializerTest.java | 112 + .../match/OxmTunnelIdSerializerTest.java | 156 ++ .../match/OxmUdpDstSerializerTest.java | 112 + .../match/OxmUdpSrcSerializerTest.java | 112 + .../match/OxmVlanPcpSerializerTest.java | 111 + .../match/OxmVlanVidSerializerTest.java | 152 ++ .../impl/util/ActionsDeserializerTest.java | 166 ++ .../protocol/impl/util/BufferHelper.java | 147 ++ .../impl/util/CodeKeyMakerFactoryTest.java | 135 ++ .../util/DefaultDeserializerFactoryTest.java | 50 + .../util/InstructionsDeserializerTest.java | 110 + .../impl/util/ListDeserializerTest.java | 58 + .../impl/util/ListSerializerTest.java | 45 + .../impl/util/MatchDeserializerTest.java | 531 +++++ .../util/OF10ActionsDeserializerTest.java | 125 ++ .../impl/util/OF10ActionsSerializerTest.java | 222 ++ .../impl/util/OF10MatchDeserializerTest.java | 101 + .../impl/util/OF10MatchSerializerTest.java | 142 ++ .../impl/util/OF13ActionsSerializerTest.java | 293 +++ .../util/OF13InstructionsSerializerTest.java | 194 ++ .../impl/util/OF13MatchSerializer02Test.java | 866 ++++++++ .../impl/util/OF13MatchSerializerTest.java | 400 ++++ .../protocol/impl/util/OpenflowUtilsTest.java | 68 + .../impl/util/TypeKeyMakerFactoryTest.java | 176 ++ .../statistics/StatisticsCountersTest.java | 137 ++ .../src/test/resources/key.bin | Bin 0 -> 2063 bytes .../src/test/resources/selfSignedController | Bin 0 -> 1351 bytes .../src/test/resources/selfSignedSwitch | Bin 0 -> 1348 bytes openflowjava/openflow-protocol-it/pom.xml | 46 + .../it/integration/IntegrationTest.java | 279 +++ .../protocol/it/integration/MockPlugin.java | 244 +++ .../src/test/resources/log4j.xml | 24 + openflowjava/openflow-protocol-spi/pom.xml | 95 + .../connection/SwitchConnectionProvider.java | 55 + .../SwitchConnectionProviderFactory.java | 25 + .../spi/statistics/StatisticsHandler.java | 28 + .../openflow-switch-connection-config.yang | 116 + .../openflow-switch-connection-provider.yang | 29 + .../openflowjava-blueprint-config/pom.xml | 68 + .../default-openflow-connection-config.xml | 17 + .../legacy-openflow-connection-config.xml | 17 + .../opendaylight/blueprint/openflowjava.xml | 34 + openflowjava/openflowjava-config/pom.xml | 56 + .../main/resources/45-openflowjava-stats.xml | 33 + .../openflowjava/tools/ConfigurationType.java | 162 ++ .../openflowjava/tools/Configurations.java | 58 + .../ConnectionToolConfigurationService.java | 39 + ...onnectionToolConfigurationServiceImpl.java | 126 ++ .../src/main/resources/configuration.xml | 23 + .../src/main/resources/configuration.xsd | 32 + openflowjava/openflowjava-util/pom.xml | 28 + .../openflowjava/util/ByteBufUtils.java | 388 ++++ .../ExperimenterDeserializerKeyFactory.java | 110 + .../ExperimenterSerializerKeyFactory.java | 71 + .../openflowjava/util/ByteBufUtilsTest.java | 469 ++++ ...xperimenterDeserializerKeyFactoryTest.java | 121 ++ .../ExperimenterSerializerKeyFactoryTest.java | 104 + openflowjava/parent/pom.xml | 392 ++++ openflowjava/pom.xml | 27 + openflowjava/simple-client/pom.xml | 55 + .../protocol/impl/clients/CallableClient.java | 119 + .../protocol/impl/clients/ClientEvent.java | 23 + .../impl/clients/ClientSslContextFactory.java | 72 + .../impl/clients/ClientSslKeyStore.java | 52 + .../impl/clients/ClientSslTrustStore.java | 52 + .../protocol/impl/clients/EventType.java | 41 + .../impl/clients/ListeningSimpleClient.java | 130 ++ .../protocol/impl/clients/OFClient.java | 40 + .../protocol/impl/clients/Scenario.java | 80 + .../impl/clients/ScenarioFactory.java | 108 + .../impl/clients/ScenarioHandler.java | 147 ++ .../impl/clients/ScenarioService.java | 33 + .../impl/clients/ScenarioServiceImpl.java | 81 + .../protocol/impl/clients/Scenarios.java | 51 + .../protocol/impl/clients/SendEvent.java | 59 + .../protocol/impl/clients/SimpleClient.java | 149 ++ .../impl/clients/SimpleClientFramer.java | 66 + .../impl/clients/SimpleClientHandler.java | 75 + .../impl/clients/SimpleClientInitializer.java | 63 + .../protocol/impl/clients/SleepEvent.java | 43 + .../protocol/impl/clients/Step.java | 108 + .../impl/clients/UdpSimpleClient.java | 149 ++ .../impl/clients/UdpSimpleClientFramer.java | 67 + .../clients/UdpSimpleClientInitializer.java | 50 + .../impl/clients/WaitForMessageEvent.java | 60 + .../src/main/resources/scenario.xml | 41 + .../src/main/resources/scenario.xsd | 40 + .../src/main/resources/selfSignedController | Bin 0 -> 1351 bytes .../src/main/resources/selfSignedSwitch | Bin 0 -> 1348 bytes 746 files changed, 69312 insertions(+) create mode 100644 openflowjava/artifacts/pom.xml create mode 100644 openflowjava/features/features-openflowjava/pom.xml create mode 100644 openflowjava/features/odl-openflowjava-all/pom.xml create mode 100644 openflowjava/features/odl-openflowjava-protocol/pom.xml create mode 100644 openflowjava/features/odl-openflowjava-protocol/src/main/feature/feature.xml create mode 100644 openflowjava/features/pom.xml create mode 100644 openflowjava/openflow-protocol-api/pom.xml create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionReadyListener.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/DeviceRequestFailedException.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ListeningStatusProvider.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueException.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandler.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandlerRegistration.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/StatisticsConfiguration.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ThreadConfiguration.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralDeserializer.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralSerializer.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java create mode 100755 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistryInjector.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java create mode 100755 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageTypeKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java create mode 100644 openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-action.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang create mode 100755 openflowjava/openflow-protocol-api/src/main/yang/openflow-augments.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-configuration.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-instruction.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/openflow-protocol.yang create mode 100755 openflowjava/openflow-protocol-api/src/main/yang/openflow-types.yang create mode 100644 openflowjava/openflow-protocol-api/src/main/yang/system-notifications.yang create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageCodeKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageTypeKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionDeserializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionSerializerKeyTest.java create mode 100644 openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/util/BinContentTest.java create mode 100644 openflowjava/openflow-protocol-impl/pom.xml create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ShutdownProvider.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java create mode 100755 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMap.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractRpcListener.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionFacade.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageConsumer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueHandlerRegistrationImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListener.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListener.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/ActionDeserializerInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/InstructionDeserializerInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKey.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/AbstractActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10EnqueueActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10OutputActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwTosActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpDstActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpSrcActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanPcpActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanVidActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10StripVlanActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlInActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlOutActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecMplsTtlActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecNwTtlActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13GroupActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13OutputActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopMplsActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopPbbActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopVlanActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushMplsActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushPbbActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushVlanActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetFieldActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetMplsTtlActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetNwTtlActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetQueueActionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractActionInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ApplyActionsInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ClearActionsInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/GoToTableInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/MeterInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteActionsInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteMetadataInstructionDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/AbstractOxmMatchEntryDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpOpDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpShaDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpThaDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthDstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthSrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthTypeDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4CodeDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4TypeDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6CodeDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6TypeDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPhyPortDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPortDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpEcnDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpProtoDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdSllDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTllDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsLabelDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsTcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTunnelIdDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanPcpDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/ActionsInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/InstructionsInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/AbstractActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10EnqueueActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10OutputActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwTosActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpDstActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpSrcActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanPcpActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanVidActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10StripVlanActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlInActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlOutActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecMplsTtlActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecNwTtlActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13GroupActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13OutputActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopMplsActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopPbbActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopVlanActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushMplsActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushPbbActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushVlanActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetMplsTtlActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetNwTtlActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetQueueActionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncRequestMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactory.java create mode 100755 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractActionInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ApplyActionsInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ClearActionsInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/GoToTableInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/MeterInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteActionsInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteMetadataInstructionSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv6AddressSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMatchEntrySerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPhyPortSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPortSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpEcnSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6DstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6FlabelSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTargetSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractCodeKeyMaker.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractTypeKeyMaker.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionConstants.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionDeserializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionSerializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMaker.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionConstants.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionDeserializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionSerializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtils.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMaker.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/Counter.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/CounterEventTypes.java create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java create mode 100644 openflowjava/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 create mode 100644 openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModuleFactory.java create mode 100644 openflowjava/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 create mode 100644 openflowjava/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 create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/exemplary-cacert.pem create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/exemplary-ctlKeystore create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/exemplary-ctlTrustStore create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/exemplary-switch-cert.pem create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/exemplary-switch-privkey.pem create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/log4j.xml create mode 100644 openflowjava/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml create mode 100644 openflowjava/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandlerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandlerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoderTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoderTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandlerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderStatisticsTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderStatisticsTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoderTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStoreTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMapTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapperTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueueTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapperTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListenerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListenerTest.java create mode 100755 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapperTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImplTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKeyTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryMultiTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyFlowTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyGroupFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyMeterFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyTableFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractInstructionDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImplTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetaAsyncRequestMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupDescTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestMeterFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestPortDescTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableFeaturesTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13InstructionsSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtilsTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactoryTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java create mode 100644 openflowjava/openflow-protocol-impl/src/test/resources/key.bin create mode 100644 openflowjava/openflow-protocol-impl/src/test/resources/selfSignedController create mode 100644 openflowjava/openflow-protocol-impl/src/test/resources/selfSignedSwitch create mode 100644 openflowjava/openflow-protocol-it/pom.xml create mode 100644 openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java create mode 100644 openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/MockPlugin.java create mode 100644 openflowjava/openflow-protocol-it/src/test/resources/log4j.xml create mode 100644 openflowjava/openflow-protocol-spi/pom.xml create mode 100644 openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java create mode 100644 openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java create mode 100644 openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/statistics/StatisticsHandler.java create mode 100644 openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang create mode 100644 openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang create mode 100644 openflowjava/openflowjava-blueprint-config/pom.xml create mode 100644 openflowjava/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml create mode 100644 openflowjava/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml create mode 100644 openflowjava/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml create mode 100644 openflowjava/openflowjava-config/pom.xml create mode 100644 openflowjava/openflowjava-config/src/main/resources/45-openflowjava-stats.xml create mode 100644 openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java create mode 100644 openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java create mode 100644 openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java create mode 100644 openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java create mode 100644 openflowjava/openflowjava-tools/src/main/resources/configuration.xml create mode 100644 openflowjava/openflowjava-tools/src/main/resources/configuration.xsd create mode 100644 openflowjava/openflowjava-util/pom.xml create mode 100644 openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java create mode 100644 openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java create mode 100755 openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java create mode 100644 openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java create mode 100644 openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java create mode 100755 openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java create mode 100644 openflowjava/parent/pom.xml create mode 100644 openflowjava/pom.xml create mode 100644 openflowjava/simple-client/pom.xml create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientEvent.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslKeyStore.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslTrustStore.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/OFClient.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java create mode 100644 openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java create mode 100644 openflowjava/simple-client/src/main/resources/scenario.xml create mode 100644 openflowjava/simple-client/src/main/resources/scenario.xsd create mode 100644 openflowjava/simple-client/src/main/resources/selfSignedController create mode 100644 openflowjava/simple-client/src/main/resources/selfSignedSwitch diff --git a/openflowjava/artifacts/pom.xml b/openflowjava/artifacts/pom.xml new file mode 100644 index 0000000000..54204e9010 --- /dev/null +++ b/openflowjava/artifacts/pom.xml @@ -0,0 +1,99 @@ + + + + + + 4.0.0 + + + org.opendaylight.odlparent + odlparent-lite + 2.0.0 + + + + org.opendaylight.openflowjava + openflowjava-artifacts + 0.10.0-SNAPSHOT + pom + + ODL :: openflowjava :: ${project.artifactId} + + + + + ${project.groupId} + openflow-protocol-api + ${project.version} + + + ${project.groupId} + openflow-protocol-impl + ${project.version} + + + ${project.groupId} + openflow-protocol-impl + ${project.version} + 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 + ${project.version} + + + ${project.groupId} + simple-client + ${project.version} + + + ${project.groupId} + openflowjava-util + ${project.version} + + + ${project.groupId} + openflowjava-config + ${project.version} + + + ${project.groupId} + openflowjava-config + ${project.version} + xml + configstats + + + ${project.groupId} + features-openflowjava + ${project.version} + features + xml + + + + + diff --git a/openflowjava/features/features-openflowjava/pom.xml b/openflowjava/features/features-openflowjava/pom.xml new file mode 100644 index 0000000000..036501c457 --- /dev/null +++ b/openflowjava/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/openflowjava/features/odl-openflowjava-all/pom.xml b/openflowjava/features/odl-openflowjava-all/pom.xml new file mode 100644 index 0000000000..38d7c4fef0 --- /dev/null +++ b/openflowjava/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/openflowjava/features/odl-openflowjava-protocol/pom.xml b/openflowjava/features/odl-openflowjava-protocol/pom.xml new file mode 100644 index 0000000000..9092873c84 --- /dev/null +++ b/openflowjava/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/openflowjava/features/odl-openflowjava-protocol/src/main/feature/feature.xml b/openflowjava/features/odl-openflowjava-protocol/src/main/feature/feature.xml new file mode 100644 index 0000000000..b1261d3f1a --- /dev/null +++ b/openflowjava/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/openflowjava/features/pom.xml b/openflowjava/features/pom.xml new file mode 100644 index 0000000000..44633fb45a --- /dev/null +++ b/openflowjava/features/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + org.opendaylight.odlparent + odlparent-lite + 2.0.0 + + + + org.opendaylight.openflowjava + features-aggregator + 0.10.0-SNAPSHOT + pom + + ODL :: openflowjava :: ${project.artifactId} + + + features-openflowjava + odl-openflowjava-protocol + odl-openflowjava-all + + + diff --git a/openflowjava/openflow-protocol-api/pom.xml b/openflowjava/openflow-protocol-api/pom.xml new file mode 100644 index 0000000000..5a2777d092 --- /dev/null +++ b/openflowjava/openflow-protocol-api/pom.xml @@ -0,0 +1,83 @@ + + 4.0.0 + + org.opendaylight.mdsal + binding-parent + 0.11.0-SNAPSHOT + + + org.opendaylight.openflowjava + openflow-protocol-api + 0.10.0-SNAPSHOT + bundle + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + 2.3.0-SNAPSHOT + 0.11.0-SNAPSHOT + + + + + + + org.opendaylight.mdsal + mdsal-artifacts + ${mdsal.version} + import + pom + + + + org.opendaylight.mdsal.model + mdsal-model-artifacts + ${mdsal.model.version} + import + pom + + + + + + + org.opendaylight.mdsal + yang-binding + + + org.opendaylight.yangtools + yang-common + + + org.opendaylight.mdsal.model + ietf-inet-types-2013-07-15 + + + org.opendaylight.mdsal.model + ietf-yang-types-20130715 + + + org.opendaylight.mdsal.model + yang-ext + + + io.netty + netty-buffer + + + junit + junit + test + + + org.mockito + mockito-core + + + diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java new file mode 100644 index 0000000000..a61ea51336 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionAdapter.java @@ -0,0 +1,103 @@ +/* + * 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.api.connection; + +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; + +/** + * @author mirehak + * @author michal.polkorab + */ +public interface ConnectionAdapter extends OpenflowProtocolService { + + /** + * disconnect corresponding switch + * @return future set to true, when disconnect completed + */ + Future disconnect(); + + /** + * @return true, if connection to switch is alive + */ + boolean isAlive(); + + /** + * @return address of the remote end - address of a switch if connected + */ + InetSocketAddress getRemoteAddress(); + + /** + * @param messageListener here will be pushed all messages from switch + */ + void setMessageListener(OpenflowProtocolListener messageListener); + + /** + * @param systemListener here will be pushed all system messages from library + */ + 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 + */ + void checkListeners(); + + /** + * notify listener about connection ready-to-use event + */ + void fireConnectionReadyNotification(); + + /** + * set listener for connection became ready-to-use event + * @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); + + /** + * @return true, if channel is configured to autoread + */ + boolean isAutoRead(); + + /** + * Registers a new bypass outbound queue + * @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 + OutboundQueueHandlerRegistration registerOutboundQueueHandler(T handler, + int maxQueueDepth, long maxBarrierNanos); + + /** + * Set filtering of PacketIn messages. By default these messages are not filtered. + * @param enabled True if PacketIn messages should be filtered, false if they should be reported. + */ + @Beta + void setPacketInFiltering(boolean enabled); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java new file mode 100644 index 0000000000..578e97b552 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionConfiguration.java @@ -0,0 +1,58 @@ +/* + * 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.api.connection; + +import java.net.InetAddress; + +/** + * @author mirehak + */ +public interface ConnectionConfiguration { + + /** + * @return address to bind, if null, all available interfaces will be used + */ + InetAddress getAddress(); + + /** + * @return port to bind + */ + int getPort(); + + /** + * @return transport protocol to use + */ + Object getTransferProtocol(); + + /** + * @return TLS configuration object + */ + TlsConfiguration getTlsConfiguration(); + + /** + * @return silence time (in milliseconds) - after this time + * {@link org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent} + * message is sent upstream + */ + long getSwitchIdleTimeout(); + + /** + * @return seed for {@link javax.net.ssl.SSLEngine} + */ + Object getSslContext(); + + /** + * @return thread numbers for TcpHandler's eventloopGroups + */ + ThreadConfiguration getThreadConfiguration(); + + /** + * @return boolean value for usability of Barrier + */ + boolean useBarrier(); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionReadyListener.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionReadyListener.java new file mode 100644 index 0000000000..0c7e026df3 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ConnectionReadyListener.java @@ -0,0 +1,21 @@ +/* + * 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.api.connection; + +/** + * @author mirehak + * + */ +public interface ConnectionReadyListener { + + /** + * fired when connection becomes ready-to-use + */ + void onConnectionReady(); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/DeviceRequestFailedException.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/DeviceRequestFailedException.java new file mode 100644 index 0000000000..347d73d0a0 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/DeviceRequestFailedException.java @@ -0,0 +1,35 @@ +/* + * 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.api.connection; + +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error; + +/** + * Exception which is used to report that a particular request failed on the + * remote device (switch). + */ +public class DeviceRequestFailedException extends OutboundQueueException { + private static final long serialVersionUID = 1L; + private final Error error; + + public DeviceRequestFailedException(final String message, @Nonnull final Error error) { + super(message); + this.error = Preconditions.checkNotNull(error); + } + + public DeviceRequestFailedException(final String message, @Nonnull final Error error, final Throwable cause) { + super(message, cause); + this.error = Preconditions.checkNotNull(error); + } + + @Nonnull public Error getError() { + return error; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ListeningStatusProvider.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ListeningStatusProvider.java new file mode 100644 index 0000000000..f54b7c2c0a --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ListeningStatusProvider.java @@ -0,0 +1,24 @@ +/* + * 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.api.connection; + +import java.util.concurrent.Future; + +/** + * for testing purposed + * @author mirehak + */ +public interface ListeningStatusProvider { + + /** + * @return future holding startup result of all library instances under plugin's control + */ + Future isOnline(); + +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java new file mode 100644 index 0000000000..3b9e7752b9 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueue.java @@ -0,0 +1,82 @@ +/* + * 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.api.connection; + +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; + +@Beta +public interface OutboundQueue { + /** + * Reserve an entry in the outbound queue. + * @return XID for the new message, or null if the queue is full + */ + Long reserveEntry(); + + /** + * 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. + * @throws IllegalArgumentException if the slot is already committed or was never reserved. + */ + 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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueException.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueException.java new file mode 100644 index 0000000000..497c7a255a --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueException.java @@ -0,0 +1,29 @@ +/* + * 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.api.connection; + +/** + * Exception reported when an exceptional event occurs on an {@link OutboundQueue}, + * which the {@link OutboundQueueHandler} needs to be aware of. + */ +public class OutboundQueueException extends Exception { + /** + * Exception reported when the device disconnects. + */ + public static final OutboundQueueException DEVICE_DISCONNECTED = new OutboundQueueException("Device disconnected"); + + private static final long serialVersionUID = 1L; + + public OutboundQueueException(final String message) { + super(message); + } + + public OutboundQueueException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandler.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandler.java new file mode 100644 index 0000000000..08007985f2 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandler.java @@ -0,0 +1,37 @@ +/* + * 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.api.connection; + +import com.google.common.annotations.Beta; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; + +/** + * Handler of the outbound queue. The queue has a maximum depth assigned when the + * handler is registered. + */ +@Beta +public interface OutboundQueueHandler { + /** + * Create a new {@link BarrierInput barrier} message. This callback is invoked + * when the queue is being flushed to the switch. The barrier ensures that any + * outstanding requests are detected as either completed or failed. + * + * @param xid XID for the barrier message + * @return New barrier message. + */ + @Nonnull BarrierInput createBarrierRequest(@Nonnull Long xid); + + /** + * Invoked whenever the underlying queue is refreshed. Implementations should + * ensure they are talking to the latest queue + * @param queue New queue instance, null indicates a shutdown, e.g. the queue + * is no longer available. + */ + void onConnectionQueueChanged(OutboundQueue queue); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandlerRegistration.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandlerRegistration.java new file mode 100644 index 0000000000..d31d1abb13 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/OutboundQueueHandlerRegistration.java @@ -0,0 +1,23 @@ +/* + * 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.api.connection; + +import com.google.common.annotations.Beta; +import org.opendaylight.yangtools.concepts.ObjectRegistration; + +/** + * An {@link ObjectRegistration} of a {@link OutboundQueueHandler}. Registration can be cancelled + * by invoking {@link #close()}. + * + * @param Handler type + */ +@Beta +public interface OutboundQueueHandlerRegistration extends ObjectRegistration { + @Override + void close(); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/StatisticsConfiguration.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/StatisticsConfiguration.java new file mode 100644 index 0000000000..daf870690b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/StatisticsConfiguration.java @@ -0,0 +1,27 @@ +/* + * 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.connection; + +/** + * Used for StatisticsCounter configuration + * + * @author madamjak + */ +public interface StatisticsConfiguration { + + /** + * @return true if statistics are / will be collected, false otherwise + */ + boolean getStatisticsCollect(); + + /** + * @return delay between two statistics logs (in milliseconds) + */ + int getLogReportDelay(); +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java new file mode 100644 index 0000000000..8b4fddf6ba --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/SwitchConnectionHandler.java @@ -0,0 +1,32 @@ +/* + * 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.api.connection; + +import java.net.InetAddress; + +/** + * @author mirehak + * @author michal.polkorab + * + */ +public interface SwitchConnectionHandler { + + /** + * @param connection to switch proving message sending/receiving, connection management + */ + void onSwitchConnected(ConnectionAdapter connection); + + /** + * @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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ThreadConfiguration.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ThreadConfiguration.java new file mode 100644 index 0000000000..e3d1fb66c4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/ThreadConfiguration.java @@ -0,0 +1,26 @@ +/* + * 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.connection; + +/** + * @author michal.polkorab + * + */ +public interface ThreadConfiguration { + + /** + * @return desired number of workerThreads processing the Openflow I/O + */ + int getWorkerThreadCount(); + + /** + * @return desired number of bossThreads registering incomming Openflow connections + */ + int getBossThreadCount(); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.java new file mode 100644 index 0000000000..f5a71a8c2c --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfiguration.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.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; + + +/** + * @author michal.polkorab + * + */ +public interface TlsConfiguration { + + /** + * @return keystore location + */ + String getTlsKeystore(); + + /** + * @return keystore type + */ + KeystoreType getTlsKeystoreType(); + + /** + * @return truststore location + */ + String getTlsTruststore(); + + /** + * @return truststore type + */ + KeystoreType getTlsTruststoreType(); + + /** + * @return keystore path type (CLASSPATH or PATH) + */ + PathType getTlsKeystorePathType(); + + /** + * @return truststore path type (CLASSPATH or PATH) + */ + PathType getTlsTruststorePathType(); + + /** + * @return password protecting specified keystore + */ + String getKeystorePassword(); + + /** + * @return password protecting certificate + */ + String getCertificatePassword(); + + /** + * @return password protecting specified truststore + */ + String getTruststorePassword(); + + /** + * @return list of cipher suites for TLS connection + */ + List getCipherSuites(); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java new file mode 100644 index 0000000000..2a290140ba --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImpl.java @@ -0,0 +1,101 @@ +/* + * 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.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; + +/** + * Class is used only for testing purposes - passwords are hardcoded + * @author michal.polkorab + */ +public class TlsConfigurationImpl implements TlsConfiguration { + + private KeystoreType trustStoreType; + private String trustStore; + private KeystoreType keyStoreType; + private String keyStore; + private PathType keystorePathType; + private PathType truststorePathType; + private List cipherSuites; + + /** + * Default constructor + * @param trustStoreType JKS or PKCS12 + * @param trustStore path to trustStore file + * @param trustStorePathType truststore path type (classpath or path) + * @param keyStoreType JKS or PKCS12 + * @param keyStore path to keyStore file + * @param keyStorePathType keystore path type (classpath or path) + */ + public TlsConfigurationImpl(KeystoreType trustStoreType, String trustStore, + PathType trustStorePathType, KeystoreType keyStoreType, + 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 + public KeystoreType getTlsTruststoreType() { + return trustStoreType; + } + + @Override + public String getTlsTruststore() { + return trustStore; + } + + @Override + public KeystoreType getTlsKeystoreType() { + return keyStoreType; + } + + @Override + public String getTlsKeystore() { + return keyStore; + } + + @Override + public PathType getTlsKeystorePathType() { + return keystorePathType; + } + + @Override + public PathType getTlsTruststorePathType() { + return truststorePathType; + } + + @Override + public String getKeystorePassword() { + return "opendaylight"; + } + + @Override + public String getCertificatePassword() { + return "opendaylight"; + } + + @Override + public String getTruststorePassword() { + return "opendaylight"; + } + + @Override + public List getCipherSuites() { + return cipherSuites; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/AlienMessageListener.java new file mode 100644 index 0000000000..a3cd7c6c49 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java new file mode 100644 index 0000000000..5a0658eb1b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerExtensionProvider.java @@ -0,0 +1,145 @@ +/* + * 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.extensibility; + +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.ExperimenterInstructionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; + +/** + * Provides methods for deserialization part of extensibility. + * In case of handling multiple multiple structures of same type (actions, + * instructions, match entries, ... ) which are differentiated by + * vendor / experimenter subtype, vendor has to switch / choose between + * these subtypes.
+ * + * This has to be done in this way because of experimenter headers, which + * provide only vendor / experimenter ID. Subtype position may be different + * for different vendors (or not present at all) - that's why vendor has to + * handle it in his own implementations. + * @author michal.polkorab + */ +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 + * @return true if deserializer was removed, + * false if no deserializer was found under specified key + */ + boolean unregisterDeserializer(ExperimenterDeserializerKey key); + + /** + * Registers action deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerActionDeserializer(ExperimenterActionDeserializerKey key, + OFGeneralDeserializer deserializer); + + /** + * Registers instruction deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerInstructionDeserializer(ExperimenterInstructionDeserializerKey key, + OFGeneralDeserializer deserializer); + + /** + * Registers match entry deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerMatchEntryDeserializer(MatchEntryDeserializerKey key, + OFGeneralDeserializer deserializer); + + /** + * Registers error message deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerErrorDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer); + + /** + * Registers experimenter (vendor) message deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer); + + /** + * Registers multipart-reply (stats) message deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer); + + /** + * Registers multipart-reply table-features message deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerMultipartReplyTFDeserializer(ExperimenterIdDeserializerKey key, + OFGeneralDeserializer deserializer); + + /** + * Registers meter band deserializer (used in multipart-reply meter-config) + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + void registerMeterBandDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer); + + /** + * Registers queue property (QUEUE_GET_CONFIG_REPLY message) deserializer + * @param key used for deserializer lookup + * @param deserializer deserializer instance + */ + 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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java new file mode 100644 index 0000000000..27660398b4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistry.java @@ -0,0 +1,53 @@ +/* + * 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.api.extensibility; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; + + +/** + * @author michal.polkorab + * + */ +public interface DeserializerRegistry { + + /** + * Initializes deserializers + */ + void init(); + + /** + * @param type of particular deserializer + * @param key used for deserializer lookup + * @return deserializer found + */ + + T getDeserializer(MessageCodeKey key); + + /** + * 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 deserializer + * @param key used for deserializer lookup + * @return true if deserializer was removed, + * false if no deserializer was found under specified key + */ + boolean unregisterDeserializer(MessageCodeKey key); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java new file mode 100644 index 0000000000..98e836334f --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/DeserializerRegistryInjector.java @@ -0,0 +1,21 @@ +/* + * 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.api.extensibility; + +/** + * Injects registry + * @author michal.polkorab + */ +public interface DeserializerRegistryInjector { + + /** + * Injects deserializer registry into deserializer + * @param deserializerRegistry registry of deserializers + */ + void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKey.java new file mode 100644 index 0000000000..b8a7ec0df0 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKey.java @@ -0,0 +1,62 @@ +/* + * 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.api.extensibility; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; + +/** + * @author michal.polkorab + * + */ +public class EnhancedMessageCodeKey extends MessageCodeKey { + + private int msgType2; + + /** + * Constructor + * @param version wire protocol version + * @param value used as distinguisher + * @param value2 used as detailed distinguisher + * @param clazz class of object that is going to be deserialized + */ + public EnhancedMessageCodeKey(short version, int value, int value2, Class clazz) { + super(version, value, clazz); + this.msgType2 = value2; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + msgType2; + 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; + } + EnhancedMessageCodeKey other = (EnhancedMessageCodeKey) obj; + if (msgType2 != other.msgType2) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " msgType2: " + msgType2; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java new file mode 100644 index 0000000000..3a9fffc260 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKey.java @@ -0,0 +1,68 @@ +/* + * 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.api.extensibility; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; + + +/** + * More specific key for {@link SerializerRegistry} + * @author michal.polkorab + * @param main type + * @param specific type + */ +public class EnhancedMessageTypeKey extends MessageTypeKey { + + private final Class msgType2; + + /** + * @param msgVersion protocol version + * @param msgType main type + * @param msgType2 subtype + */ + public EnhancedMessageTypeKey(short msgVersion, Class msgType, Class msgType2) { + super(msgVersion, msgType); + this.msgType2 = msgType2; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((msgType2 == null) ? 0 : msgType2.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; + } + @SuppressWarnings("rawtypes") + EnhancedMessageTypeKey other = (EnhancedMessageTypeKey) obj; + if (msgType2 == null) { + if (other.msgType2 != null) { + return false; + } + } else if (!msgType2.getName().equals(other.msgType2.getName())) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " msgType2: " + msgType2.getName(); + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java new file mode 100644 index 0000000000..c80df7b964 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderDeserializer.java @@ -0,0 +1,26 @@ +/* + * 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.api.extensibility; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * @author michal.polkorab + * @param output message type + */ +public interface HeaderDeserializer extends OFGeneralDeserializer { + + /** + * Deserializes byte message headers + * + * @param rawMessage message as bytes in ByteBuf + * @return POJO/DTO + */ + E deserializeHeader(ByteBuf rawMessage); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java new file mode 100644 index 0000000000..427d84ce29 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/HeaderSerializer.java @@ -0,0 +1,26 @@ +/* + * 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.api.extensibility; + +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 input message type + */ +public interface HeaderSerializer extends OFGeneralSerializer { + + /** + * Serializes object headers (e.g. for Multipart message - Table Features) + * @param input object whose headers should be serialized + * @param outBuffer output buffer + */ + void serializeHeader(T input, ByteBuf outBuffer); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java new file mode 100644 index 0000000000..06c54f9dc4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFDeserializer.java @@ -0,0 +1,29 @@ +/* + * 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.api.extensibility; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * Uniform interface for deserializing factories + * @author michal.polkorab + * @author timotej.kubas + * @param message code type + */ +public interface OFDeserializer extends OFGeneralDeserializer { + + /** + * Transforms byte message into POJO/DTO (of type E). + * + * @param message message as bytes in ByteBuf + * @return POJO/DTO + */ + E deserialize(ByteBuf message); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralDeserializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralDeserializer.java new file mode 100644 index 0000000000..c4132cc6dd --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralDeserializer.java @@ -0,0 +1,17 @@ +/* + * 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.api.extensibility; + + +/** + * @author michal.polkorab + */ +public interface OFGeneralDeserializer { + + // empty unifying interface +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralSerializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralSerializer.java new file mode 100644 index 0000000000..6dd5d3f07b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFGeneralSerializer.java @@ -0,0 +1,17 @@ +/* + * 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.api.extensibility; + +/** + * Unifying superinterface + * @author michal.polkorab + * */ +public interface OFGeneralSerializer { + + // empty unifying superinterface +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java new file mode 100644 index 0000000000..ec63be53d2 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/OFSerializer.java @@ -0,0 +1,29 @@ +/* + * 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.api.extensibility; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * Uniform interface for serializers + * @author michal.polkorab + * @author timotej.kubas + * @param message type + */ +public interface OFSerializer extends OFGeneralSerializer { + + /** + * Transforms POJO/DTO into byte message (ByteBuf). + * @param input object to be serialized + * @param outBuffer output buffer + */ + void serialize(T input, ByteBuf outBuffer); + +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java new file mode 100755 index 0000000000..366cd3ab93 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerExtensionProvider.java @@ -0,0 +1,129 @@ +/* + * 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.extensibility; + +import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmClassBase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; +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; + + +/** + * Provides methods for serialization part of extensibility. + * In case of handling multiple structures of same type (actions, + * instructions, match entries, ... ) which are differentiated by + * vendor / experimenter subtype, vendor has to switch / choose between + * these subtypes.
+ * + * This has to be done in this way because of unknown augmentations + * - that's why vendor has to handle it in his own implementations. + * @author michal.polkorab + */ +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 + * @return true if serializer was removed, + * false if no serializer was found under specified key + */ + boolean unregisterSerializer(ExperimenterSerializerKey key); + + /** + * Registers action serializer + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerActionSerializer(ActionSerializerKey key, + OFGeneralSerializer serializer); + + /** + * Registers instruction serializer + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerInstructionSerializer(InstructionSerializerKey key, + OFGeneralSerializer serializer); + + /** + * Registers match entry serializer + * @param oxm type + * @param match field type + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerMatchEntrySerializer( + MatchEntrySerializerKey key,OFGeneralSerializer serializer); + + /** + * Registers experimenter (vendor) message serializer + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + 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); + + /** + * Registers multipart-request table-features serializer + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + void registerMultipartRequestTFSerializer(ExperimenterIdSerializerKey key, + OFGeneralSerializer serializer); + + /** + * @deprecated Since we use ExperimenterIdMeterSubTypeSerializerKey as MeterBandSerializer's key, in order to avoid + * the occurrence of an error,we should discard this function + * Registers meter band serializer (used in meter-mod messages) + * @param key used for serializer lookup + * @param serializer serializer implementation + */ + @Deprecated + void registerMeterBandSerializer(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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java new file mode 100644 index 0000000000..1ddc48565e --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistry.java @@ -0,0 +1,56 @@ +/* + * 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.api.extensibility; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; + +/** + * Stores and handles serializers
+ * K - {@link MessageTypeKey} parameter type,
+ * S - returned serializer type + * @author michal.polkorab + */ +public interface SerializerRegistry { + + /** + * Serializer registry provisioning + */ + void init(); + + /** + * @param input key type + * @param type of resulting serializer + * @param msgTypeKey lookup key + * @return serializer or NullPointerException if no serializer was found + */ + S getSerializer(MessageTypeKey msgTypeKey); + + /** + * 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 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 + */ + boolean unregisterSerializer(MessageTypeKey key); +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistryInjector.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistryInjector.java new file mode 100644 index 0000000000..b074b15fc7 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/extensibility/SerializerRegistryInjector.java @@ -0,0 +1,22 @@ +/* + * 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.api.extensibility; + +/** + * Serializer registry injector + * @author michal.polkorab + */ +public interface SerializerRegistryInjector { + + /** + * Injects serializer registry + * @param serializerRegistry registry instance + */ + void injectSerializerRegistry(SerializerRegistry serializerRegistry); + +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKey.java new file mode 100644 index 0000000000..208a122771 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKey.java @@ -0,0 +1,65 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class ActionDeserializerKey extends MessageCodeKey { + + private Long experimenterId; + /** + * @param version protocol wire version + * @param type action type + * @param experimenterId experimenter / vendor ID + */ + public ActionDeserializerKey(short version, + int type, Long experimenterId) { + super(version, type, Action.class); + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof ActionDeserializerKey)) { + return false; + } + ActionDeserializerKey other = (ActionDeserializerKey) obj; + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKey.java new file mode 100644 index 0000000000..7d096f84e5 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKey.java @@ -0,0 +1,78 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * @param action type + */ +public class ActionSerializerKey extends MessageTypeKey + implements ExperimenterSerializerKey { + + private Class actionType; + private Long experimenterId; + + /** + * @param msgVersion protocol wire version + * @param actionType type of action + * @param experimenterId experimenter / vendor ID + */ + public ActionSerializerKey(short msgVersion, Class actionType, + Long experimenterId) { + super(msgVersion, Action.class); + this.actionType = actionType; + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((actionType == null) ? 0 : actionType.hashCode()); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.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; + } + ActionSerializerKey other = (ActionSerializerKey) obj; + if (actionType == null) { + if (other.actionType != null) { + return false; + } + } else if (!actionType.equals(other.actionType)) { + return false; + } + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " action type: " + actionType.getName() + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionDeserializerKey.java new file mode 100644 index 0000000000..40f21d76a6 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionDeserializerKey.java @@ -0,0 +1,28 @@ +/* + * 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.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public final class ExperimenterActionDeserializerKey extends ActionDeserializerKey + implements ExperimenterDeserializerKey { + + /** + * @param version protocol wire version + * @param experimenterId experimenter / vendor ID + */ + public ExperimenterActionDeserializerKey(short version, Long experimenterId) { + super(version, EncodeConstants.EXPERIMENTER_VALUE, experimenterId); + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionSerializerKey.java new file mode 100644 index 0000000000..b07c696ab5 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterActionSerializerKey.java @@ -0,0 +1,61 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.action.container.action.choice.ExperimenterIdCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.ExperimenterActionSubType; + +/** + * @author michal.polkorab + */ +public final class ExperimenterActionSerializerKey extends ActionSerializerKey + implements ExperimenterSerializerKey { + + private Class actionSubType; + + /** + * @param msgVersion protocol wire version + * @param experimenterId experimenter / vendor ID + * @param actionSubType vendor defined subtype + */ + public ExperimenterActionSerializerKey(short msgVersion, Long experimenterId, Class actionSubType) { + super(msgVersion, ExperimenterIdCase.class, experimenterId); + this.actionSubType = actionSubType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((actionSubType == null) ? 0 : actionSubType.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; + } + ExperimenterActionSerializerKey other = (ExperimenterActionSerializerKey) obj; + if (actionSubType == null) { + if (other.actionSubType != null) { + return false; + } + } else if (!actionSubType.equals(other.actionSubType)) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterDeserializerKey.java new file mode 100644 index 0000000000..3169de76f4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterDeserializerKey.java @@ -0,0 +1,17 @@ +/* + * 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; + +/** + * Marker interface - marks keys appropriate for experimenter deserializer registration + * @author michal.polkorab + */ +public interface ExperimenterDeserializerKey { + // only empty marker interface - to ease extensions registration +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java new file mode 100644 index 0000000000..ec2cf3e1c8 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdDeserializerKey.java @@ -0,0 +1,67 @@ +/* + * 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.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yangtools.yang.binding.DataContainer; + +/** + * @author michal.polkorab + */ +public class ExperimenterIdDeserializerKey extends MessageCodeKey implements ExperimenterDeserializerKey { + + 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(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 + hashCodeOfLong(experimenterId); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof ExperimenterIdDeserializerKey)) { + return false; + } + ExperimenterIdDeserializerKey other = (ExperimenterIdDeserializerKey) obj; + if (experimenterId != other.experimenterId) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdMeterSubTypeSerializerKey.java new file mode 100755 index 0000000000..f568a0284f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java new file mode 100644 index 0000000000..8a900e346e --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdSerializerKey.java @@ -0,0 +1,67 @@ +/* + * 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 + * @param class of object to be serialized + */ +public class ExperimenterIdSerializerKey extends MessageTypeKey + implements ExperimenterSerializerKey { + + private long experimenterId; + + /** + * @param msgVersion protocol wire version + * @param experimenterId experimenter / vendor ID + * @param objectClass class of object to be serialized + */ + public ExperimenterIdSerializerKey(short msgVersion, + long experimenterId, Class objectClass) { + super(msgVersion, objectClass); + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.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) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof ExperimenterIdSerializerKey)) { + return false; + } + ExperimenterIdSerializerKey other = (ExperimenterIdSerializerKey) obj; + if (experimenterId != other.experimenterId) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeDeserializerKey.java new file mode 100644 index 0000000000..c956feb06c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterIdTypeSerializerKey.java new file mode 100644 index 0000000000..b8f6ac9326 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java new file mode 100644 index 0000000000..eea3e4ef82 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionDeserializerKey.java @@ -0,0 +1,28 @@ +/* + * 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.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public final class ExperimenterInstructionDeserializerKey extends InstructionDeserializerKey + implements ExperimenterDeserializerKey { + + /** + * @param version protocol wire version + * @param experimenterId experimenter (vendor) identifier + */ + public ExperimenterInstructionDeserializerKey(short version, Long experimenterId) { + super(version, EncodeConstants.EXPERIMENTER_VALUE, experimenterId); + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionSerializerKey.java new file mode 100644 index 0000000000..15ee03a04b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterInstructionSerializerKey.java @@ -0,0 +1,27 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.instruction.container.instruction.choice.ExperimenterIdCase; + +/** + * @author michal.polkorab + */ +public final class ExperimenterInstructionSerializerKey extends InstructionSerializerKey + implements ExperimenterSerializerKey { + + /** + * @param msgVersion protocol wire version + * @param experimenterId experimenter / vendor ID + */ + public ExperimenterInstructionSerializerKey(short msgVersion, Long experimenterId) { + super(msgVersion, ExperimenterIdCase.class, experimenterId); + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterSerializerKey.java new file mode 100644 index 0000000000..d027155af7 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/ExperimenterSerializerKey.java @@ -0,0 +1,17 @@ +/* + * 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; + +/** + * Marker interface - marks keys appropriate for experimenter serializer registration + * @author michal.polkorab + */ +public interface ExperimenterSerializerKey { + // only empty marker interface - to ease extensions registration +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java new file mode 100644 index 0000000000..8482f6ef2d --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKey.java @@ -0,0 +1,65 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class InstructionDeserializerKey extends MessageCodeKey { + + private Long experimenterId; + /** + * @param version protocol wire version + * @param type instruction type + * @param experimenterId experimenter (vendor) identifier + */ + public InstructionDeserializerKey(short version, int type, + Long experimenterId) { + super(version, type, Instruction.class); + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof InstructionDeserializerKey)) { + return false; + } + InstructionDeserializerKey other = (InstructionDeserializerKey) obj; + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKey.java new file mode 100644 index 0000000000..213b22dbf1 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKey.java @@ -0,0 +1,79 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.InstructionChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * @param instruction type + */ +public class InstructionSerializerKey + extends MessageTypeKey implements ExperimenterSerializerKey { + + private Class instructionType; + private Long experimenterId; + + /** + * @param msgVersion protocol wire version + * @param instructionType type of instruction + * @param experimenterId experimenter / vendor ID + */ + public InstructionSerializerKey(short msgVersion, Class instructionType, + Long experimenterId) { + super(msgVersion, Instruction.class); + this.instructionType = instructionType; + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + result = prime * result + ((instructionType == null) ? 0 : instructionType.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof InstructionSerializerKey)) { + return false; + } + InstructionSerializerKey other = (InstructionSerializerKey) obj; + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + if (instructionType == null) { + if (other.instructionType != null) { + return false; + } + } else if (!instructionType.equals(other.instructionType)) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " instructionType type: " + instructionType.getName() + + " vendorID: " + experimenterId; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKey.java new file mode 100644 index 0000000000..4f995959af --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKey.java @@ -0,0 +1,79 @@ +/* + * 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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * @author michal.polkorab + * + */ +public final class MatchEntryDeserializerKey extends MessageCodeKey + implements ExperimenterDeserializerKey { + + private int oxmField; + private Long experimenterId; + + /** + * @param version protocol wire version + * @param oxmClass oxm_class (see specification) + * @param oxmField oxm_field (see specification) + */ + public MatchEntryDeserializerKey(short version, + int oxmClass, int oxmField) { + super(version, oxmClass, MatchEntry.class); + this.oxmField = oxmField; + } + + /** + * @param experimenterId experimenter / vendor ID + */ + public void setExperimenterId(Long experimenterId) { + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + result = prime * result + oxmField; + 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; + } + MatchEntryDeserializerKey other = (MatchEntryDeserializerKey) obj; + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + if (oxmField != other.oxmField) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " oxm_field: " + oxmField + " experimenterID: " + experimenterId; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKey.java new file mode 100644 index 0000000000..75fcd3e600 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKey.java @@ -0,0 +1,97 @@ +/* + * 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.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; + +/** + * @author michal.polkorab + * @param oxm_class (see specification) + * @param oxm_field (see specification) + */ +public final class MatchEntrySerializerKey + extends MessageTypeKey implements ExperimenterSerializerKey { + + private Class oxmClass; + private Class oxmField; + private Long experimenterId; + + /** + * @param msgVersion protocol wire version + * @param oxmClass oxm_class (see specification) + * @param oxmField oxm_field (see specification) + */ + public MatchEntrySerializerKey(short msgVersion, Class oxmClass, + Class oxmField) { + super(msgVersion, MatchEntry.class); + this.oxmClass = oxmClass; + this.oxmField = oxmField; + } + + /** + * @param experimenterId experimenter / vendor ID + */ + public void setExperimenterId(Long experimenterId) { + this.experimenterId = experimenterId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((experimenterId == null) ? 0 : experimenterId.hashCode()); + result = prime * result + ((oxmClass == null) ? 0 : oxmClass.hashCode()); + result = prime * result + ((oxmField == null) ? 0 : oxmField.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; + } + MatchEntrySerializerKey other = (MatchEntrySerializerKey) obj; + if (experimenterId == null) { + if (other.experimenterId != null) { + return false; + } + } else if (!experimenterId.equals(other.experimenterId)) { + return false; + } + if (oxmClass == null) { + if (other.oxmClass != null) { + return false; + } + } else if (!oxmClass.equals(other.oxmClass)) { + return false; + } + if (oxmField == null) { + if (other.oxmField != null) { + return false; + } + } else if (!oxmField.equals(other.oxmField)) { + return false; + } + return true; + } + + @Override + public String toString() { + return super.toString() + " oxm_class: " + oxmClass.getName() + " oxm_field: " + + oxmField.getName() + " experimenterID: " + experimenterId; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java new file mode 100644 index 0000000000..566b3623cd --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageCodeKey.java @@ -0,0 +1,81 @@ +/* + * 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.api.keys; + +/** + * @author michal.polkorab + */ +public class MessageCodeKey { + + private short msgVersion; + private int msgType; + private Class clazz; + + /** + * Constructor + * @param version wire protocol version + * @param value used as distinguisher (read from binary data / buffer) + * @param clazz class of object that is going to be deserialized + */ + public MessageCodeKey(short version, int value, Class clazz) { + this.msgVersion = version; + this.msgType = value; + this.clazz = clazz; + } + + public int getMsgType() { + return this.msgType; + } + + public Class getClazz() { + return this.clazz; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((clazz == null) ? 0 : clazz.hashCode()); + result = prime * result + msgType; + result = prime * result + msgVersion; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof MessageCodeKey)) { + return false; + } + MessageCodeKey other = (MessageCodeKey) obj; + if (clazz == null) { + if (other.clazz != null) { + return false; + } + } else if (!clazz.equals(other.clazz)) { + return false; + } + if (msgType != other.msgType) { + return false; + } + if (msgVersion != other.msgVersion) { + return false; + } + return true; + } + + @Override + public String toString() { + return "msgVersion: " + msgVersion + " objectClass: " + clazz.getName() + " msgType: " + msgType; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageTypeKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageTypeKey.java new file mode 100644 index 0000000000..5a130cb1c1 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/MessageTypeKey.java @@ -0,0 +1,68 @@ +/* + * 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.api.keys; + +/** + * Class used as a key in {@link org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry} + * @author michal.polkorab + * @author timotej.kubas + * @param message type (class) + */ +public class MessageTypeKey { + + private final Class msgType; + private final short msgVersion; + + /** + * @param msgVersion protocol version + * @param msgType type of message - class of serialized object + */ + public MessageTypeKey(short msgVersion, Class msgType) { + this.msgType = msgType; + this.msgVersion = msgVersion; + } + + @Override + public String toString() { + return "msgVersion: " + msgVersion + " objectType: " + msgType.getName(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((msgType == null) ? 0 : msgType.hashCode()); + result = prime * result + msgVersion; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof MessageTypeKey)) { + return false; + } + MessageTypeKey other = (MessageTypeKey) obj; + if (msgType == null) { + if (other.msgType != null) { + return false; + } + } else if (!msgType.equals(other.msgType)) { + return false; + } + if (msgVersion != other.msgVersion) { + return false; + } + return true; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java new file mode 100644 index 0000000000..71eed0948c --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKey.java @@ -0,0 +1,57 @@ +/* + * 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.api.keys; + +/** + * @author michal.polkorab + * + */ +public class TypeToClassKey { + + private short version; + private int type; + + /** + * Constructor + * @param version wire protocol version + * @param type message type / code + */ + public TypeToClassKey(short version, int type) { + this.version = version; + this.type = type; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + type; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TypeToClassKey other = (TypeToClassKey) obj; + if (type != other.type) { + return false; + } + if (version != other.version) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java new file mode 100644 index 0000000000..995fd35030 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/BinContent.java @@ -0,0 +1,36 @@ +/* + * 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.api.util; + +/** + * @author michal.polkorab + * + */ +public abstract class BinContent { + + private BinContent() { + //not called + } + + /** + * @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 input long value + * @return long cut into int + */ + public static int longToSignedInt(long value) { + return (int) value; + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java new file mode 100644 index 0000000000..58d6ccd42b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/EncodeConstants.java @@ -0,0 +1,75 @@ +/* + * 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.api.util; + +/** + * Stores common constants. + * @author michal.polkorab + */ +public abstract class EncodeConstants { + + /** Default OF padding (in bytes) */ + public static final byte PADDING = 8; + /** OpenFlow v1.0 wire protocol number */ + 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 */ + public static final int OFHEADER_SIZE = 8; + /** Zero length - used when the length is updated later */ + public static final int EMPTY_LENGTH = 0; + + /** Length of mac address */ + public static final byte MAC_ADDRESS_LENGTH = 6; + /** Number of groups in ipv4 address */ + public static final byte GROUPS_IN_IPV4_ADDRESS = 4; + /** Number of groups in ipv6 address */ + public static final byte GROUPS_IN_IPV6_ADDRESS = 8; + /** Length of ipv6 address in bytes */ + public static final byte SIZE_OF_IPV6_ADDRESS_IN_BYTES = (8 * Short.SIZE) / Byte.SIZE; + + /** Length of long in bytes */ + public static final byte SIZE_OF_LONG_IN_BYTES = Long.SIZE / Byte.SIZE; + /** Length of int in bytes */ + public static final byte SIZE_OF_INT_IN_BYTES = Integer.SIZE / Byte.SIZE; + /** Length of short in bytes */ + public static final byte SIZE_OF_SHORT_IN_BYTES = Short.SIZE / Byte.SIZE; + /** Length of byte in bytes */ + public static final byte SIZE_OF_BYTE_IN_BYTES = Byte.SIZE / Byte.SIZE; + /** Length of 3 bytes */ + public static final byte SIZE_OF_3_BYTES = 3; + + /** Empty (zero) int value */ + public static final int EMPTY_VALUE = 0; + /** 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; + + /** 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/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java new file mode 100644 index 0000000000..e47b70d663 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/java/org/opendaylight/openflowjava/protocol/api/util/OxmMatchConstants.java @@ -0,0 +1,120 @@ +/* + * 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.api.util; + +/** + * Stores oxm_match constants. + * @author michal.polkorab + */ +public abstract class OxmMatchConstants { + + /** Backward compatibility with NXM */ + public static final int NXM_0_CLASS = 0x0000; + /** Backward compatibility with NXM */ + public static final int NXM_1_CLASS = 0x0001; + /** Basic class for OpenFlow */ + public static final int OPENFLOW_BASIC_CLASS = 0x8000; + /** Experimenter class */ + public static final int EXPERIMENTER_CLASS = 0xFFFF; + + /** Switch input port */ + public static final int IN_PORT = 0; + /** Switch physical input port */ + public static final int IN_PHY_PORT = 1; + /** Metadata passed between tables */ + public static final int METADATA = 2; + /** Ethernet destination address */ + public static final int ETH_DST = 3; + /** Ethernet source address */ + public static final int ETH_SRC = 4; + /** Ethernet frame type */ + public static final int ETH_TYPE = 5; + /** VLAN id. */ + public static final int VLAN_VID = 6; + /** VLAN priority. */ + public static final int VLAN_PCP = 7; + /** IP DSCP (6 bits in ToS field). */ + public static final int IP_DSCP = 8; + /** IP ECN (2 bits in ToS field). */ + public static final int IP_ECN = 9; + /** IP protocol. */ + public static final int IP_PROTO = 10; + /** IPv4 source address. */ + public static final int IPV4_SRC = 11; + /** IPv4 destination address. */ + public static final int IPV4_DST = 12; + /** TCP source port. */ + public static final int TCP_SRC = 13; + /** TCP destination port. */ + public static final int TCP_DST = 14; + /** UDP source port. */ + public static final int UDP_SRC = 15; + /** UDP destination port. */ + public static final int UDP_DST = 16; + /** SCTP source port. */ + public static final int SCTP_SRC = 17; + /** SCTP destination port. */ + public static final int SCTP_DST = 18; + /** ICMP type. */ + public static final int ICMPV4_TYPE = 19; + /** ICMP code. */ + public static final int ICMPV4_CODE = 20; + /** ARP opcode. */ + public static final int ARP_OP = 21; + /** ARP source IPv4 address. */ + public static final int ARP_SPA = 22; + /** ARP target IPv4 address. */ + public static final int ARP_TPA = 23; + /** ARP source hardware address. */ + public static final int ARP_SHA = 24; + /** ARP target hardware address. */ + public static final int ARP_THA = 25; + /** IPv6 source address. */ + public static final int IPV6_SRC = 26; + /** IPv6 destination address. */ + public static final int IPV6_DST = 27; + /** IPv6 Flow Label */ + public static final int IPV6_FLABEL = 28; + /** ICMPv6 type. */ + public static final int ICMPV6_TYPE = 29; + /** ICMPv6 code. */ + public static final int ICMPV6_CODE = 30; + /** Target address for ND. */ + public static final int IPV6_ND_TARGET = 31; + /** Source link-layer for ND. */ + public static final int IPV6_ND_SLL = 32; + /** Target link-layer for ND. */ + public static final int IPV6_ND_TLL = 33; + /** MPLS label. */ + public static final int MPLS_LABEL = 34; + /** MPLS TC. */ + public static final int MPLS_TC = 35; + /** MPLS BoS bit. */ + public static final int MPLS_BOS = 36; + /** PBB I-SID. */ + public static final int PBB_ISID = 37; + /** Logical Port Metadata. */ + public static final int TUNNEL_ID = 38; + /** IPv6 Extension Header pseudo-field */ + public static final int IPV6_EXTHDR = 39; + + /** + * OFPXMC_NXM_1 class Constants + */ + + /** NXM IPv4 Tunnel Endpoint Source */ + public static final int NXM_NX_TUN_IPV4_SRC = 31; + /** NXM IPv4 Tunnel Endpoint Destination */ + public static final int NXM_NX_TUN_IPV4_DST = 32; + /** NXM TCP_Flag value */ + public static final int NXM_NX_TCP_FLAG = 34; + + private OxmMatchConstants() { + //not called + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-action.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-action.yang new file mode 100644 index 0000000000..d2ae42f681 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-action.yang @@ -0,0 +1,211 @@ +/* + * 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 + */ + + module openflow-action { + namespace "urn:opendaylight:openflow:common:action"; + prefix "ofaction"; + + import ietf-inet-types {prefix inet;} + import ietf-yang-types {prefix yang;} + + import openflow-types { prefix oft; } + import openflow-extensible-match { prefix oxm;} + + revision "2015-02-03" { + description "#NOT_PUBLISHED# OpenFlow 1.3 - action model"; + } + + identity experimenter-action-sub-type { + description "The base identity for vendor's actions."; + } + + container action-container { + uses action-grouping; + } + + grouping actions-grouping { + list action { + uses action-grouping; + leaf experimenter-id { + type oft:experimenter-id; + } + } + } + + grouping action-grouping { + choice action-choice { + case output-action-case { + container output-action { + leaf port { + type oft:port-number; + } + leaf max-length { + type uint16; + } + } + } + case copy-ttl-out-case { + // empty action + } + case copy-ttl-in-case { + // empty action + } + case set-mpls-ttl-case { + container set-mpls-ttl-action { + leaf mpls-ttl { + type uint8; + } + } + } + case dec-mpls-ttl-case { + // empty action + } + case push-vlan-case { + container push-vlan-action { + leaf ethertype { + type oft:ether-type; + } + } + } + case pop-vlan-case { + // empty action + } + case push-mpls-case { + container push-mpls-action { + leaf ethertype { + type oft:ether-type; + } + } + } + case pop-mpls-case { + container pop-mpls-action { + leaf ethertype { + type oft:ether-type; + } + } + } + case set-queue-case { + container set-queue-action { + leaf queue-id { + type uint32; + } + } + } + case group-case { + container group-action { + leaf group-id { + type uint32; + } + } + } + case set-nw-ttl-case { + container set-nw-ttl-action { + leaf nw-ttl { + type uint8; + } + } + } + case dec-nw-ttl-case { + // empty action + } + case set-field-case { + container set-field-action { + uses oxm:match-entries-grouping; + } + } + case push-pbb-case { + container push-pbb-action { + leaf ethertype { + type oft:ether-type; + } + } + } + case pop-pbb-case { + // empty action + } + // OF1.0 structures + case set-vlan-vid-case { + container set-vlan-vid-action { + leaf vlan-vid { + type uint16; + } + } + } + case set-vlan-pcp-case { + container set-vlan-pcp-action { + leaf vlan-pcp { + type uint8; + } + } + } + case strip-vlan-case { + // empty action + } + case set-dl-src-case { + container set-dl-src-action { + leaf dl-src-address { + type yang:mac-address; + } + } + } + case set-dl-dst-case { + container set-dl-dst-action { + leaf dl-dst-address { + type yang:mac-address; + } + } + } + case set-nw-src-case { + container set-nw-src-action { + leaf ip-address { + type inet:ipv4-address; + } + } + } + case set-nw-dst-case { + container set-nw-dst-action { + leaf ip-address { + type inet:ipv4-address; + } + } + } + case set-nw-tos-case { + container set-nw-tos-action { + leaf nw-tos { + type uint8; + } + } + } + case set-tp-src-case { + container set-tp-src-action { + leaf port { + type oft:port-number; + } + } + } + case set-tp-dst-case { + container set-tp-dst-action { + leaf port { + type oft:port-number; + } + } + } + case enqueue-case { + container enqueue-action { + leaf port { + type oft:port-number; + } + leaf queue-id { + type oft:queue-id; + } + } + } + } + } + +} diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-approved-extensions.yang new file mode 100644 index 0000000000..29a2035110 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/main/yang/openflow-augments.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-augments.yang new file mode 100755 index 0000000000..4a60c37e35 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-augments.yang @@ -0,0 +1,136 @@ +/* + * 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 + */ + + module openflow-augments { + namespace "urn:opendaylight:openflow:augments"; + prefix "aug"; + + import yang-ext {prefix ext;} + import ietf-inet-types {prefix inet;} + import ietf-yang-types {prefix yang;} + + import openflow-types {prefix oft;} + import openflow-protocol {prefix ofproto;} + import openflow-action {prefix ofaction;} + import openflow-instruction {prefix ofinstruction;} + import openflow-extensible-match {prefix oxm;} + + revision "2015-02-25" { + 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"; + } + +// OFP_MATCH AUGMENTS + augment "/oxm:oxm-container/oxm:match-entry-value" { + ext:augment-identifier "experimenter-id-match-entry"; + case experimenter-id-case { + container experimenter { + leaf experimenter { + type oft:experimenter-id; + } + } + } + } + +// OFP_ACTION AUGMENTS + augment "/ofaction:action-container/ofaction:action-choice" { + ext:augment-identifier "experimenter-id-action"; + case experimenter-id-case { + container experimenter { + leaf experimenter { + type oft:experimenter-id; + } + leaf sub-type { + type identityref { + base ofaction:experimenter-action-sub-type; + } + } + } + } + } + +// OFP_TABLE_FEATURES_PROPERTIES AUGMENTS + augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" { + ext:augment-identifier "instruction-related-table-feature-property"; + uses ofinstruction:instructions-grouping; + } + augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" { + ext:augment-identifier "next-table-related-table-feature-property"; + list next-table-ids { + config false; + leaf table-id { + type uint8; + } + } + } + augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" { + ext:augment-identifier "action-related-table-feature-property"; + uses ofaction:actions-grouping; + } + augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" { + ext:augment-identifier "oxm-related-table-feature-property"; + uses oxm:match-entries-grouping; + } + augment "/ofproto:table-features-properties-container/ofproto:table-feature-properties" { + ext:augment-identifier "experimenter-id-table-feature-property"; + leaf experimenter { + type oft:experimenter-id; + } + leaf exp-type { + type uint32; + } + } + +// OFP_INSTRUCTION AUGMENTS + augment "/ofinstruction:instruction-container/ofinstruction:instruction-choice" { + case experimenter-id-case { + container experimenter { + leaf experimenter-id { + type oft:experimenter-id; + } + } + } + } + +// OFP_QUEUE_PROP AUGMENTS + augment "/ofproto:queue-prop-container/ofproto:queue-property" { + ext:augment-identifier "rate-queue-property"; + leaf rate { + type uint16; + } + } + augment "/ofproto:queue-prop-container/ofproto:queue-property" { + ext:augment-identifier "experimenter-id-queue-property"; + leaf experimenter { + type oft:experimenter-id; + } + } + +// OFP_ERROR_AUGMENTS (only experimenter till OpenFlow v1.3) + augment "/ofproto:error-message" { + ext:augment-identifier "experimenter-id-error"; + leaf experimenter { + type oft:experimenter-id; + } + } + +// 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; + } + } + } +} diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-configuration.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-configuration.yang new file mode 100644 index 0000000000..790a151b6b --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-configuration.yang @@ -0,0 +1,59 @@ +/* + * 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 + */ + + module openflow-configuration { + namespace "urn:opendaylight:openflow:config"; + prefix "of-config"; + + revision "2014-06-30" { + description "Library configuration classes"; + } + + typedef path-type { + type enumeration { + enum CLASSPATH { + value 0; + description "Keystore file is located on classpath."; + } + enum PATH { + value 1; + description "Keystore file is located on absolute or relative path."; + } + } + } + + typedef keystore-type { + type enumeration { + enum JKS { + value 0; + description "Keystore type - JKS."; + } + enum PKCS12 { + value 1; + description "Keystore type - PKCS12."; + } + } + } + + typedef transport-protocol { + type enumeration { + enum TCP { + value 0; + description "Communication over TCP protocol."; + } + enum TLS { + value 1; + description "Communication over TLS protocol."; + } + enum UDP { + value 2; + description "Communication over UDP protocol."; + } + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang new file mode 100644 index 0000000000..f1f9e9b93d --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-extensible-match.yang @@ -0,0 +1,662 @@ +/* + * 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 + */ + + module openflow-extensible-match { + namespace "urn:opendaylight:openflow:oxm"; + prefix "oxm"; + + import ietf-yang-types {prefix yang;} + import ietf-inet-types {prefix inet;} + import openflow-types {prefix oft;} + + revision "2015-02-25" { + description "#NOT_PUBLISHED# OpenFlow 1.3 - match model"; + } + + identity oxm-match-type { + description + "The OpenFlow Extensible Match type must be supported by all OpenFlow + switches."; + base oft:match-type-base; + } + + // oxm classes + identity oxm-class-base { + description "Base identity for OXM classes"; + } + + identity nxm-0-class { + description "Match class for backward compatibility with NXM"; + base oxm-class-base; + } + identity nxm-1-class { + description "Match class for backward compatibility with NXM"; + base oxm-class-base; + } + identity openflow-basic-class { + description "Basic class for OpenFlow"; + base oxm-class-base; + } + identity experimenter-class { + description + "Marks Experimenter match type class. + All experimenter match classes MUST use this class as a base."; + base oxm-class-base; + } + + // match-field types + identity match-field { + description "Base identity for OXM Fields"; + } + + identity in_port { + base match-field; + description "OXM field for Switch input port."; + } + identity in_phy_port { + base match-field; + description "OXM field for Switch physical input port."; + } + identity metadata { + base match-field; + description "OXM field for Metadata passed between tables."; + } + identity eth_dst { + base match-field; + description "OXM field for Ethernet destination address."; + } + identity eth_src { + base match-field; + description "OXM field for Ethernet source address."; + } + identity eth_type { + base match-field; + description "OXM field for Ethernet frame type."; + } + identity vlan_vid { + base match-field; + description "OXM field for VLAN id."; + } + identity vlan_pcp { + base match-field; + description "OXM field for VLAN priority."; + } + identity ip_dscp { + base match-field; + description "OXM field for IP DSCP (6 bits in ToS field)."; + } + identity ip_ecn { + base match-field; + description "OXM field for IP ECN (2 bits in ToS field)."; + } + identity ip_proto { + base match-field; + description "OXM field for IP protocol."; + } + identity ipv4_src { + base match-field; + description "OXM field for IPv4 source address."; + } + identity ipv4_dst { + base match-field; + description "OXM field for IPv4 destination address."; + } + identity tcp_src { + base match-field; + description "OXM field for TCP source port."; + } + identity tcp_dst { + base match-field; + description "OXM field for TCP destination port."; + } + identity udp_src { + base match-field; + description "OXM field for UDP source port."; + } + identity udp_dst { + base match-field; + description "OXM field for UDP destination port."; + } + identity sctp_src { + base match-field; + description "OXM field for SCTP source port."; + } + identity sctp_dst { + base match-field; + description "OXM field for SCTP destination port."; + } + identity icmpv4_type { + base match-field; + description "OXM field for ICMP type."; + } + identity icmpv4_code { + base match-field; + description "OXM field for ICMP code."; + } + identity arp_op { + base match-field; + description "OXM field for ARP opcode."; + } + identity arp_spa { + base match-field; + description "OXM field for ARP source IPv4 address."; + } + identity arp_tpa { + base match-field; + description "OXM field for ARP target IPv4 address."; + } + identity arp_sha { + base match-field; + description "OXM field for ARP source hardware address."; + } + identity arp_tha { + base match-field; + description "OXM field for ARP target hardware address."; + } + identity ipv6_src { + base match-field; + description "OXM field for IPv6 source address."; + } + identity ipv6_dst { + base match-field; + description "OXM field for IPv6 destination address."; + } + identity ipv6_flabel { + base match-field; + description "OXM field for IPv6 Flow Label"; + } + identity icmpv6_type { + base match-field; + description "OXM field for ICMPv6 type."; + } + identity icmpv6_code { + base match-field; + description "OXM field for ICMPv6 code."; + } + identity ipv6_nd_target { + base match-field; + description "OXM field for Target address for ND."; + } + identity ipv6_nd_sll { + base match-field; + description "OXM field for Source link-layer for ND."; + } + identity ipv6_nd_tll { + base match-field; + description "OXM field for Target link-layer for ND."; + } + identity mpls_label { + base match-field; + description "OXM field for MPLS label."; + } + identity mpls_tc { + base match-field; + description "OXM field for MPLS TC."; + } + identity mpls_bos { + base match-field; + description "OXM field for MPLS BoS bit."; + } + identity pbb_isid { + base match-field; + description "OXM field for PBB I-SID."; + } + identity tunnel_id { + base match-field; + description "OXM field for Logical Port Metadata"; + } + identity ipv6_exthdr { + base match-field; + description "OXM field for IPv6 Extension Header pseudo-field"; + } + + grouping match-grouping { + container match { + description "Match structure (OF v1.3)"; + leaf type { + type identityref { + base oft:match-type-base; + } + } + uses match-entries-grouping; + } + } + + grouping match-entries-grouping { + list match-entry { + config false; + uses match-entry-fields-grouping; + uses match-entry-value-grouping; + } + } + + grouping match-entry-fields-grouping { + leaf oxm-class { + type identityref { + base oxm-class-base; + } + } + leaf oxm-match-field { + type identityref { + base match-field; + } + } + leaf has-mask { + type boolean; + } + } + + container oxm-container { + uses match-entry-value-grouping; + } + + grouping match-entry-value-grouping { + choice match-entry-value { + case in-port-case { + container in-port { + leaf port-number { + type oft:port-number; + } + } + } + case in-phy-port-case { + container in-phy-port { + leaf port-number { + type oft:port-number; + } + } + } + case metadata-case { + container metadata { + leaf metadata { + type binary; + } + leaf mask { + type binary; + } + } + } + case eth-src-case { + container eth-src { + leaf mac-address { + type yang:mac-address; + } + leaf mask { + type binary; + } + } + } + case eth-dst-case { + container eth-dst { + leaf mac-address { + type yang:mac-address; + } + leaf mask { + type binary; + } + } + } + case eth-type-case { + container eth-type { + leaf eth-type { + type oft:ether-type; + } + } + } + case vlan-vid-case { + container vlan-vid { + leaf vlan-vid { + type uint16; + } + leaf cfi-bit { + type boolean; + } + leaf mask { + type binary; + } + } + } + case vlan-pcp-case { + container vlan-pcp { + leaf vlan-pcp { + type uint8; + } + } + } + case ip-dscp-case { + container ip-dscp { + leaf dscp { + type inet:dscp; + } + } + } + case ip-ecn-case { + container ip-ecn { + leaf ecn { + type uint8; + } + } + } + case ip-proto-case { + container ip-proto { + leaf protocol-number { + type uint8; + } + } + } + case ipv4-src-case { + container ipv4-src { + leaf ipv4-address { + type inet:ipv4-address; + } + leaf mask { + type binary; + } + } + } + case ipv4-dst-case { + container ipv4-dst { + leaf ipv4-address { + type inet:ipv4-address; + } + leaf mask { + type binary; + } + } + } + case tcp-src-case { + container tcp-src { + leaf port { + type inet:port-number; + } + } + } + case tcp-dst-case { + container tcp-dst { + leaf port { + type inet:port-number; + } + } + } + case udp-src-case { + container udp-src { + leaf port { + type inet:port-number; + } + } + } + case udp-dst-case { + container udp-dst { + leaf port { + type inet:port-number; + } + } + } + case sctp-src-case { + container sctp-src { + leaf port { + type inet:port-number; + } + } + } + case sctp-dst-case { + container sctp-dst { + leaf port { + type inet:port-number; + } + } + } + case icmpv4-type-case { + container icmpv4-type { + leaf icmpv4-type { + type uint8; + } + } + } + case icmpv4-code-case { + container icmpv4-code { + leaf icmpv4-code { + type uint8; + } + } + } + case arp-op-case { + container arp-op { + leaf op-code { + type uint16; + } + } + } + case arp-spa-case { + container arp-spa { + leaf ipv4-address { + type inet:ipv4-address; + } + leaf mask { + type binary; + } + } + } + case arp-tpa-case { + container arp-tpa { + leaf ipv4-address { + type inet:ipv4-address; + } + leaf mask { + type binary; + } + } + } + case arp-sha-case { + container arp-sha { + leaf mac-address { + type yang:mac-address; + } + leaf mask { + type binary; + } + } + } + case arp-tha-case { + container arp-tha { + leaf mac-address { + type yang:mac-address; + } + leaf mask { + type binary; + } + } + } + case ipv6-src-case { + container ipv6-src { + leaf ipv6-address { + type inet:ipv6-address; + } + leaf mask { + type binary; + } + } + } + case ipv6-dst-case { + container ipv6-dst { + leaf ipv6-address { + type inet:ipv6-address; + } + leaf mask { + type binary; + } + } + } + case ipv6-flabel-case { + container ipv6-flabel { + leaf ipv6-flabel { + type inet:ipv6-flow-label; + } + leaf mask { + type binary; + } + } + } + case icmpv6-type-case { + container icmpv6-type { + leaf icmpv6-type { + type uint8; + } + } + } + case icmpv6-code-case { + container icmpv6-code { + leaf icmpv6-code { + type uint8; + } + } + } + case ipv6-nd-target-case { + container ipv6-nd-target { + leaf ipv6-address { + type inet:ipv6-address; + } + } + } + case ipv6-nd-sll-case { + container ipv6-nd-sll { + leaf mac-address { + type yang:mac-address; + } + } + } + case ipv6-nd-tll-case { + container ipv6-nd-tll { + leaf mac-address { + type yang:mac-address; + } + } + } + case mpls-label-case { + container mpls-label { + leaf mpls-label { + type uint32; + } + } + } + case mpls-tc-case { + container mpls-tc { + leaf tc { + type uint8; + } + } + } + case mpls-bos-case { + container mpls-bos { + leaf bos { + type boolean; + } + } + } + case pbb-isid-case { + container pbb-isid { + leaf isid { + type uint32; + } + leaf mask { + type binary; + } + } + } + case tunnel-id-case { + container tunnel-id { + leaf tunnel-id { + type binary; + } + leaf mask { + type binary; + } + } + } + case ipv6-exthdr-case { + container ipv6-exthdr { + leaf pseudo-field { + type oft:ipv6-exthdr-flags; + } + leaf mask { + type binary; + } + } + } + } + } + + // OF1.0 structures + grouping match-v10-grouping { + container match-v10 { + description "OF v1.0 match structure"; + leaf wildcards { + description "Wildcard fields (only flags)."; + type oft:flow-wildcards-v10; + } + leaf nw-src-mask { + description "IP source address mask (definition differs from OF v1.0.0 spec to ease + understanding, library does the transformation into OF v1.0 spec correct data)"; + type uint8; + } + leaf nw-dst-mask { + description "IP destination address mask (definition differs from OF v1.0.0 spec to ease + understanding, library does the transformation into OF v1.0 spec correct data)"; + type uint8; + } + leaf in-port { + description "Input switch port."; + type uint16; + } + leaf dl-src { + description "Ethernet source address."; + type yang:mac-address; + } + leaf dl-dst { + description "Ethernet destination address."; + type yang:mac-address; + } + leaf dl-vlan { + description "Input VLAN id."; + type uint16; + } + leaf dl-vlan-pcp { + description "Input VLAN priority."; + type uint8; + } + leaf dl-type { + description "Ethernet frame type."; + type uint16; + } + leaf nw-tos { + description "IP ToS (actually DSCP field, 6 bits)."; + type uint8; + } + leaf nw-proto { + description "IP protocol or lower 8 bits of ARP opcode."; + type uint8; + } + leaf nw-src { + description "IP source address."; + type inet:ipv4-address; + } + leaf nw-dst { + description "IP destination address."; + type inet:ipv4-address; + } + leaf tp-src { + description "TCP/UDP source port."; + type uint16; + } + leaf tp-dst { + description "TCP/UDP destination port."; + type uint16; + } + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-instruction.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-instruction.yang new file mode 100644 index 0000000000..b9e515b3a2 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-instruction.yang @@ -0,0 +1,75 @@ +/* + * 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 + */ + + module openflow-instruction { + namespace "urn:opendaylight:openflow:common:instruction"; + prefix "ofinstruction"; + + import openflow-types { prefix oft; } + import openflow-action {prefix ofaction;} + + revision "2013-07-31" { + description "#NOT_PUBLISHED# OpenFlow 1.3 - instruction model"; + } + + container instruction-container { + uses instruction-grouping; + } + + grouping instructions-grouping { + list instruction { + config false; + uses instruction-grouping; + leaf experimenter-id { + type oft:experimenter-id; + } + } + } + + grouping instruction-grouping { + choice instruction-choice { + case goto-table-case { + container goto-table { + leaf table-id { + type uint8; + } + } + } + case write-metadata-case { + container write-metadata { + leaf metadata { + type binary; + } + leaf metadata-mask { + type binary; + } + } + } + case write-actions-case { + container write-actions { + uses ofaction:actions-grouping; + } + } + case apply-actions-case { + container apply-actions { + uses ofaction:actions-grouping; + } + } + case clear-actions-case { + // empty instruction + } + case meter-case { + container meter { + leaf meter-id { + type uint32; + } + } + } + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-protocol.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-protocol.yang new file mode 100644 index 0000000000..7e42a2b9bf --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-protocol.yang @@ -0,0 +1,1438 @@ +/* + * 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 + */ + + module openflow-protocol { + namespace "urn:opendaylight:openflow:protocol"; + prefix "ofproto"; + + import ietf-yang-types {prefix yang;} + + import openflow-types {prefix oft;} + import openflow-extensible-match { prefix oxm;} + import openflow-instruction { prefix ofinstruction;} + import openflow-action {prefix ofaction;} + + revision "2013-07-31" { + description "#NOT_PUBLISHED# OpenFlow 1.3 - protocol objects model"; + } + + // Generic Structures + grouping port-grouping { + reference "ofp_port"; + leaf port-no { + type uint32; + } + leaf hw-addr { + type yang:mac-address; + } + leaf name { + type string; + } + leaf config { + description "Bitmap of OFPPC_* flags."; + type oft:port-config; + } + leaf state { + description "Bitmap of OFPPS_* flags."; + type oft:port-state; + } + leaf current-features { + description "Current features."; + type oft:port-features; + } + leaf advertised-features { + description "Features being advertised by the port."; + type oft:port-features; + } + leaf supported-features { + description "Features supported by the port."; + type oft:port-features; + } + leaf peer-features { + description "Features advertised by peer."; + type oft:port-features; + } + leaf curr-speed { + description "Current port bitrate in kbps."; + type uint32; + units "kbps"; + } + leaf max-speed { + description "Max port bitrate in kbps"; + type uint32; + units "kbps"; + } + + // OF1.0 structures + leaf config-v10 { + type oft:port-config-v10; + } + leaf state-v10 { + type oft:port-state-v10; + } + leaf current-features-v10 { + description "Current features."; + type oft:port-features-v10; + } + leaf advertised-features-v10 { + description "Features being advertised by the port."; + type oft:port-features-v10; + } + leaf supported-features-v10 { + description "Features supported by the port."; + type oft:port-features-v10; + } + leaf peer-features-v10 { + description "Features advertised by peer."; + type oft:port-features-v10; + } + } + + grouping buckets-grouping { + list buckets-list { + uses bucket-grouping; + } + } + + grouping bucket-grouping { + description "Bucket for use in groups."; + leaf weight { + description "Relative weight of bucket. Only + defined for select groups."; + type uint16; + } + leaf watch-port { + description "Port whose state affects whether this + bucket is live. Only required for fast + failover groups."; + type oft:port-number; + } + leaf watch-group { + description "Group whose state affects whether this + bucket is live. Only required for fast + failover groups."; + type uint32; + } + + uses ofaction:actions-grouping; + } + + container table-features-properties-container { + uses table-features-properties-grouping; + } + + grouping table-features-properties-grouping { + list table-feature-properties { + config false; + leaf type { + type oft:table-features-prop-type; + } + } + } + + // # MESSAGE Structures + /* Immutable messages. */ + grouping ofHeader { + reference "ofp_header struct in Openflow Switch 1.3 Spec"; + leaf version { + type uint8; + description "OpenFlow version"; + } + leaf xid { + type uint32; + description "Transaction ID"; + } + } + grouping ofHelloElementHeader { + reference "ofpt_hello_elem_header struct in Openflow Switch 1.3 Spec"; + leaf type { + type oft:hello-element-type; + //reference "OpenFlow Header element type - OFPHET_*"; + } + } + grouping hello { + reference "OFPT_HELLO message in Openflow Switch 1.3 Spec"; + /* Symmetric message */ + uses ofHeader; + + list elements { + uses ofHelloElementHeader; + + leaf-list version-bitmap { + type boolean; + } + } + } + grouping error { + reference "OFPT_ERROR message in Openflow Switch 1.3 Spec"; + /* Symmetric message */ + uses ofHeader; + + leaf type { + type uint16; + } + leaf code { + type uint16; + } + leaf type-string { + type string; + } + leaf code-string { + type string; + } + leaf data { + type binary; + } + } + grouping echo-request { + reference "OFPT_ECHO_REQUEST message in Openflow Switch 1.3 Spec"; + /* Symmetric message */ + uses ofHeader; + + leaf data { + type binary; + } + } + grouping echo-reply { + reference "OFPT_ECHO_REPLY message in Openflow Switch 1.3 Spec"; + /* Symmetric message */ + uses ofHeader; + + leaf data { + type binary; + } + } + + 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"; + /* Controller/switch message */ + uses ofHeader; + } + grouping features-reply { + reference "OFPT_FEATURES_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + uses ofHeader; + + leaf datapathId { + type uint64; + } + leaf buffers { + type uint32; + } + leaf tables { + type uint8; + } + leaf auxiliaryId { + type uint8; + } + leaf capabilities { + type oft:capabilities; + } + leaf reserved { + type uint32; + } + // OF1.0 structures + leaf capabilities-v10 { + type oft:capabilities-v10; + } + leaf actions-v10 { + type oft:action-type-v10; + } + list phy-port { + uses port-grouping; + } + } + grouping get-config-request { + reference "OFPT_GET_CONFIG_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + uses ofHeader; + } + grouping get-config-reply { + reference "OFPT_GET_CONFIG_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + uses ofHeader; + + leaf flags { + type oft:switch-config-flag; + } + leaf miss-send-len { + type uint16; + } + } + grouping set-config { + reference "OFPT_SET_CONFIG message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf flags { + type oft:switch-config-flag; + } + leaf miss-send-len { + type uint16; + } + } + /* Asynchronous messages. */ + grouping packet-in { + reference "OFPT_PACKET_IN message in Openflow Switch 1.3 Spec"; + /* Async message */ + + uses ofHeader; + + leaf buffer-id { + // ID assigned by datapath. + type uint32; + } + leaf total-len { + // Full length of frame. + type uint16; + } + leaf reason { + // Reason packet is being sent (one of OFPR_*) + type oft:packet-in-reason; + } + leaf table-id { + // ID of the table that was looked up + type oft:table-id; + } + leaf cookie { + // Cookie of the flow entry that was looked up. + type uint64; + } + uses oxm:match-grouping; + + leaf data { + type binary; + } + + // OF1.0 structures + leaf in-port { + type uint16; + } + } + grouping flow-removed { + reference "OFPT_FLOW_REMOVED message in Openflow Switch 1.3 Spec"; + /* Async message */ + uses ofHeader; + + leaf cookie { + type uint64; + } + leaf priority { + type uint16; + } + leaf reason { + type oft:flow-removed-reason; + } + leaf table-id { + type oft:table-id; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + leaf idle-timeout { + type uint16; + } + leaf hard-timeout { + type uint16; + } + leaf packet-count { + type uint64; + } + leaf byte-count { + type uint64; + } + uses oxm:match-grouping; + + // OF1.0 structures + uses oxm:match-v10-grouping; + } + grouping port-status { + reference "OFPT_PORT_STATUS message in Openflow Switch 1.3 Spec"; + + uses ofHeader; + + uses port-grouping; + + leaf reason { + type oft:port-reason; + } + } + /* Controller command messages. */ + grouping packet-out { + reference "OFPT_PACKET_OUT message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + uses ofaction:actions-grouping; + leaf data { + type binary; + } + leaf buffer-id { + type uint32; + } + leaf in-port { + type oft:port-number; + } + } + grouping flow-mod { + reference "OFPT_FLOW_MOD message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf cookie { + type uint64; + } + leaf cookie-mask { + type uint64; + } + leaf table-id { + type oft:table-id; + } + leaf command { + type oft:flow-mod-command; + } + leaf idle-timeout { + type uint16; + } + leaf hard-timeout { + type uint16; + } + leaf priority { + type uint16; + } + leaf buffer-id { + type uint32; + } + leaf out-port { + type oft:port-number; + } + leaf out-group { + type uint32; + } + leaf flags { + type oft:flow-mod-flags; + } + uses oxm:match-grouping; + + uses ofinstruction:instructions-grouping; + + // OF1.0 structures + leaf flags-v10 { + type oft:flow-mod-flags-v10; + } + uses oxm:match-v10-grouping; + uses ofaction:actions-grouping; + } + grouping group-mod { + reference "OFPT_GROUP_MOD message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf command { + type oft:group-mod-command; + } + leaf type { + type oft:group-type; + } + leaf group-id { + type oft:group-id; + } + + uses buckets-grouping; + } + + grouping port-mod { + reference "OFPT_PORT_MOD message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf port-no { + type oft:port-number; + } + leaf hw-address { + type yang:mac-address; + } + leaf config { + type oft:port-config; + } + leaf mask { + type oft:port-config; + } + leaf advertise { + type oft:port-features; + } + // OF1.0 structures + leaf config-v10 { + type oft:port-config-v10; + } + leaf mask-v10 { + type oft:port-config-v10; + } + leaf advertise-v10 { + type oft:port-features-v10; + } + } + grouping table-mod { + reference "OFPT_TABLE_MOD message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf table-id { + type oft:table-id; + } + leaf config { + type oft:table-config; + } + } + + /* Multipart messages. */ + grouping multipart-request { + reference "OFPT_MULTIPART_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf type { + type oft:multipart-type; + } + leaf flags { + type oft:multipart-request-flags; + } + choice multipart-request-body { + case multipart-request-desc-case { + container multipart-request-desc { + leaf empty { + type empty; + } + } + } + case multipart-request-flow-case { + container multipart-request-flow { + leaf table-id { + type uint8; + } + leaf out-port { + type uint32; + } + leaf out-group { + type uint32; + } + leaf cookie { + type uint64; + } + leaf cookie-mask { + type uint64; + } + uses oxm:match-grouping; + + // OF1.0 structures + uses oxm:match-v10-grouping; + } + } + case multipart-request-aggregate-case { + container multipart-request-aggregate { + leaf table-id { + type uint8; + } + leaf out-port { + type uint32; + } + leaf out-group { + type uint32; + } + leaf cookie { + type uint64; + } + leaf cookie-mask { + type uint64; + } + uses oxm:match-grouping; + + // OF1.0 structures + uses oxm:match-v10-grouping; + } + } + case multipart-request-table-case { + container multipart-request-table { + leaf empty { + type empty; + } + } + } + case multipart-request-port-stats-case { + container multipart-request-port-stats { + leaf port-no { + type uint32; + } + } + } + case multipart-request-queue-case { + container multipart-request-queue { + leaf port-no { + type uint32; + } + leaf queue-id { + type uint32; + } + } + } + case multipart-request-group-case { + container multipart-request-group { + leaf group-id { + type oft:group-id; + } + } + } + case multipart-request-group-desc-case { + container multipart-request-group-desc { + leaf empty { + type empty; + } + } + } + case multipart-request-group-features-case { + container multipart-request-group-features { + leaf empty { + type empty; + } + } + } + case multipart-request-meter-case { + container multipart-request-meter { + leaf meter-id { + type oft:meter-id; + } + } + } + case multipart-request-meter-config-case { + container multipart-request-meter-config { + leaf meter-id { + type oft:meter-id; + } + } + } + case multipart-request-meter-features-case { + container multipart-request-meter-features { + leaf empty { + type empty; + } + } + } + case multipart-request-table-features-case { + container multipart-request-table-features { + list table-features { + leaf table-id { + type uint8; + } + leaf name { + type string; + } + leaf metadata-match { + type uint64; + } + leaf metadata-write { + type uint64; + } + leaf config { + type oft:table-config; + } + leaf max-entries { + type uint32; + } + uses table-features-properties-grouping; + } + } + } + case multipart-request-port-desc-case { + container multipart-request-port-desc { + leaf empty { + type empty; + } + } + } + case multipart-request-experimenter-case { + container multipart-request-experimenter { + uses experimenter-core; + } + } + } + } + grouping multipart-reply { + reference "OFPT_MULTIPART_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf type { + type oft:multipart-type; + } + leaf flags { + type oft:multipart-request-flags; + } + choice multipart-reply-body { + case multipart-reply-desc-case { + container multipart-reply-desc { + leaf mfr_desc { + type string; + } + leaf hw_desc { + type string; + } + leaf sw_desc { + type string; + } + leaf serial_num { + type string; + } + leaf dp_desc { + type string; + } + } + } + case multipart-reply-flow-case { + container multipart-reply-flow { + list flow-stats { + leaf table-id { + type uint8; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + leaf priority { + type uint16; + } + leaf idle-timeout { + type uint16; + } + leaf hard-timeout { + type uint16; + } + leaf flags { + type oft:flow-mod-flags; + } + leaf cookie { + type uint64; + } + leaf packet-count { + type uint64; + } + leaf byte-count { + type uint64; + } + uses oxm:match-grouping; + + uses ofinstruction:instructions-grouping; + + // OF1.0 structures + uses oxm:match-v10-grouping; + uses ofaction:actions-grouping; + } + } + } + case multipart-reply-aggregate-case { + container multipart-reply-aggregate { + leaf packet-count { + type uint64; + } + leaf byte-count { + type uint64; + } + leaf flow-count { + type uint32; + } + } + } + case multipart-reply-table-case { + container multipart-reply-table { + list table-stats { + leaf table-id { + type uint8; + } + leaf active-count { + type uint32; + } + leaf lookup-count { + type uint64; + } + leaf matched-count { + type uint64; + } + + // OF1.0 structures + leaf name { + type string; + } + leaf wildcards { + type oft:flow-wildcards-v10; + } + leaf nw-src-mask { + type uint8; + } + leaf nw-dst-mask { + type uint8; + } + leaf max-entries { + type uint32; + } + } + } + } + case multipart-reply-port-stats-case { + container multipart-reply-port-stats { + list port-stats { + leaf port-no { + type uint32; + } + leaf rx-packets { + type uint64; + } + leaf tx-packets { + type uint64; + } + leaf rx-bytes { + type uint64; + } + leaf tx-bytes { + type uint64; + } + leaf rx-dropped { + type uint64; + } + leaf tx-dropped { + type uint64; + } + leaf rx-errors { + type uint64; + } + leaf tx-errors { + type uint64; + } + leaf rx-frame-err { + type uint64; + } + leaf rx-over-err { + type uint64; + } + leaf rx-crc-err { + type uint64; + } + leaf collisions { + type uint64; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + } + } + } + case multipart-reply-queue-case { + container multipart-reply-queue { + list queue-stats { + leaf port-no { + type uint32; + } + leaf queue-id { + type uint32; + } + leaf tx-bytes { + type uint64; + } + leaf tx-packets { + type uint64; + } + leaf tx-errors { + type uint64; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + } + } + } + case multipart-reply-group-case { + container multipart-reply-group { + list group-stats { + leaf group-id { + type oft:group-id; + } + leaf ref-count { + type uint32; + } + leaf packet-count { + type uint64; + } + leaf byte-count { + type uint64; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + list bucket-stats { + leaf packet-count { + type uint64; + } + leaf byte-count { + type uint64; + } + } + } + } + } + case multipart-reply-group-desc-case { + container multipart-reply-group-desc { + list group-desc { + leaf type { + type oft:group-type; + } + leaf group-id { + type oft:group-id; + } + uses buckets-grouping; + } + } + } + case multipart-reply-group-features-case { + container multipart-reply-group-features { + leaf types { + type oft:group-types; + } + leaf capabilities { + type oft:group-capabilities; + } + leaf-list max_groups { + type uint32; + } + leaf-list actions-bitmap { + type oft:action-type; + } + } + } + case multipart-reply-meter-case { + container multipart-reply-meter { + list meter-stats { + leaf meter-id { + type oft:meter-id; + } + leaf flow-count { + type uint32; + } + leaf packet-in-count { + type uint64; + } + leaf byte-in-count { + type uint64; + } + leaf duration-sec { + type uint32; + } + leaf duration-nsec { + type uint32; + } + list meter-band-stats { + leaf packet-band-count { + type uint64; + } + leaf byte-band-count { + type uint64; + } + } + } + } + } + case multipart-reply-meter-config-case { + container multipart-reply-meter-config { + list meter-config { + leaf flags { + type oft:meter-flags; + } + leaf meter-id { + type oft:meter-id; + } + list bands { + uses meter-band-header; + } + } + } + } + case multipart-reply-meter-features-case { + container multipart-reply-meter-features { + leaf max-meter { + type uint32; + } + leaf band-types { + type oft:meter-band-type-bitmap; + } + leaf capabilities { + type oft:meter-flags; + } + leaf max-bands { + type uint8; + } + leaf max-color { + type uint8; + } + } + } + case multipart-reply-table-features-case { + container multipart-reply-table-features { + list table-features { + leaf table-id { + type uint8; + } + leaf name { + type string; + } + leaf metadata-match { + type binary; + } + leaf metadata-write { + type binary; + } + leaf config { + type oft:table-config; + } + leaf max-entries { + type uint32; + } + uses table-features-properties-grouping; + } + } + } + case multipart-reply-port-desc-case { + container multipart-reply-port-desc { + list ports { + uses port-grouping; + } + } + } + case multipart-reply-experimenter-case { + container multipart-reply-experimenter { + uses experimenter-core; + } + } + } + } + /* Barrier messages. */ + grouping barrier-request { + reference "OFPT_BARRIER_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + uses ofHeader; + } + grouping barrier-reply { + reference "OFPT_BARRIER_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + uses ofHeader; + } + /* Queue Configuration messages. */ + grouping queue-get-config-request { + reference "OFPT_QUEUE_GET_CONFIG_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf port { + type oft:port-number; + } + } + grouping queue-get-config-reply { + reference "OFPT_QUEUE_GET_CONFIG_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf port { + type oft:port-number; + } + list queues { + uses packet-queue; + } + } + grouping packet-queue { + leaf queue-id { + type oft:queue-id; + } + leaf port { + type oft:port-number; + } + uses queue-property-header; + } + container queue-prop-container { + uses queue-property-header; + } + grouping queue-property-header { + list queue-property { + config false; + leaf property { + type oft:queue-properties; + } + } + } + /* Controller role change request messages. */ + grouping role-request { + reference "OFPT_ROLE_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf role { + type oft:controller-role; + } + leaf generation-id { + type uint64; + } + } + grouping role-reply { + reference "OFPT_ROLE_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf role { + type oft:controller-role; + } + leaf generation-id { + type uint64; + } + } + /* Asynchronous message configuration. */ + grouping get-async-request { + reference "OFPT_GET_ASYNC_REQUEST message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + } + grouping get-async-reply { + reference "OFPT_GET_ASYNC_REPLY message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + uses async-body-grouping; + } + grouping set-async { + reference "OFPT_SET_ASYNC message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + uses async-body-grouping; + } + + grouping async-body-grouping { + list packet-in-mask { + leaf-list mask { + type oft:packet-in-reason; + } + } + list port-status-mask { + leaf-list mask { + type oft:port-reason; + } + } + list flow-removed-mask { + leaf-list mask { + type oft:flow-removed-reason; + } + } + } + /* Meters and rate limiters configuration messages. */ + grouping meter-mod { + reference "OFPT_METER_MOD message in Openflow Switch 1.3 Spec"; + /* Controller/switch message */ + + uses ofHeader; + + leaf command { + type oft:meter-mod-command; + } + leaf flags { + type oft:meter-flags; + } + leaf meter-id { + type oft:meter-id; + } + list bands { + uses meter-band-header; + } + } + + container meter-band-container { + uses meter-band-header; + } + grouping meter-band-header { + choice meter-band { + case meter-band-drop-case { + container meter-band-drop { + uses meter-band-commons; + } + } + case meter-band-dscp-remark-case { + container meter-band-dscp-remark { + uses meter-band-commons; + leaf prec-level { + type uint8; + } + } + } + case meter-band-experimenter-case { + container meter-band-experimenter { + uses meter-band-commons; + } + } + } + } + + grouping meter-band-commons { + leaf type { + type oft:meter-band-type; + } + leaf rate { + type uint32; + } + leaf burst-size { + type uint32; + } + } + + /* Immutable messages. */ + notification hello-message { + uses hello; + reference "OFPT_HELLO message in Openflow Switch 1.3 Spec"; + + /* Symmetric message */ + } + notification error-message { + uses error; + reference "OFPT_ERROR message in Openflow Switch 1.3 Spec"; + + /* Symmetric message */ + } + notification echo-request-message { + uses echo-request; + reference "OFPT_ECHO_REQUEST message in Openflow Switch 1.3 Spec"; + + /* Symmetric message */ + } + notification experimenter-message { + 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 */ + } + // # Notification and RPCs + /* Symmetric RPC. */ + rpc echo { + input { + uses echo-request; + } + /* Controller/switch message */ + output { + uses echo-reply; + } + } + + rpc echo-reply { + input { + uses echo-reply; + } + } + + rpc hello { + input { + uses hello; + } + } + + rpc experimenter { + description "Send experimenter message to device, reply is not solicitated."; + input { + uses experimenter-of-message; + } + } + + /* Switch configuration messages. */ + rpc get-features { + input { + uses features-request; + } + /* Controller/switch message */ + output { + uses features-reply; + } + } + + rpc get-config { + input { + uses get-config-request; + } + output { + uses get-config-reply; + } + /* Controller/switch message */ + } + + rpc set-config { + input { + uses set-config; + } + /* Controller/switch message */ + } + /* Asynchronous messages. */ + notification packet-in-message { + uses packet-in; + + /* Async message */ + } + notification flow-removed-message { + uses flow-removed; + + /* Async message */ + } + notification port-status-message { + uses port-status; + + } /* Async message */ + + /* Controller command messages. */ + rpc packet-out { + input { + uses packet-out; + } + /* Controller/switch message */ + } + rpc flow-mod { + input { + uses flow-mod; + } + /* Controller/switch message */ + } + rpc group-mod { + input { + uses group-mod; + } + /* Controller/switch message */ + } + rpc port-mod { + input { + uses port-mod; + } + } /* Controller/switch message */ + + rpc table-mod { + input { + uses table-mod; + } + } /* Controller/switch message */ + + /* Multipart messages. */ + + rpc multipart-request { + input { + uses multipart-request; + } + } + + /* Controller/switch message */ + notification multipart-reply-message { + uses multipart-reply; + // notification because of multiple following responses + } /* Controller/switch message */ + + + /* Barrier messages. */ + rpc barrier { + input { + uses barrier-request; + } + output { + uses barrier-reply; + } + } + /* Queue Configuration messages. */ + rpc get-queue-config { + input { + uses queue-get-config-request; + } + output { + uses queue-get-config-reply; + } + } + + /* Controller role change request messages. */ + rpc role-request { + input { + uses role-request; + } + output { + uses role-reply; + } + } /* Controller/switch message */ + + /* Asynchronous message configuration. */ + rpc get-async { + input { + uses get-async-request; + } + output { + uses get-async-reply; + } + } + /* Controller/switch message */ + rpc set-async { + input { + uses set-async; + } + + } + /* Meters and rate limiters configuration messages. */ + rpc meter-mod { + input { + uses meter-mod; + } + } /* Controller/switch message */ +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/main/yang/openflow-types.yang b/openflowjava/openflow-protocol-api/src/main/yang/openflow-types.yang new file mode 100755 index 0000000000..7d11bafa87 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/openflow-types.yang @@ -0,0 +1,1933 @@ +/* + * 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 + */ + + module openflow-types { + namespace "urn:opendaylight:openflow:common:types"; + prefix "oft"; + + revision "2013-07-31" { + description "#NOT_PUBLISHED# OpenFlow 1.3 - common types model"; + } + + typedef port-number { + description "Port numbering. Ports are numbered starting from 1 - + supports special / reserved values (in OF v1.3)"; + type uint32; + } + + typedef port-number-values { + description "Reserved OpenFlow Port (fake output \"ports\") (OF v1.3)."; + type enumeration { + enum MAX { + description "Maximum number of physical and logical switch ports."; + value -256; // 0xffffff00 + } + enum IN_PORT { + description "Send the packet out the input port. This + reserved port must be explicitly used + in order to send back out of the input + port."; + value -8; // 0xfffffff8 + } + enum TABLE { + description "Submit the packet to the first flow table + NB: This destination port can only be + used in packet-out messages."; + value -7; // 0xfffffff9 + } + enum NORMAL { + description "Process with normal L2/L3 switching."; + value -6; // 0xfffffffa + } + enum FLOOD { + description "All physical ports in VLAN, except input + port and those blocked or link down."; + value -5; // 0xfffffffb + } + enum ALL { + description "All physical ports except input port."; + value -4; // 0xfffffffc + } + enum CONTROLLER { + description "Send to controller."; + value -3; // 0xfffffffd + } + enum LOCAL { + description "Local openflow \"port\"."; + value -2; // 0xfffffffe + } + enum ANY { + description "Wildcard port used only for flow mod + (delete) and flow stats requests. Selects + all flows regardless of output port + (including flows with no output port)."; + value -1; // 0xffffffff + } + } + } + + typedef port-features { + description "Features of ports available in datapath."; + type bits { + bit _10mb_hd { + position 0; + description "10 Mb half-duplex rate support."; + } + bit _10mb-fd { + position 1; + description "10 Mb full-duplex rate support."; + } + bit _100mb-hd { + position 2; + description "100 Mb half-duplex rate support."; + } + bit _100mb-fd { + position 3; + description "100 Mb full-duplex rate support."; + } + bit _1gb-hd { + position 4; + description "1 Gb half-duplex rate support."; + } + bit _1gb-fd { + position 5; + description "1 Gb full-duplex rate support."; + } + bit _10gb-fd { + position 6; + description "10 Gb full-duplex rate support."; + } + bit _40gb-fd { + position 7; + description "40 Gb full-duplex rate support."; + } + bit _100gb-fd { + position 8; + description "100 Gb full-duplex rate support."; + } + bit _1tb-fd { + position 9; + description "1 Tb full-duplex rate support."; + } + bit other { + position 10; + description "Other rate, not in the list."; + } + bit copper { + position 11; + description "Copper medium."; + } + bit fiber { + position 12; + description "Fiber medium."; + } + bit autoneg { + position 13; + description "Auto-negotiation."; + } + bit pause { + position 14; + description "Pause."; + } + bit pause-asym { + position 15; + description "Asymmetric pause."; + } + } + } + + typedef port-config { + description + "Flags to indicate behavior of the physical port. These flags are + describe the current configuration and used port_mod message + to configure the port's behavior."; + type bits { + bit port-down { + //description " Port is administratively down."; + position 0; + } + bit no-recv { + //description " Drop all packets received by port."; + position 2; + } + bit no-fwd { + //description " Drop packets forwarded to port."; + position 5; + } + bit no-packet-in { + //description "Do not send packet-in msgs for port."; + position 6; + } + } + } + + typedef port-state { + description + "Current state of the physical port. These are not configurable from + the controller."; + type bits { + bit link_down { + //description "No physical link present."; + position 0; + } + bit blocked { + //description "Port is blocked"; + position 1; + } + bit live { + //description "Live for Fast Failover Group."; + position 2; + } + } + } + + identity match-type-base { + description + "The match type indicates the match structure (set of fields that compose the + match) in use. The match type is placed in the type field at the beginning + of all match structures.Extensions that define match types may be + published on the ONF wiki. Support for extensions is optional."; + } + + identity standard-match-type { + base oft:match-type-base; + } + + identity instruction-base { + description "Base identity for instruction types"; + } + + identity action-base { + 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; + } + + typedef table-id { + type uint32; + } + typedef meter-id { + type uint32; + } + typedef queue-id { + type uint32; + } + typedef group-id { + type uint32; + } + + typedef ether-type { + type uint16; + } + typedef experimenter-id { + description "This type represents experimenter ID used in experimenter messages. + It also represents vendor ID - as it is the same for OF version 1.3+. + (VENDOR naming convention has been changed in OF v1.3 specification + to EXPERIMENTER)"; + type uint32; + } + typedef error-type { + type enumeration { + enum HELLO_FAILED { + value 0; + description "Hello Protocol failed."; + } + enum BAD_REQUEST { + value 1; + description "Request was not understood."; + } + enum BAD_ACTION { + value 2; + description "Error in action description."; + } + enum BAD_INSTRUCTION { + value 3; + description "Error in instruction list."; + } + enum BAD_MATCH { + value 4; + description "Error in match."; + } + enum FLOW_MOD_FAILED { + value 5; + description "Problem modifying flow entry."; + } + enum GROUP_MOD_FAILED { + value 6; + description "Problem modifying group entry."; + } + enum PORT_MOD_FAILED { + value 7; + description "Port mod request failed."; + } + enum TABLE_MOD_FAILED { + value 8; + description "Table mod request failed."; + } + enum QUEUE_OP_FAILED { + value 9; + description "Queue operation failed."; + } + enum SWITCH_CONFIG_FAILED { + value 10; + description "Switch config request failed."; + } + enum ROLE_REQUEST_FAILED { + value 11; + description "Controller Role request failed."; + } + enum METER_MOD_FAILED { + value 12; + description "Error in meter."; + } + enum TABLE_FEATURES_FAILED { + value 13; + description "Setting table features failed."; + } + enum EXPERIMENTER { + value 65535; //0xffff + description "Experimenter error messages."; + } + } + } + + typedef hello-failed-code { + type enumeration { + enum INCOMPATIBLE { + value 0; + description "Hello Protocol failed."; + } + enum EPERM { + value 1; + description "Request was not understood."; + } + } + } + + typedef bad-request-code { + type enumeration { + enum BAD_VERSION { + value 0; + } + enum BAD_TYPE { + value 1; + } + enum BAD_MULTIPART { + value 2; + } + enum BAD_EXPERIMENTER { + value 3; + } + enum BAD_EXP_TYPE { + value 4; + } + enum EPERM { + value 5; + } + enum BAD_LEN { + value 6; + } + enum BUFFER_EMPTY { + value 7; + } + enum BUFFER_UNKNOWN { + value 8; + } + enum BAD_TABLE_ID { + value 9; + } + enum IS_SLAVE { + value 10; + } + enum BAD_PORT { + value 11; + } + enum BAD_PACKET { + value 12; + } + enum MULTIPART_BUFFER_OVERFLOW { + value 13; + } + } + } + + typedef bad-action-code { + type enumeration { + enum BAD_TYPE { + value 0; + } + enum BAD_LEN { + value 1; + } + enum BAD_EXPERIMENTER { + value 2; + } + enum BAD_EXP_TYPE { + value 3; + } + enum BAD_OUT_PORT { + value 4; + } + enum BAD_ARGUMENT { + value 5; + } + enum EPERM { + value 6; + } + enum TOO_MANY { + value 7; + } + enum BAD_QUEUE { + value 8; + } + enum BAD_OUT_GROUP { + value 9; + } + enum MATCH_INCONSISTENT { + value 10; + } + enum UNSUPPORTED_ORDER { + value 11; + } + enum BAD_TAG { + value 12; + } + enum BAD_SET_TYPE { + value 13; + } + enum BAD_SET_LEN { + value 14; + } + enum BAD_SET_ARGUMENT { + value 15; + } + } + } + + typedef bad-instruction-code { + type enumeration { + enum UNKNOWN_INST { + value 0; + } + enum UNSUP_INST { + value 1; + } + enum BAD_TABLE_ID { + value 2; + } + enum UNSUP_METADATA { + value 3; + } + enum UNSUP_METADATA_MASK { + value 4; + } + enum BAD_EXPERIMENTER { + value 5; + } + enum BAD_EXP_TYPE { + value 6; + } + enum BAD_LEN { + value 7; + } + enum EPERM { + value 8; + } + } + } + + typedef bad-match-code { + type enumeration { + enum BAD_TYPE { + value 0; + } + enum BAD_LEN { + value 1; + } + enum BAD_TAG { + value 2; + } + enum BAD_DL_ADDR_MASK { + value 3; + } + enum BAD_NW_ADDR_MASK { + value 4; + } + enum BAD_WILDCARDS { + value 5; + } + enum BAD_FIELD { + value 6; + } + enum BAD_VALUE { + value 7; + } + enum BAD_MASK { + value 8; + } + enum BAD_PREREQ { + value 9; + } + enum DUP_FIELD { + value 10; + } + enum EPERM { + value 11; + } + } + } + + typedef flow-mod-failed-code { + type enumeration { + enum UNKNOWN { + value 0; + } + enum TABLE_FULL { + value 1; + } + enum BAD_TABLE_ID { + value 2; + } + enum OVERLAP { + value 3; + } + enum EPERM { + value 4; + } + enum BAD_TIMEOUT { + value 5; + } + enum BAD_COMMAND { + value 6; + } + enum BAD_FLAGS { + value 7; + } + } + } + + typedef group-mod-failed-code { + type enumeration { + enum GROUP_EXISTS { + value 0; + } + enum INVALID_GROUP { + value 1; + } + enum WEIGHT_UNSUPPORTED { + value 2; + } + enum OUT_OF_GROUPS { + value 3; + } + enum OUT_OF_BUCKETS { + value 4; + } + enum CHAINING_UNSUPPORTED { + value 5; + } + enum WATCH_UNSUPPORTED { + value 6; + } + enum LOOP { + value 7; + } + enum UNKNOWN_GROUP { + value 8; + } + enum CHAINED_GROUP { + value 9; + } + enum BAD_TYPE { + value 10; + } + enum BAD_COMMAND { + value 11; + } + enum BAD_BUCKET { + value 12; + } + enum BAD_WATCH { + value 13; + } + enum EPERM { + value 14; + } + } + } + + typedef port-mod-failed-code { + type enumeration { + enum BAD_PORT { + value 0; + } + enum BAD_HW_ADDR { + value 1; + } + enum BAD_CONFIG { + value 2; + } + enum BAD_ADVERTISE { + value 3; + } + enum EPERM { + value 4; + } + } + } + + typedef table-mod-failed-code { + type enumeration { + enum BAD_TABLE { + value 0; + } + enum BAD_CONFIG { + value 1; + } + enum EPERM { + value 2; + } + } + } + + typedef queue-op-failed-code { + type enumeration { + enum BAD_PORT { + value 0; + } + enum BAD_QUEUE { + value 1; + } + enum EPERM { + value 2; + } + } + } + + typedef switch-config-failed-code { + type enumeration { + enum BAD_FLAGS { + value 0; + } + enum BAD_LEN { + value 1; + } + enum EPERM { + value 2; + } + } + } + + typedef role-request-failed-code { + type enumeration { + enum STALE { + value 0; + } + enum UNSUP { + value 1; + } + enum BAD_ROLE { + value 2; + } + } + } + + typedef meter-mod-failed-code { + type enumeration { + enum UNKNOWN { + value 0; + } + enum METER_EXISTS { + value 1; + } + enum INVALID_METER { + value 2; + } + enum UNKNOWN_METER { + value 3; + } + enum BAD_COMMAND { + value 4; + } + enum BAD_FLAGS { + value 5; + } + enum BAD_RATE { + value 6; + } + enum BAD_BURST { + value 7; + } + enum BAD_BAND { + value 8; + } + enum BAD_BAND_VALUE { + value 9; + } + enum OUT_OF_METERS { + value 10; + } + enum OUT_OF_BANDS { + value 11; + } + } + } + + typedef table-features-failed-code { + type enumeration { + enum BAD_TABLE { + value 0; + } + enum BAD_METADATA { + value 1; + } + enum BAD_TYPE { + value 2; + } + enum BAD_LEN { + value 3; + } + enum BAD_ARGUMENT { + value 4; + } + enum EPERM { + value 5; + } + } + } + + typedef hello-element-type { + type enumeration { + enum VERSIONBITMAP { + value 1; + description "Bitmap of version supported."; + } + } + } + + typedef capabilities { + description "Capabilities supported by the datapath."; + type bits { + bit OFPC_FLOW_STATS { + position 0; + /* Flow statistics. */ + } + bit OFPC_TABLE_STATS { + position 1; + /* Table statistics. */ + } + bit OFPC_PORT_STATS { + position 2; + /* Port statistics. */ + } + bit OFPC_GROUP_STATS { + position 3; + /* Group statistics. */ + } + bit OFPC_IP_REASM { + position 5; + /* Can reassemble IP fragments. */ + } + bit OFPC_QUEUE_STATS { + position 6; + /* Queue statistics. */ + } + bit OFPC_PORT_BLOCKED { + position 8; + /* Switch will block looping ports. */ + } + } + } + + typedef switch-config-flag { + description " Handling of IP fragments. "; + type enumeration { + enum FRAG_NORMAL { + value 0; + description "No special handling for fragments."; + } + enum OFPC_FRAG_DROP { + value 1; + description "Drop fragments."; + } + enum OFPC_FRAG_REASM { + value 2; + description "Reassemble (only if OFPC_IP_REASM set)."; + } + enum OFPC_FRAG_MASK { + value 3; + } + } + } + + typedef flow-removed-reason { + description "Why was this flow removed?"; + type enumeration { + enum OFPRR_IDLE_TIMEOUT { + value 0; + description "Flow idle time exceeded idle_timeout."; + } + enum OFPRR_HARD_TIMEOUT { + value 1; + description "Time exceeded hard_timeout."; + } + enum OFPRR_DELETE { + value 2; + description "Evicted by a DELETE flow mod."; + } + enum OFPRR_GROUP_DELETE { + value 3; + description "Group was removed."; + } + } + } + + typedef port-reason { + description "What changed about the physical port"; + type enumeration { + enum OFPPR_ADD { + value 0; + description "The port was added."; + } + enum OFPPR_DELETE { + value 1; + description "he port was removed."; + } + enum OFPPR_MODIFY { + value 2; + description "Some attribute of the port has changed."; + } + } + } + + typedef flow-mod-command { + /* ofp_flow_mod_command */ + type enumeration { + enum OFPFC_ADD { + value 0; + description "New flow."; + } + enum OFPFC_MODIFY { + value 1; + description "Modify all matching flows."; + } + enum OFPFC_MODIFY_STRICT { + value 2; + description "Modify entry strictly matching wildcards and priority."; + } + enum OFPFC_DELETE { + value 3; + description "Delete all matching flows."; + } + enum OFPFC_DELETE_STRICT { + value 4; + description "Delete entry strictly matching wildcards and priority."; + } + } + } + + typedef flow-mod-flags { + /* ofp_flow_mod_flags */ + type bits { + bit OFPFF_SEND_FLOW_REM { + position 0; + description "Send flow removed message when flow expires or is deleted."; + } + bit OFPFF_CHECK_OVERLAP { + position 1; + description "Check for overlapping entries first."; + } + bit OFPFF_RESET_COUNTS { + position 2; + description "Reset flow packet and byte counts."; + } + bit OFPFF_NO_PKT_COUNTS { + position 3; + description "Don't keep track of packet count."; + } + bit OFPFF_NO_BYT_COUNTS { + position 4; + description "Don't keep track of byte count."; + } + } + } + + typedef group-mod-command { + /* ofp_group_mod_command */ + type enumeration { + enum OFPGC_ADD { + value 0; + description "New group."; + } + enum OFPGC_MODIFY { + value 1; + description "Modify all matching groups."; + } + enum OFPGC_DELETE { + value 2; + description "Delete all matching groups."; + } + } + } + + typedef group-type { + /* ofp_group_type */ + type enumeration { + enum OFPGT_ALL { + value 0; + description "All (multicast/broadcast) group."; + } + enum OFPGT_SELECT { + value 1; + description "Select group."; + } + enum OFPGT_INDIRECT { + value 2; + description "Indirect group."; + } + enum OFPGT_FF { + value 3; + description "Fast failover group."; + } + } + } + + typedef table-values { + /* ofp_table */ + type enumeration { + enum OFPTT_MAX { + value 254; // 0xfe + description "Last usable table number."; + } + enum OFPTT_ALL { + value 255; // 0xff + description "Wildcard table used for table config, + flow stats and flow deletes."; + } + } + } + + typedef group { + /* ofp_group - Group numbering. Groups can use any number up to OFPG_MAX.*/ + type enumeration { + enum OFPG_MAX { + value -256; //0xffffff00 + description "Last usable group number"; + } + /* Fake groups. */ + enum OFPG_ALL { + value -4; //0xfffffffc + description "Represents all groups for group delete commands"; + } + enum OFPG_ANY { + value -1; //0xffffffff + description "Wildcard group used only for flow stats requests. + Selects all flows regardless of group (including flows with no group)"; + } + } + } + + typedef multipart-request-flags { + description "enum ofp_multipart_request_flags "; + type bits { + bit OFPMPF_REQ_MORE { + description "More requests to follow."; + position 0; + } + } + } + + typedef multipart-type { + type enumeration { + enum OFPMP_DESC { + value 0; + description "Description of this OpenFlow switch. + The request body is empty. + The reply body is struct ofp_desc."; + } + enum OFPMP_FLOW { + value 1; + description "Individual flow statistics. + The request body is struct ofp_flow_stats_request. + The reply body is an array of struct ofp_flow_stats."; + } + enum OFPMP_AGGREGATE { + value 2; + description "Aggregate flow statistics. + The request body is struct ofp_aggregate_stats_request. + The reply body is struct ofp_aggregate_stats_reply."; + } + enum OFPMP_TABLE { + value 3; + description "Flow table statistics. + The request body is empty. + The reply body is an array of struct ofp_table_stats."; + } + enum OFPMP_PORT_STATS { + value 4; + description "Port statistics. + The request body is struct ofp_port_stats_request. + The reply body is an array of struct ofp_port_stats."; + } + enum OFPMP_QUEUE { + value 5; + description "Queue statistics for a port + The request body is struct ofp_queue_stats_request. + The reply body is an array of struct ofp_queue_stats"; + } + enum OFPMP_GROUP { + value 6; + description "Group counter statistics. + The request body is struct ofp_group_stats_request. + The reply is an array of struct ofp_group_stats."; + } + enum OFPMP_GROUP_DESC { + value 7; + description "Group description. + The request body is empty. + The reply body is an array of struct ofp_group_desc."; + } + enum OFPMP_GROUP_FEATURES { + value 8; + description "Group features. + The request body is empty. + The reply body is struct ofp_group_features."; + } + enum OFPMP_METER { + value 9; + description "Meter statistics. + The request body is struct ofp_meter_multipart_requests. + The reply body is an array of struct ofp_meter_stats."; + } + enum OFPMP_METER_CONFIG { + value 10; + description "Meter configuration. + The request body is struct ofp_meter_multipart_requests. + The reply body is an array of struct ofp_meter_config."; + } + enum OFPMP_METER_FEATURES { + value 11; + description "Meter features. + The request body is empty. + The reply body is struct ofp_meter_features."; + } + enum OFPMP_TABLE_FEATURES { + value 12; + description "Table features. + The request body is either empty or contains an array of + struct ofp_table_features containing the controller’s + desired view of the switch. If the switch is unable to + set the specified view an error is returned. + The reply body is an array of struct ofp_table_features."; + } + enum OFPMP_PORT_DESC { + value 13; + description "Port description. + The request body is empty. + The reply body is an array of struct ofp_port."; + } + enum OFPMP_EXPERIMENTER { + value 65535; //0xffff + description "Experimenter extension. + The request and reply bodies begin with + struct ofp_experimenter_multipart_header. + The request and reply bodies are otherwise experimenter-defined."; + } + } + } + + typedef queue-properties { + /* ofp_queue_properties */ + type enumeration { + enum OFPQT_NONE { + value 0; + description "No property defined for queue (default)."; + } + enum OFPQT_MIN_RATE { + value 1; + description "Minimum datarate guaranteed."; + } + enum OFPQT_MAX_RATE { + value 2; + description "Maximum datarate."; + } + enum OFPQT_EXPERIMENTER { + value 65535; // 0xffff + description "Experimenter defined property."; + } + } + } + + typedef controller-role { + /* ofp_controller_role */ + type enumeration { + enum OFPCR_ROLE_NOCHANGE { + value 0; + description "Don’t change current role."; + } + enum OFPCR_ROLE_EQUAL { + value 1; + description "Default role, full access."; + } + enum OFPCR_ROLE_MASTER { + value 2; + description "Full access, at most one master."; + } + enum OFPCR_ROLE_SLAVE { + value 3; + description "Read-only access."; + } + } + } + + typedef packet-in-reason { + /* ofp_packet_in_reason */ + type enumeration { + enum OFPR_NO_MATCH { + value 0; + description "No matching flow (table-miss flow entry). "; + } + enum OFPR_ACTION { + value 1; + description "Action explicitly output to controller. "; + } + enum OFPR_INVALID_TTL { + value 2; + description "Packet has invalid TTL "; + } + } + } + + typedef action-type { + /* ofp_action_type */ + type bits { + bit OFPAT_OUTPUT { + position 0; + /* Output to switch port. */ + } + bit OFPAT_COPY_TTL_OUT { + position 1; + /* Copy TTL "outwards" -- from next-to-outermost to outermost */ + } + bit OFPAT_COPY_TTL_IN { + position 2; + /* Copy TTL "inwards" -- from outermost to next-to-outermost */ + } + bit OFPAT_SET_MPLS_TTL { + position 3; + /* MPLS TTL */ + } + bit OFPAT_DEC_MPLS_TTL { + position 4; + /* Decrement MPLS TTL */ + } + bit OFPAT_PUSH_VLAN { + position 5; + /* Push a new VLAN tag */ + } + bit OFPAT_POP_VLAN { + position 6; + /* Pop the outer VLAN tag */ + } + bit OFPAT_PUSH_MPLS { + position 7; + /* Push a new MPLS tag */ + } + bit OFPAT_POP_MPLS { + position 8; + /* Pop the outer MPLS tag */ + } + bit OFPAT_SET_QUEUE { + position 9; + /* Set queue id when outputting to a port */ + } + bit OFPAT_GROUP { + position 10; + /* Apply group. */ + } + bit OFPAT_SET_NW_TTL { + position 11; + /* IP TTL. */ + } + bit OFPAT_DEC_NW_TTL { + position 12; + /* Decrement IP TTL. */ + } + bit OFPAT_SET_FIELD { + position 13; + /* Set a header field using OXM TLV format. */ + } + bit OFPAT_PUSH_PBB { + position 14; + /* Push a new PBB service tag (I-TAG) */ + } + bit OFPAT_POP_PBB { + position 15; + /* Pop the outer PBB service tag (I-TAG) */ + } + bit OFPAT_EXPERIMENTER { + position 16; + } + } + } + + typedef meter-mod-command { + /* ofp_meter_mod_command */ + type enumeration { + enum OFPMC_ADD { + description "New meter. "; + } + enum OFPMC_MODIFY { + description "Modify specified meter. "; + } + enum OFPMC_DELETE { + description "Delete specified meter. "; + } + } + } + + typedef meter-flags { + /* ofp_meter_flags */ + type bits { + bit OFPMF_KBPS { + position 0; + /* Rate value in kb/s (kilo-bit per second). */ + } + bit OFPMF_PKTPS { + position 1; + /* Rate value in packet/sec. */ + } + bit OFPMF_BURST { + position 2; + /* Do burst size. */ + } + bit OFPMF_STATS { + position 3; + /* Collect statistics. */ + } + } + } + + typedef meter-band-type { + /* ofp_meter_band_type */ + type enumeration { + enum OFPMBT_DROP { + value 1; + description "Drop packet. "; + } + enum OFPMBT_DSCP_REMARK { + value 2; + description "Remark DSCP in the IP header. "; + } + enum OFPMBT_EXPERIMENTER { + value 65535; //0xFFFF + description "Experimenter meter band. "; + } + } + } + + typedef meter-band-type-bitmap { + /* ofp_meter_band_type */ + type bits { + bit OFPMBT_DROP { + position 1; + description "Drop packet. "; + } + bit OFPMBT_DSCP_REMARK { + position 2; + description "Remark DSCP in the IP header. "; + } + } + } + + typedef meter { + description "Meter numbering. Flow meters can use any number up to OFPM_MAX"; + type enumeration { + enum OFPM_MAX { + value -65536; //0xffff0000 + description "Last usable meter number"; + } + /* Virtual meters. */ + enum OFPM_SLOWPATH { + value -3; //0xfffffffd + description "Meter for slow datapath"; + } + enum OFPM_CONTROLLER { + value -2; //0xfffffffe + description "Meter for controller connection"; + } + enum OFPM_ALL { + value -1; //0xffffffff + description "Represents all meters for stat requests commands"; + } + } + } + + typedef table-config { + /* ofp_table_config */ + type bits { + bit OFPTC_DEPRECATED_MASK { + /* Deprecated bits */ + position 3; + } + } + } + + typedef table-features-prop-type { + type enumeration { + enum OFPTFPT_INSTRUCTIONS { + value 0; + description "Instructions property."; + } + enum OFPTFPT_INSTRUCTIONS_MISS { + value 1; + description "Instructions for table-miss."; + } + enum OFPTFPT_NEXT_TABLES { + value 2; + description "Next Table property."; + } + enum OFPTFPT_NEXT_TABLES_MISS { + value 3; + description "Next Table for table-miss."; + } + enum OFPTFPT_WRITE_ACTIONS { + value 4; + description "Write Actions property."; + } + enum OFPTFPT_WRITE_ACTIONS_MISS { + value 5; + description "Write Actions for table-miss."; + } + enum OFPTFPT_APPLY_ACTIONS { + value 6; + description "Apply Actions property."; + } + enum OFPTFPT_APPLY_ACTIONS_MISS { + value 7; + description "Apply Actions for table-miss."; + } + enum OFPTFPT_MATCH { + value 8; + description "Match property."; + } + enum OFPTFPT_WILDCARDS { + value 10; + description "Wildcards property."; + } + enum OFPTFPT_WRITE_SETFIELD { + value 12; + description "Write Set-Field property."; + } + enum OFPTFPT_WRITE_SETFIELD_MISS { + value 13; + description "Write Set-Field for table-miss."; + } + enum OFPTFPT_APPLY_SETFIELD { + value 14; + description "Apply Set-Field property."; + } + enum OFPTFPT_APPLY_SETFIELD_MISS { + value 15; + description "Apply Set-Field for table-miss."; + } + enum OFPTFPT_EXPERIMENTER { + value 65534; + description "Experimenter property."; + } + enum OFPTFPT_EXPERIMENTER_MISS { + value 65535; //0xffff + description "Experimenter for table-miss."; + } + } + } + + typedef group-types { + /* ofp_group_type */ + type bits { + bit OFPGT_ALL { + description "All (multicast/broadcast) group."; + position 0; + } + bit OFPGT_SELECT { + description "Select group."; + position 1; + } + bit OFPGT_INDIRECT { + description "Indirect group."; + position 2; + } + bit OFPGT_FF { + description "Fast failover group."; + position 3; + } + } + } + + typedef group-capabilities { + /* ofp_group_capabilities */ + type bits { + bit OFPGFC_SELECT_WEIGHT { + description "Support weight for select groups"; + position 0; + } + bit OFPGFC_SELECT_LIVENESS { + description "Support liveness for select groups"; + position 1; + } + bit OFPGFC_CHAINING { + description "Support chaining group"; + position 2; + } + bit OFPGFC_CHAINING_CHECKS { + description "Check chaining for loops and delete"; + position 3; + } + } + } + + typedef ipv6-exthdr-flags { + description "Bit definitions for IPv6 Extension Header pseudo-field."; + type bits { + bit nonext { + description " encountered."; + position 0; + } + bit esp { + description "Encrypted Sec Payload header present."; + position 1; + } + bit auth { + description "Authentication header present."; + position 2; + } + bit dest { + description "1 or 2 dest headers present."; + position 3; + } + bit frag { + description "Fragment header present."; + position 4; + } + bit router { + description "Router header present."; + position 5; + } + bit hop { + description "Hop-by-hop header present."; + position 6; + } + bit unrep { + description "Unexpected repeats encountered."; + position 7; + } + bit unseq { + description "Unexpected sequencing encountered."; + position 8; + } + } + } + +// OPENFLOW v1.0 STRUCTURES + // Structures under this line are needed to support OpenFlow version 1.0 + // wire protocol 0x01; + + typedef error-type-v10 { + type enumeration { + enum HELLO_FAILED { + value 0; + description "Hello Protocol failed."; + } + enum BAD_REQUEST { + value 1; + description "Request was not understood."; + } + enum BAD_ACTION { + value 2; + description "Error in action description."; + } + enum FLOW_MOD_FAILED { + value 3; + description "Problem modifying flow entry."; + } + enum PORT_MOD_FAILED { + value 4; + description "Port mod request failed."; + } + enum QUEUE_OP_FAILED { + value 5; + description "Queue operation failed."; + } + } + } + + typedef hello-failed-code-v10 { + type enumeration { + enum INCOMPATIBLE { + value 0; + description "Hello Protocol failed."; + } + enum EPERM { + value 1; + description "Request was not understood."; + } + } + } + + typedef bad-request-code-v10 { + type enumeration { + enum BAD_VERSION { + value 0; + } + enum BAD_TYPE { + value 1; + } + enum BAD_STAT { + value 2; + } + enum BAD_VENDOR { + value 3; + } + enum BAD_SUBTYPE { + value 4; + } + enum EPERM { + value 5; + } + enum BAD_LEN { + value 6; + } + enum BUFFER_EMPTY { + value 7; + } + enum BUFFER_UNKNOWN { + value 8; + } + } + } + + typedef bad-action-code-v10 { + type enumeration { + enum BAD_TYPE { + value 0; + } + enum BAD_LEN { + value 1; + } + enum VENDOR { + value 2; + } + enum BAD_VENDOR_TYPE { + value 3; + } + enum BAD_OUT_PORT { + value 4; + } + enum BAD_ARGUMENT { + value 5; + } + enum EPERM { + value 6; + } + enum TOO_MANY { + value 7; + } + enum BAD_QUEUE { + value 8; + } + } + } + + typedef flow-mod-failed-code-v10 { + type enumeration { + enum ALL_TABLES_FULL { + value 0; + } + enum OVERLAP { + value 1; + } + enum EPERM { + value 2; + } + enum BAD_EMERG_TIMEOUT { + value 3; + } + enum BAD_COMMAND { + value 4; + } + enum UNSUPPORTED { + value 5; + } + } + } + + typedef port-mod-failed-code-v10 { + type enumeration { + enum BAD_PORT { + value 0; + } + enum BAD_HW_ADDR { + value 1; + } + } + } + + typedef queue-op-failed-code-v10 { + type enumeration { + enum BAD_PORT { + value 0; + } + enum BAD_QUEUE { + value 1; + } + enum EPERM { + value 2; + } + } + } + + typedef port-number-values-v10 { + description "Port numbering. Physical ports are numbered starting from 1."; + type enumeration { + enum MAX { + value 65280; // 0xff00 + } + enum IN_PORT { + description "Send the packet out the input port. This + virtual port must be explicitly used + in order to send back out of the input + port."; + value 65528; // 0xfff8 + } + enum TABLE { + description "Perform actions in flow table. + NB: This can only be the destination + port for packet-out messages."; + value 65529; // 0xfff9 + } + enum NORMAL { + description "Process with normal L2/L3 switching."; + value 65530; // 0xfffa + } + enum FLOOD { + description "All physical ports except input port and + those disabled by STP."; + value 65531; // 0xfffb + } + enum ALL { + description "All physical ports except input port."; + value 65532; // 0xfffc + } + enum CONTROLLER { + description "Send to controller."; + value 65533; // 0xfffd + } + enum LOCAL { + description "Local openflow \"port\"."; + value 65534; // 0xfffe + } + enum NONE { + description "Not associated with a physical port."; + value 65535; // 0xffff + } + } + } + + typedef port-config-v10 { + description + "Flags to indicate behavior of the physical port. These flags are + describe the current configuration and used port_mod message + to configure the port's behavior."; + type bits { + bit port-down { + description " Port is administratively down."; + position 0; + } + bit no-stp { + description "Disable 802.1D spanning tree on port."; + position 1; + } + bit no-recv { + description " Drop all packets received by port."; + position 2; + } + bit no-recv-stp { + description " Drop received 802.1D STP packets."; + position 3; + } + bit no-flood { + description " Do not include this port when flooding."; + position 4; + } + bit no-fwd { + description " Drop packets forwarded to port."; + position 5; + } + bit no-packet-in { + description "Do not send packet-in msgs for port."; + position 6; + } + } + } + + typedef port-state-v10 { + description "Current state of the physical port. These are not configurable from + the controller."; + type bits { + bit link_down { + description "No physical link present."; + position 0; + } + bit blocked { + description "Port is blocked"; + position 1; + } + bit live { + description "Live for Fast Failover Group."; + position 2; + } + bit stp_listen { + description "Not learning or relaying frames."; + } + bit stp_learn { + description "Learning but not relaying frames."; + } + bit stp_forward { + description "Learning and relaying frames."; + } + bit stp_block { + description "Not part of spanning tree."; + } + bit stp_mask { + description "Bit mask for OFPPS_STP_* values."; + } + } + } + + typedef port-features-v10 { + description "Features of ports available in datapath."; + reference "ofp_port_features"; + type bits { + bit _10mb-hd { + position 0; + description "10 Mb half-duplex rate support."; + } + bit _10mb-fd { + position 1; + description "10 Mb full-duplex rate support."; + } + bit _100mb-hd { + position 2; + description "100 Mb half-duplex rate support."; + } + bit _100mb-fd { + position 3; + description "100 Mb full-duplex rate support."; + } + bit _1gb-hd { + position 4; + description "1 Gb half-duplex rate support."; + } + bit _1gb-fd { + position 5; + description "1 Gb full-duplex rate support."; + } + bit _10gb-fd { + position 6; + description "10 Gb full-duplex rate support."; + } + bit copper { + position 7; + description "Copper medium."; + } + bit fiber { + position 8; + description "Fiber medium."; + } + bit autoneg { + position 9; + description "Auto-negotiation."; + } + bit pause { + position 10; + description "Pause."; + } + bit pause-asym { + position 11; + description "Asymmetric pause."; + } + } + } + + typedef capabilities-v10 { + type bits { + bit OFPC_FLOW_STATS { + position 0; + description "Flow statistics."; + } + bit OFPC_TABLE_STATS { + position 1; + description "Table statistics."; + } + bit OFPC_PORT_STATS { + position 2; + description "Port statistics."; + } + bit OFPC_STP { + position 3; + description "802.1d spanning tree."; + } + bit OFPC_RESERVED { + position 4; + description "Reserved, must be zero."; + } + bit OFPC_IP_REASM { + position 5; + description "Can reassemble IP fragments."; + } + bit OFPC_QUEUE_STATS { + position 6; + description "Queue statistics."; + } + bit OFPC_ARP_MATCH_IP { + position 8; + description "Match IP addresses in ARP pkts."; + } + } + } + + typedef flow-mod-flags-v10 { + /* ofp_flow_mod_flags */ + type bits { + bit OFPFF_SEND_FLOW_REM { + position 0; + description "Send flow removed message when flow expires or is deleted."; + } + bit OFPFF_CHECK_OVERLAP { + position 1; + description "Check for overlapping entries first."; + } + bit OFPFF_EMERG { + position 2; + description "Reset flow packet and byte counts."; + } + } + } + + typedef action-type-v10 { + /* ofp_action_type */ + type bits { + bit OFPAT_OUTPUT { + position 0; + description "Output to switch port."; + } + bit OFPAT_SET_VLAN_VID { + position 1; + description "Set the 802.1q VLAN id."; + } + bit OFPAT_SET_VLAN_PCP { + position 2; + description "Set the 802.1q priority."; + } + bit OFPAT_STRIP_VLAN { + position 3; + description "Strip the 802.1q header."; + } + bit OFPAT_SET_DL_SRC { + position 4; + description "Ethernet source address."; + } + bit OFPAT_SET_DL_DST { + position 5; + description "Ethernet destination address."; + } + bit OFPAT_SET_NW_SRC { + position 6; + description "IP source address."; + } + bit OFPAT_SET_NW_DST { + position 7; + description "IP destination address."; + } + bit OFPAT_SET_NW_TOS { + position 8; + description "IP ToS (DSCP field, 6 bits)."; + } + bit OFPAT_SET_TP_SRC { + position 9; + description "TCP/UDP source port."; + } + bit OFPAT_SET_TP_DST { + position 10; + description "TCP/UDP destination port."; + } + bit OFPAT_ENQUEUE { + position 11; + description "Output to queue."; + } + bit OFPAT_VENDOR { + position 12; + description "Experimenter in later versions."; + } + } + } + + typedef flow-wildcards-v10 { + /* ofp_flow_wildcards */ + description "Flow wildcards - NW_SRC_MASK & NW_DST_MASK are handled separately"; + type bits { + bit IN_PORT { + description "Switch input port."; + position 0; + } + bit DL_VLAN { + description "VLAN id."; + position 1; + } + bit DL_SRC { + description "Ethernet source address."; + position 2; + } + bit DL_DST { + description "Ethernet destination address."; + position 3; + } + bit DL_TYPE { + description "Ethernet frame type."; + position 4; + } + bit NW_PROTO { + description "IP protocol."; + position 5; + } + bit TP_SRC { + description "TCP/UDP source port."; + position 6; + } + bit TP_DST { + description "TCP/UDP destination port."; + position 7; + } + bit DL_VLAN_PCP { + description "VLAN priority."; + position 20; + } + bit NW_TOS { + description "IP ToS (DSCP field, 6 bits)."; + position 21; + } + } + } + +} diff --git a/openflowjava/openflow-protocol-api/src/main/yang/system-notifications.yang b/openflowjava/openflow-protocol-api/src/main/yang/system-notifications.yang new file mode 100644 index 0000000000..5bd805c37c --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/main/yang/system-notifications.yang @@ -0,0 +1,31 @@ +/* + * 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 + */ + + module system-notifications { + namespace "urn:opendaylight:openflow:system"; + prefix "ofs"; + + revision "2013-09-27" { + description "#NOT_PUBLISHED# Model of system messages used in OpenFlow Protocol Library"; + } + + notification disconnect-event { + description "Disconnect notification"; + leaf info { + type string; + } + } + + notification switch-idle-event { + description "Switch-idle notification"; + leaf info { + type string; + } + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java new file mode 100644 index 0000000000..be52a18890 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/connection/TlsConfigurationImplTest.java @@ -0,0 +1,46 @@ +/* + * 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.connection; + +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 + * + */ +public class TlsConfigurationImplTest { + + /** + * Test correct TlsConfigurationImpl creation + */ + @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, 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()); + assertEquals("Wrong truststore type", KeystoreType.JKS, config.getTlsTruststoreType()); + assertEquals("Wrong keystore path type", PathType.PATH, config.getTlsKeystorePathType()); + assertEquals("Wrong truststore path type", PathType.CLASSPATH, config.getTlsTruststorePathType()); + 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/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKeyTest.java new file mode 100644 index 0000000000..6e08c1e4d4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageCodeKeyTest.java @@ -0,0 +1,74 @@ +/* + * 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.extensibility; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; + +/** + * @author michal.polkorab + * + */ +public class EnhancedMessageCodeKeyTest { + + /** + * Test EnhancedMessageCodeKey equals and hashCode + */ + @Test + public void test() { + EnhancedMessageCodeKey key1 = + new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, BarrierInput.class); + EnhancedMessageCodeKey key2 = + new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, BarrierInput.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageCodeKey(EncodeConstants.OF13_VERSION_ID, 4, 8, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, BarrierOutput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 6, 8, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 16, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test EnhancedMessageTypeKey equals - additional test + */ + @Test + public void testEquals() { + EnhancedMessageCodeKey key1 = + new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, BarrierInput.class); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + } + + /** + * Test EnhancedMessageCodeKey toString() + */ + @Test + public void testToString() { + EnhancedMessageCodeKey key1 = + new EnhancedMessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, 8, BarrierInput.class); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectClass: org.opendaylight.yang.gen.v1.urn.opendaylight" + + ".openflow.protocol.rev130731.BarrierInput msgType: 4 msgType2: 8", key1.toString()); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKeyTest.java new file mode 100644 index 0000000000..eb19e7ffd7 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/EnhancedMessageTypeKeyTest.java @@ -0,0 +1,86 @@ +/* + * 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.extensibility; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.SetFieldCase; +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; + +/** + * @author michal.polkorab + * + */ +public class EnhancedMessageTypeKeyTest { + + /** + * Test EnhancedMessageTypeKey equals and hashCode + */ + @Test + public void test() { + EnhancedMessageTypeKey key1 = + new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, OutputActionCase.class); + EnhancedMessageTypeKey key2 = + new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, OutputActionCase.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Action.class, OutputActionCase.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, null, OutputActionCase.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Instruction.class, OutputActionCase.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Action.class, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Action.class, SetFieldCase.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test EnhancedMessageTypeKey equals - additional test + */ + @Test + public void testEquals() { + EnhancedMessageTypeKey key1; + EnhancedMessageTypeKey key2; + key1 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, OutputActionCase.class); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, OutputActionCase.class); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + key1 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, null); + Assert.assertFalse("Wrong equal by msgType2.", key1.equals(key2)); + key1 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, OutputActionCase.class); + key2 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, Action.class, SetFieldCase.class); + Assert.assertFalse("Wrong equal by msgType2 class name.", key1.equals(key2)); + } + + /** + * Test EnhancedMessageTypeKey toString() + */ + @Test + public void testToString() { + EnhancedMessageTypeKey key1 = new EnhancedMessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, + Action.class, OutputActionCase.class); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectType: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.common.action.rev150203.actions.grouping.Action msgType2:" + + " org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action" + + ".grouping.action.choice.OutputActionCase", key1.toString()); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageCodeKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageCodeKeyTest.java new file mode 100644 index 0000000000..2c5b69c6e9 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageCodeKeyTest.java @@ -0,0 +1,78 @@ +/* + * 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.extensibility; + +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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; + +/** + * @author michal.polkorab + * + */ +public class MessageCodeKeyTest { + + /** + * Test MessageCodeKey equals and hashCode + */ + @Test + public void test() { + MessageCodeKey key1 = + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierInput.class); + MessageCodeKey key2 = + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierInput.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 4, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierOutput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 6, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test MessageCodeKey equals - additional test + */ + @Test + public void testEquals() { + MessageCodeKey key1 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierInput.class); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to null.", key1.equals(null)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + key1 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, null); + MessageCodeKey key2 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierInput.class); + Assert.assertFalse("Wrong equal by clazz.", key1.equals(key2)); + + key2 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, null); + Assert.assertTrue("Wrong equal by clazz.", key1.equals(key2)); + } + + /** + * Test MessageCodeKey toString() + */ + @Test + public void testToString() { + MessageCodeKey key1 = new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 4, BarrierInput.class); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectClass: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.protocol.rev130731.BarrierInput msgType: 4", key1.toString()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageTypeKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageTypeKeyTest.java new file mode 100644 index 0000000000..7a45015a52 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/extensibility/MessageTypeKeyTest.java @@ -0,0 +1,77 @@ +/* + * 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.extensibility; + +import org.junit.Assert; +import org.junit.Test; +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.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; + +/** + * @author michal.polkorab + * + */ +public class MessageTypeKeyTest { + + /** + * Test MessageTypeKey equals and hashCode + */ + @Test + public void test() { + MessageTypeKey key1 = + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class); + MessageTypeKey key2 = + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, BarrierInput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierOutput.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test MessageTypeKey equals - additional test + */ + @Test + public void testEquals() { + MessageTypeKey key1; + MessageTypeKey key2; + key1 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to null.", key1.equals(null)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + key1 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, null); + key2 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class); + Assert.assertFalse("Wrong equal by msgType.", key1.equals(key2)); + + key2 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, null); + Assert.assertTrue("Wrong equal by msgType.", key1.equals(key2)); + } + + /** + * Test MessageTypeKey toString() + */ + @Test + public void testToString() { + MessageTypeKey key1 = new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectType: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.protocol.rev130731.BarrierInput", key1.toString()); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKeyTest.java new file mode 100644 index 0000000000..84760e8b84 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionDeserializerKeyTest.java @@ -0,0 +1,70 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class ActionDeserializerKeyTest { + + /** + * Test ActionDeserializerKey equals and hashCode + */ + @Test + public void test() { + ActionDeserializerKey key1 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 42L); + ActionDeserializerKey key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 11, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ActionDeserializerKey equals - additional test + */ + @Test + public void testEquals(){ + ActionDeserializerKey key1 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + ActionDeserializerKey key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 42L); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + Assert.assertFalse("Wrong equal by experimenterId", key1.equals(key2)); + key2 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + Assert.assertTrue("Wrong equal by experimenterId", key1.equals(key2)); + } + + /** + * Test InstructionDeserializerKey toString() + */ + @Test + public void testToString(){ + ActionDeserializerKey key1 = new ActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectClass: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.common.action.rev150203.actions.grouping.Action msgType: 11" + + " experimenterID: null", key1.toString()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKeyTest.java new file mode 100644 index 0000000000..9fdde0ae6c --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/ActionSerializerKeyTest.java @@ -0,0 +1,84 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlOutCase; + +/** + * @author michal.polkorab + * + */ +public class ActionSerializerKeyTest { + + /** + * Test ActionSerializerKey equals and hashCode + */ + @Test + public void test() { + ActionSerializerKey key1 = + new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, 42L); + ActionSerializerKey key2 = + new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlOutCase.class, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new ActionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, CopyTtlInCase.class, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ActionSerializerKey equals - additional test + */ + @Test + public void testEquals(){ + ActionSerializerKey key1 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, 42L); + ActionSerializerKey key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + CopyTtlInCase.class, 42L); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal by actionType", key1.equals(key2)); + + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, 42L); + Assert.assertTrue("Wrong equal by action type", key1.equals(key2)); + key1 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, null); + Assert.assertFalse("Wrong equal by experimenterId", key1.equals(key2)); + key2 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, CopyTtlInCase.class, null); + Assert.assertTrue("Wrong equal by experimenterId", key1.equals(key2)); + } + + /** + * Test ActionSerializerKey toString() + */ + @Test + public void testToString(){ + ActionSerializerKey key1 = new ActionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, + CopyTtlInCase.class, 42L); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectType: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.common.action.rev150203.actions.grouping.Action action type:" + + " org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action" + + ".grouping.action.choice.CopyTtlInCase experimenterID: 42", key1.toString()); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKeyTest.java new file mode 100644 index 0000000000..6b501a1cf0 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionDeserializerKeyTest.java @@ -0,0 +1,70 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class InstructionDeserializerKeyTest { + + /** + * Test InstructionDeserializerKey equals and hashCode + */ + @Test + public void test() { + InstructionDeserializerKey key1 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 42L); + InstructionDeserializerKey key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 11, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test InstructionDeserializerKey equals - additional test + */ + @Test + public void testEquals(){ + InstructionDeserializerKey key1 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + InstructionDeserializerKey key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, 24L); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + Assert.assertFalse("Wrong equal by experimenterId", key1.equals(key2)); + key2 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + Assert.assertTrue("Wrong equal by experimenterId", key1.equals(key2)); + } + + /** + * Test InstructionDeserializerKey toString() + */ + @Test + public void testToString(){ + InstructionDeserializerKey key1 = new InstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 11, null); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectClass: org.opendaylight.yang.gen.v1.urn.opendaylight" + + ".openflow.common.instruction.rev130731.instructions.grouping.Instruction msgType: 11" + + " experimenterID: null", key1.toString()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKeyTest.java new file mode 100644 index 0000000000..17ecf58222 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/InstructionSerializerKeyTest.java @@ -0,0 +1,85 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCase; + +/** + * @author michal.polkorab + * + */ +public class InstructionSerializerKeyTest { + + /** + * Test InstructionSerializerKey equals and hashCode + */ + @Test + public void test() { + InstructionSerializerKey key1 = + new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 42L); + InstructionSerializerKey key2 = + new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, WriteActionsCase.class, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, ApplyActionsCase.class, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test InstructionSerializerKey equals - additional test + */ + @Test + public void testEquals(){ + InstructionSerializerKey key1 = + new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 42L); + InstructionSerializerKey key2 = + new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 42L); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + key1 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, null); + Assert.assertFalse("Wrong equal by experimenterId.", key1.equals(key2)); + + key1 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, 42L); + key2 = new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, null, 42L); + Assert.assertTrue("Wrong equal by instructionType.", key1.equals(key2)); + } + + /** + * Test InstructionSerializerKey toString() + */ + @Test + public void testToString(){ + InstructionSerializerKey key1 = + new InstructionSerializerKey<>(EncodeConstants.OF10_VERSION_ID, ApplyActionsCase.class, 42L); + + Assert.assertEquals("Wrong toString()", "msgVersion: 1 objectType: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction " + + "instructionType type: org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction" + + ".rev130731.instruction.grouping.instruction.choice.ApplyActionsCase vendorID: 42", key1.toString()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java new file mode 100644 index 0000000000..d2aefedbf5 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/KeysTest.java @@ -0,0 +1,84 @@ +/* + * 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; +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.opendaylight.openflow.augments.rev150225.action.container.action.choice.ExperimenterIdCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.ExperimenterActionSubType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; + +/** + * @author michal.polkorab + */ +public class KeysTest { + + /** + * Testing equals() and hashcode() methods of extension deserializer's keys + */ + @Test + public void testEqualsAndHashcodeOfDeserializerKeys() { + ActionDeserializerKey actionDeserializerKey = new ActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, + EncodeConstants.EXPERIMENTER_VALUE, 1L); + ExperimenterActionDeserializerKey experimenterActionDeserializerKey = new ExperimenterActionDeserializerKey( + EncodeConstants.OF13_VERSION_ID, 1L); + Assert.assertEquals(actionDeserializerKey, experimenterActionDeserializerKey); + Assert.assertEquals(actionDeserializerKey.hashCode(), experimenterActionDeserializerKey.hashCode()); + + InstructionDeserializerKey instructionDeserializerKey = new InstructionDeserializerKey( + EncodeConstants.OF13_VERSION_ID, EncodeConstants.EXPERIMENTER_VALUE, 1L); + ExperimenterInstructionDeserializerKey experimenterInstructionDeserializerKey = new ExperimenterInstructionDeserializerKey( + EncodeConstants.OF13_VERSION_ID, 1L); + Assert.assertEquals(instructionDeserializerKey, experimenterInstructionDeserializerKey); + Assert.assertEquals(instructionDeserializerKey.hashCode(), experimenterInstructionDeserializerKey.hashCode()); + + MatchEntryDeserializerKey matchKey = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_OP); + MatchEntryDeserializerKey matchKey2 = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + OxmMatchConstants.OPENFLOW_BASIC_CLASS, OxmMatchConstants.ARP_OP); + Assert.assertEquals(matchKey, matchKey2); + Assert.assertEquals(matchKey.hashCode(), matchKey2.hashCode()); + } + + /** + * Testing equals() and hashcode() methods of extension serializer's keys + */ + @Test + public void testEqualsAndHashcodeOfActionDeserializerKeys() { + ActionSerializerKey actionSerializerKey = new ActionSerializerKey<>( + EncodeConstants.OF13_VERSION_ID, ExperimenterIdCase.class, 1L); + ExperimenterActionSerializerKey experimenterActionSerializerKey = new ExperimenterActionSerializerKey( + EncodeConstants.OF13_VERSION_ID, 1L, ExpSubType.class); + Assert.assertFalse(actionSerializerKey.equals(experimenterActionSerializerKey)); + Assert.assertFalse(experimenterActionSerializerKey.equals(actionSerializerKey)); + + InstructionSerializerKey instructionSerializerKey = + new InstructionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, org.opendaylight.yang.gen.v1.urn + .opendaylight.openflow.augments.rev150225.instruction.container.instruction.choice + .ExperimenterIdCase.class, 1L); + ExperimenterInstructionSerializerKey experimenterInstructionSerializerKey = new ExperimenterInstructionSerializerKey(EncodeConstants.OF13_VERSION_ID, 1L); + Assert.assertEquals(instructionSerializerKey, experimenterInstructionSerializerKey); + Assert.assertEquals(instructionSerializerKey.hashCode(), experimenterInstructionSerializerKey.hashCode()); + + MatchEntrySerializerKey matchKey = new MatchEntrySerializerKey<>( + EncodeConstants.OF10_VERSION_ID, OpenflowBasicClass.class, InPort.class); + MatchEntrySerializerKey matchKey2 = new MatchEntrySerializerKey<>( + EncodeConstants.OF10_VERSION_ID, OpenflowBasicClass.class, InPort.class); + Assert.assertEquals(matchKey, matchKey2); + Assert.assertEquals(matchKey.hashCode(), matchKey2.hashCode()); + } + + private static class ExpSubType extends ExperimenterActionSubType { + // empty class - only used in test for comparation + } + +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKeyTest.java new file mode 100644 index 0000000000..ceefbc1b49 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntryDeserializerKeyTest.java @@ -0,0 +1,83 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class MatchEntryDeserializerKeyTest { + + /** + * Test MatchEntryDeserializerKey equals and hashCode + */ + @Test + public void test() { + MatchEntryDeserializerKey key1 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); + MatchEntryDeserializerKey key2 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0, 42); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 0); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, 0x8000, 42); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, 0x8000, 42); + key2.setExperimenterId(158L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); + key2.setExperimenterId(158L); + key1.setExperimenterId(158L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test MatchEntryDeserializerKey equals - additional test + */ + @Test + public void testEquals() { + MatchEntryDeserializerKey key1 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); + MatchEntryDeserializerKey key2 = new MatchEntryDeserializerKey(EncodeConstants.OF10_VERSION_ID, 0x8000, 42); + + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + Long expId1=123456L; + Long expId2=654321L; + key1.setExperimenterId(null); + key2.setExperimenterId(expId2); + Assert.assertFalse("Wrong equal by experimeterId.", key1.equals(key2)); + + key1.setExperimenterId(expId1); + Assert.assertFalse("Wrong equal by experimeterId.", key1.equals(key2)); + Assert.assertFalse("Wrong equals with different object class", key1.equals(key2)); + } + + /** + * Test MatchEntryDeserializerKey toString() + */ + @Test + public void testToString(){ + MatchEntryDeserializerKey key1 = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, 0x8000, 42); + + Assert.assertEquals("Wrong toString()", "msgVersion: 4 objectClass: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry" + + " msgType: 32768 oxm_field: 42 experimenterID: null", key1.toString()); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKeyTest.java new file mode 100644 index 0000000000..fbd5e26adc --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/MatchEntrySerializerKeyTest.java @@ -0,0 +1,108 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.Nxm0Class; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; + +/** + * @author michal.polkorab + * + */ +public class MatchEntrySerializerKeyTest { + + /** + * Test MatchEntrySerializerKey equals and hashCode + */ + @Test + public void test() { + MatchEntrySerializerKey key1 = new MatchEntrySerializerKey<> + (EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); + MatchEntrySerializerKey key2 = new MatchEntrySerializerKey<> + (EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + OpenflowBasicClass.class, InPhyPort.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + Nxm0Class.class, InPort.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF10_VERSION_ID, + OpenflowBasicClass.class, InPhyPort.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + OpenflowBasicClass.class, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + null, InPhyPort.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + key2.setExperimenterId(42L); + Assert.assertFalse("Wrong hashCode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test MatchEntrySerializerKey equals - additional test + */ + @Test + public void testEquals(){ + MatchEntrySerializerKey key1; + MatchEntrySerializerKey key2; + key1 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to different class.", key1.equals(new Object())); + + Long expId1 = 987654331L; + Long expId2 = 123456789L; + + key1.setExperimenterId(null); + key2.setExperimenterId(expId2); + Assert.assertFalse("Wrong equal by experimenterId", key1.equals(key2)); + key1.setExperimenterId(expId1); + Assert.assertFalse("Wrong equal by experimenterId", key1.equals(key2)); + key1 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, null, InPort.class); + key1.setExperimenterId(expId2); + Assert.assertFalse("Wrong equal by oxmClass", key1.equals(key2)); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, null, InPort.class); + key2.setExperimenterId(expId2); + Assert.assertTrue("Wrong equal by oxmClass", key1.equals(key2)); + key1 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, null); + key1.setExperimenterId(expId2); + Assert.assertFalse("Wrong equal by oxmField", key1.equals(key2)); + key2 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, null); + key2.setExperimenterId(expId2); + Assert.assertTrue("Wrong equal by oxmField", key1.equals(key2)); + } + + /** + * Test MatchEntrySerializerKey toString() + */ + @Test + public void testToString(){ + MatchEntrySerializerKey key1; + key1 = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, OpenflowBasicClass.class, InPort.class); + + Assert.assertEquals("Wrong toString()", "msgVersion: 4 objectType: org.opendaylight.yang.gen.v1.urn" + + ".opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry" + + " oxm_class: org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225" + + ".OpenflowBasicClass oxm_field: org.opendaylight.yang.gen.v1.urn.opendaylight.openflow" + + ".oxm.rev150225.InPort experimenterID: null", key1.toString()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java new file mode 100644 index 0000000000..8b6192d3be --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/TypeToClassKeyTest.java @@ -0,0 +1,38 @@ +/* + * 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; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +/** + * + * @author madamjak + * + */ +public class TypeToClassKeyTest { + + /** + * Test equals + */ + @Test + public void test(){ + final short ver10 = EncodeConstants.OF10_VERSION_ID; + final short ver13 = EncodeConstants.OF13_VERSION_ID; + final int type1 = 1; + final int type2 = 2; + TypeToClassKey typeToClsKey10 = new TypeToClassKey(ver10,type1); + Assert.assertTrue("Wrong - equals to same object", typeToClsKey10.equals(typeToClsKey10)); + Assert.assertFalse("Wrong - equals to null", typeToClsKey10.equals(null)); + Assert.assertFalse("Wrong - equals to different class", typeToClsKey10.equals(new Object())); + TypeToClassKey typeToClsKey13 = new TypeToClassKey(ver13,type2); + Assert.assertFalse("Wrong - equals by different version", typeToClsKey13.equals(new Object())); + Assert.assertFalse("Wrong - equals by different type", typeToClsKey13.equals(typeToClsKey10)); + } +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionDeserializerKeyTest.java new file mode 100644 index 0000000000..97543feabf --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionDeserializerKeyTest.java @@ -0,0 +1,43 @@ +/* + * 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.ExperimenterActionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class ExperimenterActionDeserializerKeyTest { + + /** + * Test ExperimenterActionDeserializerKey equals and hashCode + */ + @Test + public void test() { + ExperimenterActionDeserializerKey key1 = + new ExperimenterActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + ExperimenterActionDeserializerKey key2 = + new ExperimenterActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionSerializerKeyTest.java new file mode 100644 index 0000000000..e3e910cac4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterActionSerializerKeyTest.java @@ -0,0 +1,77 @@ +/* + * 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.ExperimenterActionSerializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.ExperimenterActionSubType; + +/** + * @author michal.polkorab + * + */ +public class ExperimenterActionSerializerKeyTest { + + + /** + * Test ExperimenterActionSerializerKey equals and hashCode + */ + @Test + public void test() { + ExperimenterActionSerializerKey key1 = + new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, TestSubType.class); + ExperimenterActionSerializerKey key2 = + new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, TestSubType.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF13_VERSION_ID, 42L, TestSubType.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, null, TestSubType.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 55L, TestSubType.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 55L, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 55L, TestSubType2.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ExperimenterActionSerializerKey equals + */ + @Test + public void testEquals() { + ExperimenterActionSerializerKey key1; + ExperimenterActionSerializerKey key2; + key1 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, null); + Assert.assertTrue("Wrong equal to identical object.", key1.equals(key1)); + key2 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, TestSubType2.class); + Assert.assertFalse("Wrong equal by actionSubType.", key1.equals(key2)); + key1 = new ExperimenterActionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L, TestSubType.class); + Assert.assertFalse("Wrong equal by actionSubType.", key1.equals(key2)); + } + + + private static class TestSubType extends ExperimenterActionSubType { + // empty class - only used in test for comparation + } + + private static class TestSubType2 extends ExperimenterActionSubType { + // empty class - only used in test for comparation + } + + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java new file mode 100644 index 0000000000..d7f61084c4 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdDeserializerKeyTest.java @@ -0,0 +1,68 @@ +/* + * 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.ExperimenterIdDeserializerKey; +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.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage; + +/** + * @author michal.polkorab + * + */ +public class ExperimenterIdDeserializerKeyTest { + + /** + * Test ExperimenterIdDeserializerKey equals and hashCode + */ + @Test + public void test() { + ExperimenterIdDeserializerKey key1 = + new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + ExperimenterIdDeserializerKey key2 = + new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + 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, 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); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L, ErrorMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ExperimenterIdDeserializerKey equals - additional test + */ + @Test + public void testEquals() { + ExperimenterIdDeserializerKey key1 = + 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)); + ExperimenterIdDeserializerKey key2 = + new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by experimenterId.", key1.equals(key2)); + } + +} diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java new file mode 100644 index 0000000000..a3bf789138 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdSerializerKeyTest.java @@ -0,0 +1,65 @@ +/* + * 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.MessageTypeKey; +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 ExperimenterIdSerializerKeyTest { + + /** + * Test ExperimenterIdSerializerKey equals and hashCode + */ + @Test + public void testHashCodeAndEquals() { + ExperimenterIdSerializerKey key1 = + new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + ExperimenterIdSerializerKey key2 = + new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + 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, 55L, 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, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 55L, ErrorMessage.class); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Test ExperimenterIdSerializerKey equals - additional test + */ + @Test + public void testEquals() { + ExperimenterIdSerializerKey key1 = + 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)); + ExperimenterIdSerializerKey key2 = + new ExperimenterIdSerializerKey<>(EncodeConstants.OF10_VERSION_ID, 42L, ExperimenterMessage.class); + Assert.assertFalse("Wrong equal by experimenterId.", key1.equals(key2)); + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeDeserializerKeyTest.java new file mode 100644 index 0000000000..7405b7734c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterIdTypeSerializerKeyTest.java new file mode 100644 index 0000000000..a613d0d854 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionDeserializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionDeserializerKeyTest.java new file mode 100644 index 0000000000..74f1bf96d9 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionDeserializerKeyTest.java @@ -0,0 +1,43 @@ +/* + * 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.ExperimenterInstructionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class ExperimenterInstructionDeserializerKeyTest { + + /** + * Test ExperimenterInstructionDeserializerKey equals and hashCode + */ + @Test + public void test() { + ExperimenterInstructionDeserializerKey key1 = + new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + ExperimenterInstructionDeserializerKey key2 = + new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionSerializerKeyTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionSerializerKeyTest.java new file mode 100644 index 0000000000..e7f8e35a3d --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/keys/experimenter/ExperimenterInstructionSerializerKeyTest.java @@ -0,0 +1,44 @@ +/* + * 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.ExperimenterInstructionSerializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class ExperimenterInstructionSerializerKeyTest { + + /** + * Test ExperimenterInstructionSerializerKey equals and hashCode + */ + @Test + public void test() { + ExperimenterInstructionSerializerKey key1 = + new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + ExperimenterInstructionSerializerKey key2 = + new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + Assert.assertTrue("Wrong equals", key1.equals(key2)); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionSerializerKey(EncodeConstants.OF13_VERSION_ID, 42L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID, null); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + key2 = new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID, 55L); + Assert.assertFalse("Wrong equals", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/util/BinContentTest.java b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/util/BinContentTest.java new file mode 100644 index 0000000000..3c2bc650c7 --- /dev/null +++ b/openflowjava/openflow-protocol-api/src/test/java/org/opendaylight/openflowjava/protocol/api/util/BinContentTest.java @@ -0,0 +1,63 @@ +/* + * 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.api.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author michal.polkorab + */ +public class BinContentTest { + + /** + * Testing correct conversion from signed int value to unsigned long value + */ + @Test + public void testIntToUnsignedLong() { + int a = 0; + int b = 1; + int c = -1; + int d = Integer.MAX_VALUE; + int e = Integer.MIN_VALUE; + int f = 12345; + Assert.assertEquals("Wrong conversion", 0, BinContent.intToUnsignedLong(a)); + Assert.assertEquals("Wrong conversion", 1, BinContent.intToUnsignedLong(b)); + Assert.assertEquals("Wrong conversion", 4294967295L, BinContent.intToUnsignedLong(c)); + Assert.assertEquals("Wrong conversion", Integer.MAX_VALUE, BinContent.intToUnsignedLong(d)); + Assert.assertEquals("Wrong conversion", ((long) Integer.MAX_VALUE) + 1, BinContent.intToUnsignedLong(e)); + Assert.assertEquals("Wrong conversion", 12345, BinContent.intToUnsignedLong(f)); + } + + /** + * Testing correct conversion from unsigned long value to signed int value + */ + @Test + public void testLongToSignedInt() { + long a = 0; + long b = 1; + long c = -1; + long d = Integer.MAX_VALUE; + long e = Integer.MIN_VALUE; + long f = 12345; + long g = Long.MAX_VALUE; + long h = 1094624935644L; + long i = ((long) Integer.MAX_VALUE) + 1; + Assert.assertEquals("Wrong conversion", 0, BinContent.longToSignedInt(a)); + Assert.assertEquals("Wrong conversion", 1, BinContent.longToSignedInt(b)); + Assert.assertEquals("Wrong conversion", -1, BinContent.longToSignedInt(c)); + Assert.assertEquals("Wrong conversion", Integer.MAX_VALUE, BinContent.longToSignedInt(d)); + Assert.assertEquals("Wrong conversion", Integer.MIN_VALUE, BinContent.longToSignedInt(e)); + Assert.assertEquals("Wrong conversion", 12345, BinContent.longToSignedInt(f)); + Assert.assertEquals("Wrong conversion", -1, BinContent.longToSignedInt(g)); + Assert.assertEquals("Wrong conversion", -591724836, BinContent.longToSignedInt(h)); + Assert.assertEquals("Wrong conversion", Integer.MIN_VALUE, BinContent.longToSignedInt(i)); + } + +} diff --git a/openflowjava/openflow-protocol-impl/pom.xml b/openflowjava/openflow-protocol-impl/pom.xml new file mode 100644 index 0000000000..62c2ddd3be --- /dev/null +++ b/openflowjava/openflow-protocol-impl/pom.xml @@ -0,0 +1,162 @@ + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + openflow-protocol-impl + bundle + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + org.opendaylight.openflowjava.protocol.impl.*, + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.* + + + + + + org.opendaylight.yangtools + yang-maven-plugin + + + + generate-sources + + + + + + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + + ${jmxGeneratorPath} + + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + + + + + + org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl + + ${salGeneratorPath} + + + org.opendaylight.mdsal.binding.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + ${project.build.directory}/site/models + + + true + + + + + + org.opendaylight.controller + yang-jmx-generator-plugin + ${config.version} + + + org.opendaylight.mdsal + maven-sal-api-gen-plugin + ${mdsal.model.version} + jar + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + + + + + ${project.groupId} + openflow-protocol-api + + + ${project.groupId} + openflow-protocol-spi + + + org.opendaylight.openflowjava + openflowjava-util + + + org.opendaylight.controller + sal-common-util + + + org.opendaylight.controller + sal-common-api + + + org.opendaylight.yangtools + concepts + + + + + io.netty + netty-handler + + + org.osgi + org.osgi.core + + + org.slf4j + slf4j-log4j12 + test + + + com.google.guava + guava + + + junit + junit + test + + + org.mockito + mockito-core + + + org.opendaylight.controller + config-api + + + io.netty + netty-transport-native-epoll + + linux-x86_64 + + + diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java new file mode 100644 index 0000000000..414f2c25f4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ChannelInitializerFactory.java @@ -0,0 +1,96 @@ +/* + * 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.impl.core; + +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; + +/** + * @author michal.polkorab + * + */ +public class ChannelInitializerFactory { + + private long switchIdleTimeOut; + private DeserializationFactory deserializationFactory; + private SerializationFactory serializationFactory; + private TlsConfiguration tlsConfig; + private SwitchConnectionHandler switchConnectionHandler; + private boolean useBarrier; + + /** + * @return PublishingChannelInitializer that initializes new channels + */ + public TcpChannelInitializer createPublishingChannelInitializer() { + 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; + } + + /** + * @return PublishingChannelInitializer that initializes new channels + */ + public UdpChannelInitializer createUdpChannelInitializer() { + final UdpChannelInitializer initializer = new UdpChannelInitializer(); + initializer.setSwitchIdleTimeout(switchIdleTimeOut); + initializer.setDeserializationFactory(deserializationFactory); + initializer.setSerializationFactory(serializationFactory); + initializer.setSwitchConnectionHandler(switchConnectionHandler); + return initializer; + } + + /** + * @param switchIdleTimeOut + */ + public void setSwitchIdleTimeout(final long switchIdleTimeOut) { + this.switchIdleTimeOut = switchIdleTimeOut; + } + + /** + * @param deserializationFactory + */ + public void setDeserializationFactory(final DeserializationFactory deserializationFactory) { + this.deserializationFactory = deserializationFactory; + } + + /** + * @param serializationFactory + */ + public void setSerializationFactory(final SerializationFactory serializationFactory) { + this.serializationFactory = serializationFactory; + } + + /** + * @param tlsConfig + */ + public void setTlsConfig(final TlsConfiguration tlsConfig) { + this.tlsConfig = tlsConfig; + } + + /** + * @param 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java new file mode 100644 index 0000000000..1e95c65c48 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionInitializer.java @@ -0,0 +1,24 @@ +/* + * 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; + +/** + * @author martin.uhlir + * + */ +public interface ConnectionInitializer { + + /** + * Initiates connection towards device + * @param host - host IP + * @param port - port number + */ + void initiateConnection(String host, int port); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java new file mode 100644 index 0000000000..b0fee5c3bb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandler.java @@ -0,0 +1,68 @@ +/* + * 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.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; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Holds reference to {@link ConnectionAdapterImpl} and passes messages for further processing. + * Also informs on switch disconnection. + * @author michal.polkorab + */ +public class DelegatingInboundHandler extends ChannelInboundHandlerAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(DelegatingInboundHandler.class); + private final MessageConsumer consumer; + private boolean inactiveMessageSent = false; + + /** + * Constructs class + creates and sets MessageConsumer. + * @param connectionAdapter reference for adapter communicating with upper layers outside library + */ + public DelegatingInboundHandler(final MessageConsumer connectionAdapter) { + LOG.trace("Creating DelegatingInboundHandler"); + consumer = Preconditions.checkNotNull(connectionAdapter); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, final Object msg) { + consumer.consume((DataObject) msg); + } + + @Override + public void channelInactive(final ChannelHandlerContext ctx) { + LOG.debug("Channel inactive"); + if (!inactiveMessageSent) { + DisconnectEventBuilder builder = new DisconnectEventBuilder(); + builder.setInfo("Channel inactive"); + consumer.consume(builder.build()); + inactiveMessageSent = true; + } + } + + @Override + public void channelUnregistered(final ChannelHandlerContext ctx) { + LOG.debug("Channel unregistered"); + if (!inactiveMessageSent) { + DisconnectEventBuilder builder = new DisconnectEventBuilder(); + builder.setInfo("Channel unregistered"); + consumer.consume(builder.build()); + inactiveMessageSent = true; + } + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java new file mode 100644 index 0000000000..5f408e6c6c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandler.java @@ -0,0 +1,53 @@ +/* + * 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.core; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.timeout.ReadTimeoutHandler; + +import java.util.concurrent.TimeUnit; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Detects idle state of switch and informs upper layers + * @author michal.polkorab + */ +public class IdleHandler extends ReadTimeoutHandler { + + private static final Logger LOG = LoggerFactory.getLogger(IdleHandler.class); + private boolean first = true; + + /** + * @param readerIdleTime + * @param unit + */ + public IdleHandler(final long readerIdleTime, final TimeUnit unit) { + super(readerIdleTime, unit); + } + + @Override + public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception { + super.channelRead(ctx, msg); + first = true; + } + + @Override + protected void readTimedOut(final ChannelHandlerContext ctx) throws Exception { + if (first) { + LOG.debug("Switch idle"); + SwitchIdleEventBuilder builder = new SwitchIdleEventBuilder(); + builder.setInfo("Switch idle"); + ctx.fireChannelRead(builder.build()); + first = false; + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.java new file mode 100644 index 0000000000..261beb9ce2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoder.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.impl.core; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class OFDatagramPacketDecoder extends SimpleChannelInboundHandler{ + + 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 (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) { + LOG.warn("Translated POJO is null"); + } else { + MessageConsumer consumer = UdpConnectionMap.getMessageConsumer(msg.getAddress()); + consumer.consume(dataObject); + } + } catch(Exception e) { + LOG.warn("Message deserialization failed", e); + // TODO: delegate exception to allow easier deserialization + // debugging / deserialization problem awareness + } finally { + msg.getMessageBuffer().release(); + } + } + + /** + * @param deserializationFactory + */ + public void setDeserializationFactory(final DeserializationFactory deserializationFactory) { + this.deserializationFactory = deserializationFactory; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java new file mode 100644 index 0000000000..8b1faef30f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoder.java @@ -0,0 +1,56 @@ +/* + * 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.impl.core; + +import java.util.List; + +import org.opendaylight.openflowjava.protocol.impl.core.connection.UdpMessageListenerWrapper; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.codec.MessageToMessageEncoder; +import io.netty.util.concurrent.Future; + +/** + * @author michal.polkorab + * + */ +public class OFDatagramPacketEncoder extends MessageToMessageEncoder { + + private static final Logger LOG = LoggerFactory.getLogger(OFDatagramPacketEncoder.class); + private SerializationFactory serializationFactory; + + @Override + protected void encode(ChannelHandlerContext ctx, + UdpMessageListenerWrapper wrapper, List out) throws Exception { + 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) { + LOG.warn("Message serialization failed: {}", e.getMessage()); + Future newFailedFuture = ctx.newFailedFuture(e); + wrapper.getListener().operationComplete(newFailedFuture); + return; + } + } + + /** + * @param serializationFactory + */ + public void setSerializationFactory(SerializationFactory serializationFactory) { + this.serializationFactory = serializationFactory; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.java new file mode 100644 index 0000000000..0eb2916165 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandler.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.protocol.impl.core; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.List; + +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class OFDatagramPacketHandler extends MessageToMessageDecoder { + + private static final Logger LOG = LoggerFactory.getLogger(OFDatagramPacketHandler.class); + + /** Length of OpenFlow 1.3 header */ + public static final byte LENGTH_OF_HEADER = 8; + private static final byte LENGTH_INDEX_IN_HEADER = 2; + private ConnectionAdapterFactory adapterFactory = new ConnectionAdapterFactoryImpl(); + private SwitchConnectionHandler connectionHandler; + + /** + * Default constructor + * @param sch the switchConnectionHandler that decides + * what to do with incomming message / channel + */ + public OFDatagramPacketHandler(SwitchConnectionHandler sch) { + this.connectionHandler = sch; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + 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 { + LOG.debug("OFDatagramPacketFramer"); + MessageConsumer consumer = UdpConnectionMap.getMessageConsumer(msg.sender()); + if (consumer == null) { + ConnectionFacade connectionFacade = + adapterFactory.createConnectionFacade(ctx.channel(), msg.sender(), false); + connectionHandler.onSwitchConnected(connectionFacade); + connectionFacade.checkListeners(); + UdpConnectionMap.addConnection(msg.sender(), connectionFacade); + } + ByteBuf bb = msg.content(); + int readableBytes = bb.readableBytes(); + if (readableBytes < LENGTH_OF_HEADER) { + 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); + LOG.debug("length of actual message: {}", length); + + if (readableBytes < length) { + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); + LOG.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); + } + return; + } + 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)) { + LOG.debug("detected version: {}", version); + ByteBuf messageBuffer = bb.slice(); + out.add(new VersionMessageUdpWrapper(version, messageBuffer, msg.sender())); + messageBuffer.retain(); + } else { + LOG.warn("detected version: {} - currently not supported", version); + } + bb.skipBytes(bb.readableBytes()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java new file mode 100644 index 0000000000..90d0ab0227 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoder.java @@ -0,0 +1,73 @@ +/* + * 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.core; + +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; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Transforms OpenFlow Protocol messages to POJOs. + * @author michal.polkorab + */ +public class OFDecoder extends MessageToMessageDecoder { + + private static final Logger LOG = LoggerFactory.getLogger(OFDecoder.class); + private final StatisticsCounters statisticsCounter; + + // TODO: make this final? + private DeserializationFactory deserializationFactory; + + public OFDecoder() { + LOG.trace("Creating OFDecoder"); + // TODO: pass as argument + statisticsCounter = StatisticsCounters.getInstance(); + } + + @Override + protected void decode(ChannelHandlerContext ctx, VersionMessageWrapper msg, List out) throws Exception { + statisticsCounter.incrementCounter(CounterEventTypes.US_RECEIVED_IN_OFJAVA); + 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) { + 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) { + LOG.warn("Message deserialization failed", e); + statisticsCounter.incrementCounter(CounterEventTypes.US_DECODE_FAIL); + } finally { + msg.getMessageBuffer().release(); + } + } + + /** + * @param deserializationFactory + */ + public void setDeserializationFactory(DeserializationFactory deserializationFactory) { + this.deserializationFactory = deserializationFactory; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java new file mode 100644 index 0000000000..2f35669377 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoder.java @@ -0,0 +1,69 @@ +/* + * 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.core; + +import io.netty.buffer.ByteBuf; +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; +import org.opendaylight.openflowjava.statistics.StatisticsCounters; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Transforms OpenFlow Protocol messages to POJOs. + * @author michal.polkorab + * @author timotej.kubas + */ +public class OFEncoder extends MessageToByteEncoder { + + private static final Logger LOG = LoggerFactory.getLogger(OFEncoder.class); + private SerializationFactory serializationFactory; + private final StatisticsCounters statisticsCounters; + + /** Constructor of class */ + public OFEncoder() { + statisticsCounters = StatisticsCounters.getInstance(); + LOG.trace("Creating OFEncoder"); + } + + @Override + protected void encode(final ChannelHandlerContext ctx, final MessageListenerWrapper wrapper, final ByteBuf out) + throws Exception { + 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(final Exception e) { + LOG.warn("Message serialization failed ", e); + statisticsCounters.incrementCounter(CounterEventTypes.DS_ENCODE_FAIL); + if (wrapper.getListener() != null) { + final Future newFailedFuture = ctx.newFailedFuture(e); + wrapper.getListener().operationComplete(newFailedFuture); + } + out.clear(); + return; + } + } + + /** + * @param serializationFactory + */ + public void setSerializationFactory(final SerializationFactory serializationFactory) { + this.serializationFactory = serializationFactory; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java new file mode 100644 index 0000000000..a9c5ecd252 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoder.java @@ -0,0 +1,92 @@ +/* + * 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.core; + +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; +import org.slf4j.LoggerFactory; + +/** + * Decodes incoming messages into message frames. + * @author michal.polkorab + */ +public class OFFrameDecoder extends ByteToMessageDecoder { + + /** 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 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. + * @param tlsPresent true is TLS is required, false otherwise + */ + public OFFrameDecoder(ConnectionFacade connectionFacade, boolean tlsPresent) { + LOG.trace("Creating OFFrameDecoder"); + if (tlsPresent) { + firstTlsPass = true; + } + this.connectionFacade = connectionFacade; + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (cause instanceof io.netty.handler.ssl.NotSslRecordException) { + LOG.warn("Not an TLS record exception - please verify TLS configuration."); + } else { + LOG.warn("Unexpected exception from downstream.", cause); + } + LOG.warn("Closing connection."); + ctx.close(); + } + + @Override + protected void decode(ChannelHandlerContext chc, ByteBuf bb, List list) throws Exception { + if (firstTlsPass) { + connectionFacade.fireConnectionReadyNotification(); + firstTlsPass = false; + } + int readableBytes = bb.readableBytes(); + if (readableBytes < LENGTH_OF_HEADER) { + 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); + LOG.debug("length of actual message: {}", length); + + if (readableBytes < length) { + if (LOG.isDebugEnabled()) { + LOG.debug("skipping bytebuf - too few bytes for msg: {} < {}", readableBytes, length); + LOG.debug("bytebuffer: {}", ByteBufUtils.byteBufToHexString(bb)); + } + return; + } + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + + ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); + list.add(messageBuffer); + messageBuffer.retain(); + bb.skipBytes(length); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java new file mode 100644 index 0000000000..8e23566af1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetector.java @@ -0,0 +1,73 @@ +/* + * 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.core; + +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; +import org.opendaylight.openflowjava.statistics.StatisticsCounters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Detects version of used OpenFlow Protocol and discards unsupported version messages. + * @author michal.polkorab + */ +public class OFVersionDetector extends ByteToMessageDecoder { + + 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; + + public OFVersionDetector() { + LOG.trace("Creating OFVersionDetector"); + statisticsCounters = StatisticsCounters.getInstance(); + } + + public void setFilterPacketIns(final boolean enabled) { + filterPacketIns = enabled; + } + + @Override + protected void decode(final ChannelHandlerContext ctx, final ByteBuf in, final List out) { + if (!in.isReadable()) { + LOG.debug("not enough data"); + in.release(); + return; + } + + final byte version = in.readByte(); + 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 { + LOG.debug("dropped packetin"); + statisticsCounters.incrementCounter(CounterEventTypes.US_DROPPED_PACKET_IN); + } + } else { + LOG.warn("detected version: {} - currently not supported", version); + } + in.skipBytes(in.readableBytes()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java new file mode 100644 index 0000000000..93b39d4f67 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java @@ -0,0 +1,24 @@ +/* + * 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.core; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * @author mirehak + */ +public interface OnlineProvider { + + /** + * @return the isOnlineFuture + */ + ListenableFuture getIsOnlineFuture(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java new file mode 100644 index 0000000000..88144d47be --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/PipelineHandlers.java @@ -0,0 +1,63 @@ +/* + * 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.impl.core; + +/** + * Stores names of handlers used in pipeline. + * + * @author michal.polkorab + */ +public enum PipelineHandlers { + + /** + * Detects switch idle state + */ + IDLE_HANDLER, + /** + * Component for handling TLS frames + */ + SSL_HANDLER, + /** + * Decodes incoming messages into message frames + */ + OF_FRAME_DECODER, + /** + * Detects version of incoming OpenFlow Protocol message + */ + OF_VERSION_DETECTOR, + /** + * Transforms OpenFlow Protocol byte messages into POJOs + */ + OF_DECODER, + /** + * Transforms POJOs into OpenFlow Protocol byte messages + */ + OF_ENCODER, + /** + * Delegates translated POJOs into MessageConsumer + */ + DELEGATING_INBOUND_HANDLER, + /** + * Performs configurable efficient flushing + */ + CHANNEL_OUTBOUND_QUEUE_MANAGER, + /** + * Decodes incoming messages into message frames + * and filters them based on version supported + */ + OF_DATAGRAMPACKET_HANDLER, + /** + * Transforms OpenFlow Protocol datagram messages into POJOs + */ + OF_DATAGRAMPACKET_DECODER, + /** + * Transforms POJOs into OpenFlow Protocol datagrams + */ + OF_DATAGRAMPACKET_ENCODER +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java new file mode 100644 index 0000000000..ec4ffd4a94 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ProtocolChannelInitializer.java @@ -0,0 +1,115 @@ +/* + * 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.impl.core; + +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; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; + +/** + * @param Channel type + * @author michal.polkorab + */ +public abstract class ProtocolChannelInitializer + extends ChannelInitializer { + + private SwitchConnectionHandler switchConnectionHandler; + private long switchIdleTimeout; + private SerializationFactory serializationFactory; + private DeserializationFactory deserializationFactory; + private TlsConfiguration tlsConfiguration; + private boolean useBarrier; + + /** + * @param switchConnectionHandler the switchConnectionHandler to set + */ + public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) { + this.switchConnectionHandler = switchConnectionHandler; + } + + /** + * @param switchIdleTimeout the switchIdleTimeout to set + */ + public void setSwitchIdleTimeout(final long switchIdleTimeout) { + this.switchIdleTimeout = switchIdleTimeout; + } + + /** + * @param serializationFactory + */ + public void setSerializationFactory(final SerializationFactory serializationFactory) { + this.serializationFactory = serializationFactory; + } + + /** + * @param deserializationFactory + */ + public void setDeserializationFactory(final DeserializationFactory deserializationFactory) { + this.deserializationFactory = deserializationFactory; + } + + /** + * @param tlsConfiguration + */ + public void setTlsConfiguration(final TlsConfiguration tlsConfiguration) { + this.tlsConfiguration = tlsConfiguration; + } + + /** + * @return switch connection handler + */ + public SwitchConnectionHandler getSwitchConnectionHandler() { + return switchConnectionHandler; + } + + /** + * @return switch idle timeout + */ + public long getSwitchIdleTimeout() { + return switchIdleTimeout; + } + + /** + * @return serialization factory + */ + public SerializationFactory getSerializationFactory() { + return serializationFactory; + } + + /** + * @return deserialization factory + */ + public DeserializationFactory getDeserializationFactory() { + return deserializationFactory; + } + + /** + * @return TLS configuration + */ + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java new file mode 100644 index 0000000000..560e910ea8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java @@ -0,0 +1,24 @@ +/* + * 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.core; + +import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; + +/** + * @author mirehak + */ +public interface ServerFacade extends ShutdownProvider, OnlineProvider, Runnable { + + /** + * Sets thread configuration + * @param threadConfig desired thread configuration + */ + void setThreadConfig(ThreadConfiguration threadConfig); +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ShutdownProvider.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ShutdownProvider.java new file mode 100644 index 0000000000..15978def52 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ShutdownProvider.java @@ -0,0 +1,25 @@ +/* + * 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.core; + +import com.google.common.util.concurrent.ListenableFuture; + + +/** + * @author mirehak + */ +public interface ShutdownProvider { + + /** + * @return shutdown future + */ + ListenableFuture shutdown(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java new file mode 100644 index 0000000000..dbaa207022 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactory.java @@ -0,0 +1,88 @@ +/* + * 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.core; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.NoSuchAlgorithmException; +import java.security.Security; +import java.security.cert.CertificateException; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for setting up TLS connection. + * + * @author michal.polkorab + */ +public class SslContextFactory { + + // "TLS" - supports some version of TLS + // Use "TLSv1", "TLSv1.1", "TLSv1.2" for specific TLS version + private static final String PROTOCOL = "TLS"; + private TlsConfiguration tlsConfig; + + private static final Logger LOG = LoggerFactory + .getLogger(SslContextFactory.class); + + /** + * @param tlsConfig + * TLS configuration object, contains keystore locations + + * keystore types + */ + public SslContextFactory(TlsConfiguration tlsConfig) { + this.tlsConfig = tlsConfig; + } + + /** + * @return servercontext + */ + public SSLContext getServerContext() { + String algorithm = Security + .getProperty("ssl.KeyManagerFactory.algorithm"); + if (algorithm == null) { + algorithm = "SunX509"; + } + SSLContext serverContext = null; + try { + KeyStore ks = KeyStore.getInstance(tlsConfig.getTlsKeystoreType().name()); + ks.load(SslKeyStore.asInputStream(tlsConfig.getTlsKeystore(), tlsConfig.getTlsKeystorePathType()), + tlsConfig.getKeystorePassword().toCharArray()); + KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); + kmf.init(ks, tlsConfig.getCertificatePassword().toCharArray()); + + KeyStore ts = KeyStore.getInstance(tlsConfig.getTlsTruststoreType().name()); + ts.load(SslKeyStore.asInputStream(tlsConfig.getTlsTruststore(), tlsConfig.getTlsTruststorePathType()), + tlsConfig.getTruststorePassword().toCharArray()); + TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); + tmf.init(ts); + + serverContext = SSLContext.getInstance(PROTOCOL); + serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } catch (IOException e) { + LOG.warn("IOException - Failed to load keystore / truststore." + + " Failed to initialize the server-side SSLContext", e); + } catch (NoSuchAlgorithmException e) { + LOG.warn("NoSuchAlgorithmException - Unsupported algorithm." + + " Failed to initialize the server-side SSLContext", e); + } catch (CertificateException e) { + LOG.warn("CertificateException - Unable to access certificate (check password)." + + " Failed to initialize the server-side SSLContext", e); + } catch (Exception e) { + LOG.warn("Exception - Failed to initialize the server-side SSLContext", e); + } + return serverContext; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java new file mode 100644 index 0000000000..e4efea9f76 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStore.java @@ -0,0 +1,66 @@ +/* + * 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.core; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for storing keys + * + * @author michal.polkorab + */ +public final class SslKeyStore { + + private static final Logger LOG = LoggerFactory.getLogger(SslKeyStore.class); + + private SslKeyStore() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * InputStream instance of key - key location is on classpath + * @param filename keystore location + * @param pathType keystore location type - "classpath" or "path" + * + * @return key as InputStream + */ + public static InputStream asInputStream(String filename, PathType pathType) { + InputStream in; + switch (pathType) { + case CLASSPATH: + in = SslKeyStore.class.getResourceAsStream(filename); + if (in == null) { + throw new IllegalStateException("KeyStore file not found: " + + filename); + } + break; + case PATH: + LOG.debug("Current dir using System:" + + System.getProperty("user.dir")); + File keystorefile = new File(filename); + try { + in = new FileInputStream(keystorefile); + } catch (FileNotFoundException e) { + throw new IllegalStateException("KeyStore file not found: " + + filename,e); + } + break; + default: + throw new IllegalArgumentException("Unknown path type: " + pathType); + } + return in; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java new file mode 100644 index 0000000000..79ad266535 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java new file mode 100755 index 0000000000..612afcb73f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java @@ -0,0 +1,324 @@ +/* + * 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.core; + +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; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +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; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionSerializerKey; +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.impl.deserialization.DeserializationFactory; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Exposed class for server handling
+ * C - {@link MatchEntrySerializerKey} parameter representing oxm_class (see specification)
+ * F - {@link MatchEntrySerializerKey} parameter representing oxm_field (see specification) + * @author mirehak + * @author michal.polkorab + */ +public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, ConnectionInitializer { + + private static final Logger LOG = LoggerFactory + .getLogger(SwitchConnectionProviderImpl.class); + private SwitchConnectionHandler switchConnectionHandler; + private ServerFacade serverFacade; + private ConnectionConfiguration connConfig; + private final SerializationFactory serializationFactory; + private final SerializerRegistry serializerRegistry; + private final DeserializerRegistry deserializerRegistry; + private final DeserializationFactory deserializationFactory; + private TcpConnectionInitializer connectionInitializer; + + /** Constructor */ + public SwitchConnectionProviderImpl() { + serializerRegistry = new SerializerRegistryImpl(); + serializerRegistry.init(); + serializationFactory = new SerializationFactory(); + serializationFactory.setSerializerTable(serializerRegistry); + deserializerRegistry = new DeserializerRegistryImpl(); + deserializerRegistry.init(); + deserializationFactory = new DeserializationFactory(); + deserializationFactory.setRegistry(deserializerRegistry); + } + + @Override + public void setConfiguration(final ConnectionConfiguration connConfig) { + this.connConfig = connConfig; + } + + @Override + public void setSwitchConnectionHandler(final SwitchConnectionHandler switchConnectionHandler) { + LOG.debug("setSwitchConnectionHandler"); + this.switchConnectionHandler = switchConnectionHandler; + } + + @Override + public ListenableFuture shutdown() { + LOG.debug("Shutdown summoned"); + if(serverFacade == null){ + LOG.warn("Can not shutdown - not configured or started"); + throw new IllegalStateException("SwitchConnectionProvider is not started or not configured."); + } + return serverFacade.shutdown(); + } + + @Override + public ListenableFuture startup() { + LOG.debug("Startup summoned"); + ListenableFuture result = null; + try { + serverFacade = createAndConfigureServer(); + if (switchConnectionHandler == null) { + throw new IllegalStateException("SwitchConnectionHandler is not set"); + } + new Thread(serverFacade).start(); + result = serverFacade.getIsOnlineFuture(); + } catch (final Exception e) { + final SettableFuture exResult = SettableFuture.create(); + exResult.setException(e); + result = exResult; + } + return result; + } + + /** + * @return + */ + private ServerFacade createAndConfigureServer() { + LOG.debug("Configuring .."); + ServerFacade server = null; + final ChannelInitializerFactory factory = new ChannelInitializerFactory(); + factory.setSwitchConnectionHandler(switchConnectionHandler); + factory.setSwitchIdleTimeout(connConfig.getSwitchIdleTimeout()); + factory.setTlsConfig(connConfig.getTlsConfiguration()); + factory.setSerializationFactory(serializationFactory); + factory.setDeserializationFactory(deserializationFactory); + 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()); + final TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer(); + ((TcpHandler) server).setChannelInitializer(channelInitializer); + ((TcpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); + + final EventLoopGroup workerGroupFromTcpHandler = ((TcpHandler) server).getWorkerGroup(); + connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler, isEpollEnabled); + connectionInitializer.setChannelInitializer(channelInitializer); + connectionInitializer.run(); + } 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); + } + server.setThreadConfig(connConfig.getThreadConfiguration()); + return server; + } + + /** + * @return servers + */ + public ServerFacade getServerFacade() { + return serverFacade; + } + + @Override + public void close() throws Exception { + shutdown(); + } + + @Override + public boolean unregisterSerializer(final ExperimenterSerializerKey key) { + return serializerRegistry.unregisterSerializer((MessageTypeKey) key); + } + + @Override + public boolean unregisterDeserializer(final ExperimenterDeserializerKey key) { + return deserializerRegistry.unregisterDeserializer((MessageCodeKey) key); + } + + @Override + public void registerActionSerializer(final ActionSerializerKey key, + final OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerActionDeserializer(final ExperimenterActionDeserializerKey key, + final OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerInstructionSerializer(final InstructionSerializerKey key, + final OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerInstructionDeserializer(final ExperimenterInstructionDeserializerKey key, + final OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerMatchEntrySerializer(final MatchEntrySerializerKey key, + final OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerMatchEntryDeserializer(final MatchEntryDeserializerKey key, + final OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerErrorDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerExperimenterMessageDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerMultipartReplyMessageDeserializer(ExperimenterIdDeserializerKey key, + OFDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerMultipartReplyTFDeserializer(final ExperimenterIdDeserializerKey key, + final OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerQueuePropertyDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerMeterBandDeserializer(final ExperimenterIdDeserializerKey key, + final OFDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerExperimenterMessageSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerMultipartRequestSerializer(ExperimenterIdSerializerKey key, + OFSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + 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(final ExperimenterIdMeterSubTypeSerializerKey key, + final OFSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void initiateConnection(final String host, final int port) { + connectionInitializer.initiateConnection(host, port); + } + + @Override + public ConnectionConfiguration getConfiguration() { + return this.connConfig; + } + + @Override + public void registerSerializer(MessageTypeKey key, OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(key, serializer); + } + + @Override + public void registerDeserializer(MessageCodeKey key, OFGeneralDeserializer deserializer) { + deserializerRegistry.registerDeserializer(key, deserializer); + } + + @Override + public void registerDeserializerMapping(final TypeToClassKey key, final Class clazz) { + deserializationFactory.registerMapping(key, clazz); + } + + @Override + public boolean unregisterDeserializerMapping(final TypeToClassKey key) { + return deserializationFactory.unregisterMapping(key); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java new file mode 100644 index 0000000000..9e6e2f1401 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpChannelInitializer.java @@ -0,0 +1,138 @@ +/* + * 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.core; + +import io.netty.channel.Channel; +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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Initializes TCP / TLS channel. + * @author michal.polkorab + */ +public class TcpChannelInitializer extends ProtocolChannelInitializer { + + private static final Logger LOG = LoggerFactory.getLogger(TcpChannelInitializer.class); + private final DefaultChannelGroup allChannels; + private final ConnectionAdapterFactory connectionAdapterFactory; + + /** + * Default constructor. + */ + public TcpChannelInitializer() { + this( new DefaultChannelGroup("netty-receiver", null), new ConnectionAdapterFactoryImpl() ); + } + + /** + * Testing constructor. + */ + protected TcpChannelInitializer( final DefaultChannelGroup channelGroup, final ConnectionAdapterFactory connAdaptorFactory ) { + allChannels = channelGroup ; + connectionAdapterFactory = connAdaptorFactory ; + } + + @Override + protected void initChannel(final SocketChannel ch) { + if (ch.remoteAddress() != null) { + 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(); + LOG.debug("Incoming connection rejected"); + return; + } + } + LOG.debug("Incoming connection accepted - building pipeline"); + allChannels.add(ch); + ConnectionFacade connectionFacade = null; + connectionFacade = connectionAdapterFactory.createConnectionFacade(ch, null, useBarrier()); + try { + LOG.debug("Calling OF plugin: {}", getSwitchConnectionHandler()); + getSwitchConnectionHandler().onSwitchConnected(connectionFacade); + connectionFacade.checkListeners(); + 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; + final SslContextFactory sslFactory = new SslContextFactory(getTlsConfiguration()); + final SSLEngine engine = sslFactory.getServerContext().createSSLEngine(); + engine.setNeedClientAuth(true); + engine.setUseClientMode(false); + 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()); + final OFDecoder ofDecoder = new OFDecoder(); + ofDecoder.setDeserializationFactory(getDeserializationFactory()); + ch.pipeline().addLast(PipelineHandlers.OF_DECODER.name(), ofDecoder); + 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)); + if (!tlsPresent) { + connectionFacade.fireConnectionReadyNotification(); + } + } catch (final Exception e) { + LOG.warn("Failed to initialize channel", e); + ch.close(); + } + } + + /** + * @return iterator through active connections + */ + public Iterator getConnectionIterator() { + return allChannels.iterator(); + } + + /** + * @return amount of active channels + */ + public int size() { + return allChannels.size(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java new file mode 100644 index 0000000000..d0a2fc6357 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java @@ -0,0 +1,94 @@ +/* + * 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.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; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; + +/** + * Initializes (TCP) connection to device + * @author martin.uhlir + * + */ +public class TcpConnectionInitializer implements ServerFacade, + ConnectionInitializer { + + 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(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(); + if(isEpollEnabled) { + b.group(workerGroup).channel(EpollSocketChannel.class) + .handler(channelInitializer); + } else { + b.group(workerGroup).channel(NioSocketChannel.class) + .handler(channelInitializer); + } + } + + @Override + public ListenableFuture shutdown() { + final SettableFuture result = SettableFuture.create(); + workerGroup.shutdownGracefully(); + return result; + } + + @Override + public ListenableFuture getIsOnlineFuture() { + return null; + } + + @Override + public void setThreadConfig(ThreadConfiguration threadConfig) { + this.threadConfig = threadConfig; + } + + @Override + public void initiateConnection(String host, int port) { + try { + b.connect(host, port).sync(); + } catch (InterruptedException e) { + LOG.error("Unable to initiate connection", e); + } + } + + /** + * @param channelInitializer + */ + public void setChannelInitializer(TcpChannelInitializer channelInitializer) { + this.channelInitializer = channelInitializer; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java new file mode 100644 index 0000000000..2391423103 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java @@ -0,0 +1,269 @@ +/* + * 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.core; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.PooledByteBufAllocator; +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; + +import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; + +/** + * Class implementing server over TCP / TLS for handling incoming connections. + * + * @author michal.polkorab + */ +public class TcpHandler implements ServerFacade { + /* + * High/low write watermarks, in KiB. + */ + private static final int DEFAULT_WRITE_HIGH_WATERMARK = 64; + private static final int DEFAULT_WRITE_LOW_WATERMARK = 32; + /* + * Write spin count. This tells netty to immediately retry a non-blocking + * write this many times before moving on to selecting. + */ + private static final int DEFAULT_WRITE_SPIN_COUNT = 16; + + private static final Logger LOG = LoggerFactory.getLogger(TcpHandler.class); + + private int port; + private String address; + private final InetAddress startupAddress; + 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. + * + * @param port listening port of TCPHandler server + */ + public TcpHandler(final int port) { + this(null, port); + } + + /** + * Constructor of TCPHandler that listens on selected address and port. + * @param address listening address of TCPHandler server + * @param port listening port of TCPHandler server + */ + public TcpHandler(final InetAddress address, final int port) { + this.port = port; + this.startupAddress = address; + isOnlineFuture = SettableFuture.create(); + } + + /** + * Starts server on selected port. + */ + @Override + public void run() { + /* + * We generally do not perform IO-unrelated tasks, so we want to have + * all outstanding tasks completed before the executing thread goes + * back into select. + * + * Any other setting means netty will measure the time it spent selecting + * and spend roughly proportional time executing tasks. + */ + //workerGroup.setIoRatio(100); + + final ChannelFuture f; + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(socketChannelClass) + .handler(new LoggingHandler(LogLevel.DEBUG)) + .childHandler(channelInitializer) + .option(ChannelOption.SO_BACKLOG, 128) + .option(ChannelOption.SO_REUSEADDR, true) + .childOption(ChannelOption.SO_KEEPALIVE, true) + .childOption(ChannelOption.TCP_NODELAY , true) + .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) + .childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, DEFAULT_WRITE_HIGH_WATERMARK * 1024) + .childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, DEFAULT_WRITE_LOW_WATERMARK * 1024) + .childOption(ChannelOption.WRITE_SPIN_COUNT, DEFAULT_WRITE_SPIN_COUNT); + + if (startupAddress != null) { + f = b.bind(startupAddress.getHostAddress(), port).sync(); + } else { + f = b.bind(port).sync(); + } + } catch (InterruptedException e) { + LOG.error("Interrupted while binding port {}", port, e); + return; + } + + try { + InetSocketAddress isa = (InetSocketAddress) f.channel().localAddress(); + address = isa.getHostString(); + + // Update port, as it may have been specified as 0 + this.port = isa.getPort(); + + LOG.debug("address from tcphandler: {}", address); + isOnlineFuture.set(true); + LOG.info("Switch listener started and ready to accept incoming tcp/tls connections on port: {}", port); + f.channel().closeFuture().sync(); + } catch (InterruptedException e) { + LOG.error("Interrupted while waiting for port {} shutdown", port, e); + } finally { + shutdown(); + } + } + + /** + * Shuts down {@link TcpHandler}} + */ + @Override + public ListenableFuture shutdown() { + final SettableFuture result = SettableFuture.create(); + workerGroup.shutdownGracefully(); + // boss will shutdown as soon, as worker is down + bossGroup.shutdownGracefully().addListener(new GenericFutureListener>() { + + @Override + public void operationComplete( + final io.netty.util.concurrent.Future downResult) throws Exception { + result.set(downResult.isSuccess()); + if (downResult.cause() != null) { + result.setException(downResult.cause()); + } + } + + }); + return result; + } + + /** + * + * @return number of connected clients / channels + */ + public int getNumberOfConnections() { + return channelInitializer.size(); + } + + @Override + public ListenableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + /** + * @return the port + */ + public int getPort() { + return port; + } + + /** + * @return the address + */ + public String getAddress() { + return address; + } + + /** + * @param channelInitializer + */ + public void setChannelInitializer(TcpChannelInitializer channelInitializer) { + this.channelInitializer = channelInitializer; + } + + @Override + 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) { + socketChannelClass = NioServerSocketChannel.class; + if (threadConfiguration != null) { + bossGroup = new NioEventLoopGroup(threadConfiguration.getBossThreadCount()); + workerGroup = new NioEventLoopGroup(threadConfiguration.getWorkerThreadCount()); + } else { + 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 EventLoopGroup getWorkerGroup() { + return workerGroup; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java new file mode 100644 index 0000000000..ccb8b06c7c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpChannelInitializer.java @@ -0,0 +1,31 @@ +/* + * 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.impl.core; + +import io.netty.channel.socket.DatagramChannel; + +/** + * @author michal.polkorab + * + */ +public class UdpChannelInitializer extends ProtocolChannelInitializer { + + @Override + protected void initChannel(DatagramChannel ch) throws Exception { + ch.pipeline().addLast(PipelineHandlers.OF_DATAGRAMPACKET_HANDLER.name(), + new OFDatagramPacketHandler(getSwitchConnectionHandler())); + OFDatagramPacketDecoder ofDatagramPacketDecoder = new OFDatagramPacketDecoder(); + ofDatagramPacketDecoder.setDeserializationFactory(getDeserializationFactory()); + ch.pipeline().addLast(PipelineHandlers.OF_DATAGRAMPACKET_DECODER.name(), + ofDatagramPacketDecoder); + OFDatagramPacketEncoder ofDatagramPacketEncoder = new OFDatagramPacketEncoder(); + ofDatagramPacketEncoder.setSerializationFactory(getSerializationFactory()); + ch.pipeline().addLast(PipelineHandlers.OF_ENCODER.name(), ofDatagramPacketEncoder); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMap.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMap.java new file mode 100644 index 0000000000..d23d5ada1c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMap.java @@ -0,0 +1,62 @@ +/* + * 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.impl.core; + +import java.net.InetSocketAddress; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; + +/** + * As UDP communication is handled only by one channel, it is needed + * to store MessageConsumers, so that we know which consumer handles which channel + + * @author michal.polkorab + */ +public final class UdpConnectionMap { + + private static Map connectionMap = new ConcurrentHashMap<>(); + + private UdpConnectionMap() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * @param address sender's address + * @return corresponding MessageConsumer + */ + public static MessageConsumer getMessageConsumer(InetSocketAddress address) { + if(address == null){ + throw new IllegalArgumentException("Address can not be null"); + } + return connectionMap.get(address); + } + + /** + * @param address sender's address + * @param consumer MessageConsumer to be added / paired with specified address + */ + public static void addConnection(InetSocketAddress address, MessageConsumer consumer) { + if(address == null){ + throw new IllegalArgumentException("Address can not be null"); + } + connectionMap.put(address, consumer); + } + + /** + * @param address sender's address + */ + public static void removeConnection(InetSocketAddress address) { + if(address == null){ + throw new IllegalArgumentException("Address can not be null"); + } + connectionMap.remove(address); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java new file mode 100644 index 0000000000..1dac7a593f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java @@ -0,0 +1,195 @@ +/* + * 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.impl.core; + +import io.netty.bootstrap.Bootstrap; +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; + +import java.net.InetAddress; +import java.net.InetSocketAddress; + +import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; + +/** + * Class implementing server over UDP for handling incoming connections. + * + * @author michal.polkorab + */ +public final class UdpHandler implements ServerFacade { + + private static final Logger LOG = LoggerFactory + .getLogger(UdpHandler.class); + private int port; + private EventLoopGroup group; + private final InetAddress startupAddress; + private final SettableFuture isOnlineFuture; + private UdpChannelInitializer channelInitializer; + private ThreadConfiguration threadConfig; + private Class datagramChannelClass; + + /** + * Constructor of UdpHandler that listens on selected port. + * + * @param port listening port of UdpHandler server + */ + public UdpHandler(final int port) { + this(null, port); + } + + /** + * Constructor of UdpHandler that listens on selected address and port. + * @param address listening address of UdpHandler server + * @param port listening port of UdpHandler server + */ + public UdpHandler(final InetAddress address, final int port) { + this.port = port; + this.startupAddress = address; + isOnlineFuture = SettableFuture.create(); + } + + @Override + public void run() { + final ChannelFuture f; + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(datagramChannelClass) + .option(ChannelOption.SO_BROADCAST, false) + .handler(channelInitializer); + + if (startupAddress != null) { + f = b.bind(startupAddress.getHostAddress(), port).sync(); + } else { + f = b.bind(port).sync(); + } + } catch (InterruptedException e) { + LOG.error("Interrupted while binding port {}", port, e); + return; + } + + try { + InetSocketAddress isa = (InetSocketAddress) f.channel().localAddress(); + String address = isa.getHostString(); + + // Update port, as it may have been specified as 0 + this.port = isa.getPort(); + + LOG.debug("Address from udpHandler: {}", address); + isOnlineFuture.set(true); + LOG.info("Switch listener started and ready to accept incoming udp connections on port: {}", port); + f.channel().closeFuture().sync(); + } catch (InterruptedException e) { + LOG.error("Interrupted while waiting for port {} shutdown", port, e); + } finally { + shutdown(); + } + } + + @Override + public ListenableFuture shutdown() { + final SettableFuture result = SettableFuture.create(); + group.shutdownGracefully().addListener(new GenericFutureListener>() { + + @Override + public void operationComplete( + final io.netty.util.concurrent.Future downResult) throws Exception { + result.set(downResult.isSuccess()); + if (downResult.cause() != null) { + result.setException(downResult.cause()); + } + } + + }); + return result; + } + + @Override + public ListenableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + /** + * @return the port + */ + public int getPort() { + return port; + } + + /** + * @param channelInitializer + */ + public void setChannelInitializer(UdpChannelInitializer channelInitializer) { + this.channelInitializer = channelInitializer; + } + + @Override + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java new file mode 100644 index 0000000000..8f8d06413f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapper.java @@ -0,0 +1,38 @@ +/* + * 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.impl.core; + +import io.netty.buffer.ByteBuf; +import java.net.InetSocketAddress; + +/** + * Wraps received messages (includes version) and sender address + + * @author michal.polkorab + */ +public class VersionMessageUdpWrapper extends VersionMessageWrapper { + private final InetSocketAddress address; + + /** + * @param version Openflow wire version + * @param messageBuffer ByteBuf containing binary message + * @param address sender address + */ + public VersionMessageUdpWrapper(final short version, final ByteBuf messageBuffer, final InetSocketAddress address) { + super(version, messageBuffer); + this.address = address; + } + + /** + * @return sender address + */ + public InetSocketAddress getAddress() { + return address; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java new file mode 100644 index 0000000000..cdbe419c92 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageWrapper.java @@ -0,0 +1,45 @@ +/* + * 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.core; + +import com.google.common.base.Preconditions; +import io.netty.buffer.ByteBuf; + +/** + * Wraps received messages (includes version) + * @author michal.polkorab + */ +public class VersionMessageWrapper { + 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(final short version, final ByteBuf messageBuffer) { + this.version = version; + this.messageBuffer = Preconditions.checkNotNull(messageBuffer); + } + + /** + * @return the version version decoded in {@link OFVersionDetector} + */ + public short getVersion() { + return version; + } + + /** + * @return the messageBuffer message received from {@link OFFrameDecoder} + */ + public ByteBuf getMessageBuffer() { + return messageBuffer; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapter.java new file mode 100644 index 0000000000..57f1498c8f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java new file mode 100644 index 0000000000..20627b04c2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractConnectionAdapterStatistics.java @@ -0,0 +1,77 @@ +/* + * 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractOutboundQueueManager.java new file mode 100644 index 0000000000..f609610afc --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractRpcListener.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractRpcListener.java new file mode 100644 index 0000000000..7579cbd630 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractRpcListener.java @@ -0,0 +1,90 @@ +/* + * 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.impl.core.connection; + +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class holds all the context we need for sending a single message down the tube. + * A MessageHolder (used in queue) and the actual listener. It is not a thing of beauty, + * but it keeps us from allocating unnecessary objects in the egress path. + */ +abstract class AbstractRpcListener implements GenericFutureListener>, ChannelOutboundQueue.MessageHolder { + private static final Logger LOG = LoggerFactory.getLogger(AbstractRpcListener.class); + private static final String APPLICATION_TAG = "OPENFLOW_LIBRARY"; + private static final String TAG = "OPENFLOW"; + private final SettableFuture> result = SettableFuture.create(); + private final String failureInfo; + private Object message; + + /** + * Create RcpError object + * @param info + * @param severity - error severity + * @param message + * @param cause - details of reason + * @return + */ + static RpcError buildRpcError(final String info, final String message, final Throwable cause) { + return RpcResultBuilder.newError(ErrorType.RPC, TAG, message, APPLICATION_TAG, info, cause); + } + + AbstractRpcListener(final Object message, final String failureInfo) { + this.failureInfo = Preconditions.checkNotNull(failureInfo); + this.message = Preconditions.checkNotNull(message); + } + + public final ListenableFuture> getResult() { + return result; + } + + @Override + public final void operationComplete(final Future future) { + if (!future.isSuccess()) { + LOG.debug("operation failed"); + failedRpc(future.cause()); + } else { + LOG.debug("operation complete"); + operationSuccessful(); + } + } + + @Override + public final Object takeMessage() { + final Object ret = message; + Preconditions.checkState(ret != null, "Message has already been taken"); + message = null; + return ret; + } + + @Override + public final GenericFutureListener> takeListener() { + return this; + } + + protected abstract void operationSuccessful(); + + protected final void failedRpc(final Throwable cause) { + final RpcError rpcError = buildRpcError(failureInfo, "check switch connection", cause); + result.set(RpcResultBuilder.failed().withRpcError(rpcError).build()); + } + + protected final void successfulRpc(final T value) { + result.set(RpcResultBuilder.success(value).build()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/AbstractStackedOutboundQueue.java new file mode 100644 index 0000000000..b4356ee41e --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java new file mode 100644 index 0000000000..5845dff85a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue.java @@ -0,0 +1,278 @@ +/* + * 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.impl.core.connection; + +import com.google.common.base.Preconditions; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.util.concurrent.EventExecutor; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; +import java.net.InetSocketAddress; +import java.util.Queue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Channel handler which bypasses wraps on top of normal Netty pipeline, allowing + * writes to be enqueued from any thread, it then schedules a task pipeline task, + * which shuffles messages from the queue into the pipeline. + * + * Note this is an *Inbound* handler, as it reacts to channel writability changing, + * which in the Netty vocabulary is an inbound event. This has already changed in + * the Netty 5.0.0 API, where Handlers are unified. + */ +final class ChannelOutboundQueue extends ChannelInboundHandlerAdapter { + public interface MessageHolder { + /** + * Take ownership of the encapsulated listener. Guaranteed to + * be called at most once. + * + * @return listener encapsulated in the holder, may be null + * @throws IllegalStateException if the listener is no longer + * available (for example because it has already been + * taken). + */ + GenericFutureListener> takeListener(); + + /** + * Take ownership of the encapsulated message. Guaranteed to be + * called at most once. + * + * @return message encapsulated in the holder, may not be null + * @throws IllegalStateException if the message is no longer + * available (for example because it has already been + * taken). + */ + T takeMessage(); + } + + /** + * 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 static final Logger LOG = LoggerFactory.getLogger(ChannelOutboundQueue.class); + + // Passed to executor to request triggering of flush + private final Runnable flushRunnable = new Runnable() { + @Override + public void run() { + ChannelOutboundQueue.this.flush(); + } + }; + + /* + * Instead of using an AtomicBoolean object, we use these two. It saves us + * from allocating an extra object. + */ + private static final AtomicIntegerFieldUpdater FLUSH_SCHEDULED_UPDATER = + AtomicIntegerFieldUpdater.newUpdater(ChannelOutboundQueue.class, "flushScheduled"); + private volatile int flushScheduled = 0; + + private final Queue> queue; + private final long maxWorkTime; + private final Channel channel; + private final InetSocketAddress address; + + public ChannelOutboundQueue(final Channel channel, final int queueDepth, final InetSocketAddress address) { + Preconditions.checkArgument(queueDepth > 0, "Queue depth has to be positive"); + + /* + * This looks like a good trade-off for throughput. Alternative is + * to use an ArrayBlockingQueue -- but that uses a single lock to + * synchronize both producers and consumers, potentially leading + * to less throughput. + */ + this.queue = new LinkedBlockingQueue<>(queueDepth); + this.channel = Preconditions.checkNotNull(channel); + this.maxWorkTime = TimeUnit.MICROSECONDS.toNanos(DEFAULT_WORKTIME_MICROS); + this.address = address; + } + + /** + * Enqueue a message holder for transmission. Is a thread-safe entry point + * for the channel. If the cannot be placed on the queue, this + * + * @param holder MessageHolder which should be enqueue + * @return Success indicator, true if the enqueue operation succeeded, + * false if the queue is full. + */ + public boolean enqueue(final MessageHolder holder) { + LOG.trace("Enqueuing message {}", holder); + if (queue.offer(holder)) { + LOG.trace("Message enqueued"); + conditionalFlush(); + return true; + } + + LOG.debug("Message queue is full"); + return false; + } + + private void scheduleFlush(final EventExecutor executor) { + if (FLUSH_SCHEDULED_UPDATER.compareAndSet(this, 0, 1)) { + LOG.trace("Scheduling flush task"); + executor.execute(flushRunnable); + } else { + LOG.trace("Flush task is already present"); + } + } + + /** + * Schedule a queue flush if it is not empty and the channel is found + * to be writable. + */ + private void conditionalFlush() { + if (queue.isEmpty()) { + LOG.trace("Queue is empty, flush not needed"); + return; + } + if (!channel.isWritable()) { + LOG.trace("Channel {} is not writable, not issuing a flush", channel); + return; + } + + scheduleFlush(channel.pipeline().lastContext().executor()); + } + + /* + * The synchronized keyword should be unnecessary, really, but it enforces + * queue order should something go terribly wrong. It should be completely + * uncontended. + */ + private synchronized void flush() { + + final long start = System.nanoTime(); + final long deadline = start + maxWorkTime; + + LOG.debug("Dequeuing messages to channel {}", channel); + + long messages = 0; + for (;; ++messages) { + if (!channel.isWritable()) { + LOG.trace("Channel is no longer writable"); + break; + } + + final MessageHolder h = queue.poll(); + if (h == null) { + LOG.trace("The queue is completely drained"); + break; + } + + final GenericFutureListener> l = h.takeListener(); + + final ChannelFuture p; + if (address == null) { + p = channel.write(new MessageListenerWrapper(h.takeMessage(), l)); + } else { + p = channel.write(new UdpMessageListenerWrapper(h.takeMessage(), l, address)); + } + if (l != null) { + p.addListener(l); + } + + /* + * 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, channel); + channel.flush(); + } + + if (LOG.isDebugEnabled()) { + final long stop = System.nanoTime(); + LOG.debug("Flushed {} messages in {}us to channel {}", + messages, TimeUnit.NANOSECONDS.toMicros(stop - start), channel); + } + + /* + * 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 (!FLUSH_SCHEDULED_UPDATER.compareAndSet(this, 1, 0)) { + LOG.warn("Channel {} queue {} flusher found unscheduled", channel, queue); + } + + conditionalFlush(); + } + + private void conditionalFlush(final ChannelHandlerContext ctx) { + Preconditions.checkState(ctx.channel().equals(channel), "Inconsistent channel %s with context %s", channel, 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); + conditionalFlush(ctx); + } + + @Override + public void channelInactive(final ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + + long entries = 0; + LOG.debug("Channel shutdown, flushing queue..."); + final Future result = ctx.newFailedFuture(new RejectedExecutionException("Channel disconnected")); + while (true) { + final MessageHolder e = queue.poll(); + if (e == null) { + break; + } + + e.takeListener().operationComplete(result); + entries++; + } + + LOG.debug("Flushed {} queue entries", entries); + } + + @Override + public String toString() { + return String.format("Channel %s queue [%s messages flushing=%s]", channel, queue.size(), flushScheduled); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java new file mode 100644 index 0000000000..1b0a83a7a3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactory.java @@ -0,0 +1,29 @@ +/* + * 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.core.connection; + +import io.netty.channel.Channel; +import java.net.InetSocketAddress; + +/** + * @author mirehak + * @author michal.polkorab + */ +public interface ConnectionAdapterFactory { + + /** + * @param ch {@link Channel} channel + * @param address {@link InetSocketAddress} + * @param useBarrier + * @return connection adapter tcp-implementation + */ + ConnectionFacade createConnectionFacade(Channel ch, InetSocketAddress address, boolean useBarrier); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java new file mode 100644 index 0000000000..91871580ec --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImpl.java @@ -0,0 +1,31 @@ +/* + * 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.core.connection; + +import io.netty.channel.Channel; +import java.net.InetSocketAddress; + +/** + * @author mirehak + * @author michal.polkorab + */ +public class ConnectionAdapterFactoryImpl implements ConnectionAdapterFactory { + + /** + * @param ch + * @return connection adapter tcp-implementation + */ + @Override + public ConnectionFacade createConnectionFacade(final Channel ch, final InetSocketAddress address, + final boolean useBarrier) { + return new ConnectionAdapterImpl(ch, address, useBarrier); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java new file mode 100644 index 0000000000..e9de9ca253 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl.java @@ -0,0 +1,238 @@ +/* + * 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.core.connection; + +import com.google.common.base.Preconditions; +import io.netty.channel.Channel; +import java.net.InetSocketAddress; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration; +import org.opendaylight.openflowjava.protocol.api.extensibility.AlienMessageListener; +import org.opendaylight.openflowjava.protocol.impl.core.OFVersionDetector; +import org.opendaylight.openflowjava.protocol.impl.core.PipelineHandlers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage; +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.HelloMessage; +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.OpenflowProtocolListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handles messages (notifications + rpcs) and connections. + * @author mirehak + * @author michal.polkorab + */ +public class ConnectionAdapterImpl extends AbstractConnectionAdapterStatistics implements ConnectionFacade { + + private static final Logger LOG = LoggerFactory.getLogger(ConnectionAdapterImpl.class); + + private ConnectionReadyListener connectionReadyListener; + private OpenflowProtocolListener messageListener; + private SystemNotificationsListener systemListener; + private AlienMessageListener alienMessageListener; + private AbstractOutboundQueueManager outputManager; + private OFVersionDetector versionDetector; + + private final boolean useBarrier; + + /** + * 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)) + * @param useBarrier value is configurable by configSubsytem + */ + public ConnectionAdapterImpl(final Channel channel, final InetSocketAddress address, final boolean useBarrier) { + super(channel, address); + this.useBarrier = useBarrier; + LOG.debug("ConnectionAdapter created"); + } + + @Override + public void setMessageListener(final OpenflowProtocolListener messageListener) { + this.messageListener = messageListener; + } + + @Override + public void setConnectionReadyListener(final ConnectionReadyListener connectionReadyListener) { + this.connectionReadyListener = connectionReadyListener; + } + + @Override + public void setSystemListener(final SystemNotificationsListener systemListener) { + this.systemListener = systemListener; + } + + @Override + public void setAlienMessageListener(final AlienMessageListener alienMessageListener) { + this.alienMessageListener = alienMessageListener; + } + + @Override + public void consumeDeviceMessage(final DataObject message) { + LOG.debug("ConsumeIntern msg on {}", channel); + if (disconnectOccured) { + return; + } + if (message instanceof Notification) { + + // System events + if (message instanceof DisconnectEvent) { + systemListener.onDisconnectEvent((DisconnectEvent) message); + responseCache.invalidateAll(); + disconnectOccured = true; + } else if (message instanceof SwitchIdleEvent) { + systemListener.onSwitchIdleEvent((SwitchIdleEvent) message); + // OpenFlow messages + } else if (message instanceof EchoRequestMessage) { + if (outputManager != null) { + outputManager.onEchoRequest((EchoRequestMessage) message); + } else { + messageListener.onEchoRequestMessage((EchoRequestMessage) message); + } + } else if (message instanceof ErrorMessage) { + // Send only unmatched errors + if (outputManager == null || !outputManager.onMessage((OfHeader) message)) { + messageListener.onErrorMessage((ErrorMessage) message); + } + } else if (message instanceof ExperimenterMessage) { + if (outputManager != null) { + outputManager.onMessage((OfHeader) message); + } + messageListener.onExperimenterMessage((ExperimenterMessage) message); + } else if (message instanceof FlowRemovedMessage) { + messageListener.onFlowRemovedMessage((FlowRemovedMessage) message); + } else if (message instanceof HelloMessage) { + LOG.info("Hello received"); + messageListener.onHelloMessage((HelloMessage) message); + } else if (message instanceof MultipartReplyMessage) { + if (outputManager != null) { + outputManager.onMessage((OfHeader) message); + } + messageListener.onMultipartReplyMessage((MultipartReplyMessage) message); + } else if (message instanceof PacketInMessage) { + messageListener.onPacketInMessage((PacketInMessage) message); + } else if (message instanceof PortStatusMessage) { + messageListener.onPortStatusMessage((PortStatusMessage) message); + } else { + LOG.warn("message listening not supported for type: {}", message.getClass()); + } + } else if (message instanceof OfHeader) { + LOG.debug("OF header msg received"); + boolean found = false; + + if (outputManager == null || !outputManager.onMessage((OfHeader) message)) { + final RpcResponseKey key = createRpcResponseKey((OfHeader) message); + final ResponseExpectedRpcListener listener = findRpcResponse(key); + if (listener != null) { + found = true; + LOG.debug("Corresponding rpcFuture found"); + listener.completed((OfHeader) message); + LOG.debug("After setting rpcFuture"); + responseCache.invalidate(key); + } + } + + if (!found && alienMessageListener != null) { + LOG.debug("Alien message {} received", message.getImplementedInterface()); + alienMessageListener.onAlienMessage((OfHeader) message); + } + } else { + LOG.warn("message listening not supported for type: {}", message.getClass()); + } + } + + private static RpcResponseKey createRpcResponseKey(final OfHeader message) { + return new RpcResponseKey(message.getXid(), message.getImplementedInterface().getName()); + } + + @Override + public void checkListeners() { + final StringBuilder buffer = new StringBuilder(); + if (systemListener == null) { + buffer.append("SystemListener "); + } + if (messageListener == null) { + buffer.append("MessageListener "); + } + if (connectionReadyListener == null) { + buffer.append("ConnectionReadyListener "); + } + + Preconditions.checkState(buffer.length() == 0, "Missing listeners: %s", buffer.toString()); + } + + @Override + public void fireConnectionReadyNotification() { + versionDetector = (OFVersionDetector) channel.pipeline().get(PipelineHandlers.OF_VERSION_DETECTOR.name()); + Preconditions.checkState(versionDetector != null); + + new Thread(new Runnable() { + @Override + public void run() { + connectionReadyListener.onConnectionReady(); + } + }).start(); + } + + @Override + public OutboundQueueHandlerRegistration registerOutboundQueueHandler( + final T handler, final int maxQueueDepth, final long maxBarrierNanos) { + Preconditions.checkState(outputManager == null, "Manager %s already registered", outputManager); + + 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; + /* 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 + protected void removeRegistration() { + outputManager.close(); + channel.pipeline().remove(outputManager); + outputManager = null; + } + }; + } + + Channel getChannel() { + return channel; + } + + @Override + public void setPacketInFiltering(final boolean enabled) { + versionDetector.setFilterPacketIns(enabled); + LOG.debug("PacketIn filtering {}abled", enabled ? "en" : "dis"); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionFacade.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionFacade.java new file mode 100644 index 0000000000..c56ab4843e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionFacade.java @@ -0,0 +1,20 @@ +/* + * 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.core.connection; + +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; + +/** + * @author michal.polkorab + */ +public interface ConnectionFacade extends MessageConsumer, ConnectionAdapter { + + // empty unifying superinterface +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageConsumer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageConsumer.java new file mode 100644 index 0000000000..84c45cee91 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageConsumer.java @@ -0,0 +1,24 @@ +/* + * 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.core.connection; + +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author mirehak + */ +public interface MessageConsumer { + + /** + * @param message to process + */ + void consume(DataObject message); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapper.java new file mode 100644 index 0000000000..4b98fd8cfe --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapper.java @@ -0,0 +1,50 @@ +/* + * 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.impl.core.connection; + +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +/** + * Wraps outgoing message and includes listener attached to this message. This object + * is sent to OFEncoder. When OFEncoder fails to serialize the message, + * listener is filled with exception. The exception is then delegated to upper ODL layers. + * @author michal.polkorab + */ +public class MessageListenerWrapper { + + private OfHeader msg; + private GenericFutureListener> listener; + + /** + * @param msg outgoing message + * @param listener listener attached to channel.write(msg) Future + */ + public MessageListenerWrapper(Object msg, GenericFutureListener> listener) { + this.msg = (OfHeader) msg; + this.listener = listener; + } + + /** + * @return outgoing message (downstream) + */ + public OfHeader getMsg() { + return msg; + } + + + /** + * @return listener listening on message sending success / failure + */ + public GenericFutureListener> getListener() { + return listener; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java new file mode 100644 index 0000000000..d88566b8d3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntry.java @@ -0,0 +1,149 @@ +/* + * 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.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.FutureCallback; + +import java.util.function.Function; + +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class OutboundQueueEntry { + private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueEntry.class); + public static final Function DEFAULT_IS_COMPLETE = new Function() { + + @Override + public Boolean apply(final OfHeader message) { + if (message instanceof MultipartReplyMessage) { + return !((MultipartReplyMessage) message).getFlags().isOFPMPFREQMORE(); + } + + return true; + } + + }; + + private FutureCallback callback; + private OfHeader message; + private boolean completed; + private boolean barrier; + private volatile boolean committed; + private OutboundQueueException lastException = null; + private Function isCompletedFunction = DEFAULT_IS_COMPLETE; + + void commit(final OfHeader message, final FutureCallback callback) { + commit(message, callback, DEFAULT_IS_COMPLETE); + } + + void commit(final OfHeader message, final FutureCallback callback, + final Function isCompletedFunction) { + if (this.completed) { + LOG.warn("Can't commit a completed message."); + if (callback != null) { + 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() { + barrier = false; + callback = null; + completed = false; + message = null; + + // Volatile write, needs to be last + committed = false; + } + + boolean isBarrier() { + return barrier; + } + + boolean isCommitted() { + return committed; + } + + boolean isCompleted() { + return completed; + } + + 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 = isCompletedFunction.apply(response); + + completed = reallyComplete; + if (callback != null) { + callback.onSuccess(response); + if (reallyComplete) { + // We will not need the callback anymore, make sure it can be GC'd + callback = null; + } + } + LOG.debug("Entry {} completed {} with response {}", this, completed, response); + return reallyComplete; + } + + void fail(final OutboundQueueException cause) { + if (!completed) { + lastException = cause; + completed = true; + if (callback != null) { + callback.onFailure(cause); + callback = null; + } + } else { + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueHandlerRegistrationImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueHandlerRegistrationImpl.java new file mode 100644 index 0000000000..697d2ddd21 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueHandlerRegistrationImpl.java @@ -0,0 +1,18 @@ +/* + * 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 org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandler; +import org.opendaylight.openflowjava.protocol.api.connection.OutboundQueueHandlerRegistration; +import org.opendaylight.yangtools.concepts.AbstractObjectRegistration; + +abstract class OutboundQueueHandlerRegistrationImpl extends AbstractObjectRegistration implements OutboundQueueHandlerRegistration { + protected OutboundQueueHandlerRegistrationImpl(final T instance) { + super(instance); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java new file mode 100644 index 0000000000..1769facefa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManager.java @@ -0,0 +1,124 @@ +/* + * 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 java.net.InetSocketAddress; +import java.util.concurrent.TimeUnit; +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.OfHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class OutboundQueueManager extends + AbstractOutboundQueueManager { + private static final Logger LOG = LoggerFactory.getLogger(OutboundQueueManager.class); + + private final int maxNonBarrierMessages; + private final long maxBarrierNanos; + + // Updated from netty only + private boolean barrierTimerEnabled; + private long lastBarrierNanos = System.nanoTime(); + private int nonBarrierMessages; + + // Passed to executor to request a periodic barrier check + private final Runnable barrierRunnable = new Runnable() { + @Override + public void run() { + barrier(); + } + }; + + OutboundQueueManager(final ConnectionAdapterImpl parent, final InetSocketAddress address, final T handler, + final int maxNonBarrierMessages, final long maxBarrierNanos) { + super(parent, address, handler); + Preconditions.checkArgument(maxNonBarrierMessages > 0); + this.maxNonBarrierMessages = maxNonBarrierMessages; + Preconditions.checkArgument(maxBarrierNanos > 0); + this.maxBarrierNanos = maxBarrierNanos; + } + + @Override + protected StackedOutboundQueue initializeStackedOutboudnqueue() { + return new StackedOutboundQueue(this); + } + + private void scheduleBarrierTimer(final long now) { + long next = lastBarrierNanos + maxBarrierNanos; + if (next < now) { + LOG.trace("Attempted to schedule barrier in the past, reset maximum)"); + next = now + maxBarrierNanos; + } + + final long delay = next - now; + LOG.trace("Scheduling barrier timer {}us from now", TimeUnit.NANOSECONDS.toMicros(delay)); + parent.getChannel().eventLoop().schedule(barrierRunnable, next - now, TimeUnit.NANOSECONDS); + barrierTimerEnabled = true; + } + + private void scheduleBarrierMessage() { + final Long xid = currentQueue.reserveBarrierIfNeeded(); + if (xid == null) { + LOG.trace("Queue {} already contains a barrier, not scheduling one", currentQueue); + return; + } + + 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"); + } + } + + /** + * 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 + * by. That timestamp does not need to be completely accurate, + * hence we use the flush start time. Alternative would be to + * measure System.nanoTime() for each barrier -- needlessly + * adding overhead. + */ + @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 >= maxNonBarrierMessages) { + LOG.trace("Scheduled barrier request after {} non-barrier messages", nonBarrierMessages); + scheduleBarrierMessage(); + } else if (!barrierTimerEnabled) { + scheduleBarrierTimer(now); + } + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueManagerNoBarrier.java new file mode 100644 index 0000000000..1fc514735d --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListener.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListener.java new file mode 100644 index 0000000000..15df265de0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListener.java @@ -0,0 +1,46 @@ +/* + * 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.impl.core.connection; + +import java.util.concurrent.TimeoutException; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Preconditions; +import com.google.common.cache.Cache; + +final class ResponseExpectedRpcListener extends AbstractRpcListener { + private static final Logger LOG = LoggerFactory.getLogger(ResponseExpectedRpcListener.class); + private final Cache> cache; + private final RpcResponseKey key; + + ResponseExpectedRpcListener(final Object message, final String failureInfo, + final Cache> cache, final RpcResponseKey key) { + super(message, failureInfo); + this.cache = Preconditions.checkNotNull(cache); + this.key = Preconditions.checkNotNull(key); + } + + public void discard() { + LOG.warn("Request for {} did not receive a response", key); + failedRpc(new TimeoutException("Request timed out")); + } + + @SuppressWarnings("unchecked") + public void completed(final OfHeader message) { + successfulRpc((T)message); + } + + @Override + protected void operationSuccessful() { + LOG.debug("Request for {} sent successfully", key); + cache.put(key, this); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java new file mode 100644 index 0000000000..050f3cf76b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKey.java @@ -0,0 +1,82 @@ +/* + * 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.core.connection; + + + +/** + * @author mirehak + */ +public class RpcResponseKey { + + private final long xid; + private final String outputClazz; + /** + * @param xid + * @param outputClazz + */ + public RpcResponseKey(long xid, String outputClazz) { + this.xid = xid; + this.outputClazz = outputClazz; + } + + /** + * @return the xid + */ + public long getXid() { + return xid; + } + + /** + * @return the outputClazz + */ + public String getOutputClazz() { + return outputClazz; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((outputClazz == null) ? 0 : outputClazz.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + RpcResponseKey other = (RpcResponseKey) obj; + if (outputClazz == null) { + if (other.outputClazz != null) { + return false; + } + } else if (!outputClazz.equals(other.outputClazz)) { + return false; + } else if (xid != other.getXid()) { + return false; + } + return true; + } + + @Override + public String toString() { + return "RpcResultKey [xid=" + xid + ", outputClazz=" + outputClazz + + "]"; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListener.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListener.java new file mode 100644 index 0000000000..fc73863227 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListener.java @@ -0,0 +1,19 @@ +/* + * 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.impl.core.connection; + +final class SimpleRpcListener extends AbstractRpcListener { + public SimpleRpcListener(final Object message, final String failureInfo) { + super(message, failureInfo); + } + + @Override + protected void operationSuccessful() { + successfulRpc(null); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueue.java new file mode 100644 index 0000000000..dd1e952002 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedOutboundQueueNoBarrier.java new file mode 100644 index 0000000000..76b1243a7b --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/StackedSegment.java new file mode 100644 index 0000000000..43aa002ac7 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapper.java new file mode 100644 index 0000000000..e783dc42ae --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapper.java @@ -0,0 +1,45 @@ +/* + * 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.impl.core.connection; + +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +import java.net.InetSocketAddress; + +/** + * Wraps outgoing message and includes listener attached to this message. This object + * is sent to OFEncoder. When OFEncoder fails to serialize the message, + * listener is filled with exception. The exception is then delegated to upper ODL layers. + * This object is used for UDP communication - it also carries recipient address + + * @author michal.polkorab + */ +public class UdpMessageListenerWrapper extends MessageListenerWrapper { + + private InetSocketAddress address; + + /** + * @param msg message to be sent + * @param listener listener attached to channel.write(msg) Future + * @param address recipient's address + */ + public UdpMessageListenerWrapper(Object msg, GenericFutureListener> listener, + InetSocketAddress address) { + super(msg, listener); + this.address = address; + } + + /** + * @return recipient address + */ + public InetSocketAddress getAddress() { + return address; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/ActionDeserializerInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/ActionDeserializerInitializer.java new file mode 100644 index 0000000000..1c6c5d2037 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/ActionDeserializerInitializer.java @@ -0,0 +1,92 @@ +/* + * 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; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10EnqueueActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10OutputActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetDlDstActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetDlSrcActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetNwDstActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetNwSrcActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetNwTosActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetTpDstActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetTpSrcActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetVlanPcpActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10SetVlanVidActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF10StripVlanActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13CopyTtlInActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13CopyTtlOutActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13DecMplsTtlActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13DecNwTtlActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13GroupActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13OutputActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PopMplsActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PopPbbActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PopVlanActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PushMplsActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PushPbbActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13PushVlanActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13SetFieldActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13SetMplsTtlActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13SetNwTtlActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.action.OF13SetQueueActionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.ActionDeserializerRegistryHelper; + +/** + * @author michal.polkorab + * + */ +public final class ActionDeserializerInitializer { + + private ActionDeserializerInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers action deserializers + * @param registry registry to be filled with deserializers + */ + public static void registerDeserializers(DeserializerRegistry registry) { + // register OF v1.0 action deserializers + ActionDeserializerRegistryHelper helper = + new ActionDeserializerRegistryHelper(EncodeConstants.OF10_VERSION_ID, registry); + helper.registerDeserializer(0, new OF10OutputActionDeserializer()); + helper.registerDeserializer(1, new OF10SetVlanVidActionDeserializer()); + helper.registerDeserializer(2, new OF10SetVlanPcpActionDeserializer()); + helper.registerDeserializer(3, new OF10StripVlanActionDeserializer()); + helper.registerDeserializer(4, new OF10SetDlSrcActionDeserializer()); + helper.registerDeserializer(5, new OF10SetDlDstActionDeserializer()); + helper.registerDeserializer(6, new OF10SetNwSrcActionDeserializer()); + helper.registerDeserializer(7, new OF10SetNwDstActionDeserializer()); + helper.registerDeserializer(8, new OF10SetNwTosActionDeserializer()); + helper.registerDeserializer(9, new OF10SetTpSrcActionDeserializer()); + helper.registerDeserializer(10, new OF10SetTpDstActionDeserializer()); + helper.registerDeserializer(11, new OF10EnqueueActionDeserializer()); + // register OF v1.3 action deserializers + helper = new ActionDeserializerRegistryHelper(EncodeConstants.OF13_VERSION_ID, registry); + helper.registerDeserializer(0, new OF13OutputActionDeserializer()); + helper.registerDeserializer(11, new OF13CopyTtlOutActionDeserializer()); + helper.registerDeserializer(12, new OF13CopyTtlInActionDeserializer()); + helper.registerDeserializer(15, new OF13SetMplsTtlActionDeserializer()); + helper.registerDeserializer(16, new OF13DecMplsTtlActionDeserializer()); + helper.registerDeserializer(17, new OF13PushVlanActionDeserializer()); + helper.registerDeserializer(18, new OF13PopVlanActionDeserializer()); + helper.registerDeserializer(19, new OF13PushMplsActionDeserializer()); + helper.registerDeserializer(20, new OF13PopMplsActionDeserializer()); + helper.registerDeserializer(21, new OF13SetQueueActionDeserializer()); + helper.registerDeserializer(22, new OF13GroupActionDeserializer()); + helper.registerDeserializer(23, new OF13SetNwTtlActionDeserializer()); + helper.registerDeserializer(24, new OF13DecNwTtlActionDeserializer()); + helper.registerDeserializer(25, new OF13SetFieldActionDeserializer()); + helper.registerDeserializer(26, new OF13PushPbbActionDeserializer()); + helper.registerDeserializer(27, new OF13PopPbbActionDeserializer()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/AdditionalMessageDeserializerInitializer.java new file mode 100644 index 0000000000..33fc1ac138 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java new file mode 100644 index 0000000000..de631b11fa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactory.java @@ -0,0 +1,88 @@ +/* + * 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; + +import io.netty.buffer.ByteBuf; +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.yangtools.yang.binding.DataObject; + +/** + * @author michal.polkorab + * @author timotej.kubas + * @author giuseppex.petralia@intel.com + */ +public class DeserializationFactory { + + private final Map> messageClassMap = new ConcurrentHashMap<>(); + private DeserializerRegistry registry; + + /** + * Constructor + */ + public DeserializationFactory() { + 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 + * @return correct POJO as DataObject + */ + public DataObject deserialize(final ByteBuf rawMessage, final short version) { + DataObject dataObject = null; + 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)); + 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 + */ + public void setRegistry(final DeserializerRegistry registry) { + this.registry = registry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java new file mode 100644 index 0000000000..7ba0f2c393 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImpl.java @@ -0,0 +1,102 @@ +/* + * 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; + +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; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.MatchDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.OF10MatchDeserializer; +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.v10.grouping.MatchV10; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Stores and registers deserializers + * + * @author michal.polkorab + */ +public class DeserializerRegistryImpl implements DeserializerRegistry { + + private static final Logger LOG = LoggerFactory.getLogger(DeserializerRegistryImpl.class); + private Map registry; + + /** + * Decoder table provisioning + */ + @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()); + + // register match entry deserializers + MatchEntryDeserializerInitializer.registerMatchEntryDeserializers(this); + // register action deserializers + ActionDeserializerInitializer.registerDeserializers(this); + // register instruction deserializers + InstructionDeserializerInitializer.registerDeserializers(this); + } + + @Override + @SuppressWarnings("unchecked") + public T getDeserializer(MessageCodeKey key) { + OFGeneralDeserializer deserializer = registry.get(key); + if (deserializer == null) { + throw new IllegalStateException("Deserializer for key: " + key + + " was not found - please verify that all needed deserializers ale loaded correctly"); + } + return (T) deserializer; + } + + @Override + 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) { + 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); + } + } + + @Override + public boolean unregisterDeserializer(MessageCodeKey key) { + if (key == null) { + throw new IllegalArgumentException("MessageCodeKey is null"); + } + OFGeneralDeserializer deserializer = registry.remove(key); + if (deserializer == null) { + return false; + } + return true; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/InstructionDeserializerInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/InstructionDeserializerInitializer.java new file mode 100644 index 0000000000..40cae2c4bb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/InstructionDeserializerInitializer.java @@ -0,0 +1,46 @@ +/* + * 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; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.ApplyActionsInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.ClearActionsInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.GoToTableInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.MeterInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.WriteActionsInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.instruction.WriteMetadataInstructionDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionDeserializerRegistryHelper; + +/** + * @author michal.polkorab + * + */ +public final class InstructionDeserializerInitializer { + + private InstructionDeserializerInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers instruction deserializers + * @param registry registry to be filled with deserializers + */ + public static void registerDeserializers(DeserializerRegistry registry) { + // register OF v1.3 instruction deserializers + InstructionDeserializerRegistryHelper helper = + new InstructionDeserializerRegistryHelper(EncodeConstants.OF13_VERSION_ID, registry); + helper.registerDeserializer(1, new GoToTableInstructionDeserializer()); + helper.registerDeserializer(2, new WriteMetadataInstructionDeserializer()); + helper.registerDeserializer(3, new WriteActionsInstructionDeserializer()); + helper.registerDeserializer(4, new ApplyActionsInstructionDeserializer()); + helper.registerDeserializer(5, new ClearActionsInstructionDeserializer()); + helper.registerDeserializer(6, new MeterInstructionDeserializer()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java new file mode 100644 index 0000000000..98d1b34e72 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MatchEntryDeserializerInitializer.java @@ -0,0 +1,120 @@ +/* + * 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; + +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; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmArpThaDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmArpTpaDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmEthDstDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmEthSrcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmEthTypeDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIcmpv4CodeDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIcmpv4TypeDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIcmpv6CodeDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIcmpv6TypeDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmInPhyPortDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmInPortDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpDscpDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpEcnDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpProtoDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv4DstDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv4SrcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6DstDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6ExtHdrDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6FlabelDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6NdSllDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6NdTargetDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6NdTllDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmIpv6SrcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmMetadataDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmMplsBosDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmMplsLabelDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmMplsTcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmPbbIsidDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmSctpDstDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmSctpSrcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmTcpDstDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmTcpSrcDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmTunnelIdDeserializer; +import org.opendaylight.openflowjava.protocol.impl.deserialization.match.OxmUdpDstDeserializer; +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.impl.deserialization.match.ext.OnfOxmTcpFlagsDeserializer; +import org.opendaylight.openflowjava.protocol.impl.util.MatchEntryDeserializerRegistryHelper; + +/** + * Util class for init registration of match entry deserializers. + * @author michal.polkorab + */ +public final class MatchEntryDeserializerInitializer { + + private MatchEntryDeserializerInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers match entry deserializers. + * @param registry registry to be filled with deserializers + */ + public static void registerMatchEntryDeserializers(DeserializerRegistry registry) { + // register OpenflowBasicClass match entry deserializers + MatchEntryDeserializerRegistryHelper helper = + new MatchEntryDeserializerRegistryHelper(EncodeConstants.OF13_VERSION_ID, + OxmMatchConstants.OPENFLOW_BASIC_CLASS, registry); + helper.register(OxmMatchConstants.IN_PORT, new OxmInPortDeserializer()); + helper.register(OxmMatchConstants.IN_PHY_PORT, new OxmInPhyPortDeserializer()); + helper.register(OxmMatchConstants.METADATA, new OxmMetadataDeserializer()); + helper.register(OxmMatchConstants.ETH_DST, new OxmEthDstDeserializer()); + helper.register(OxmMatchConstants.ETH_SRC, new OxmEthSrcDeserializer()); + helper.register(OxmMatchConstants.ETH_TYPE, new OxmEthTypeDeserializer()); + helper.register(OxmMatchConstants.VLAN_VID, new OxmVlanVidDeserializer()); + helper.register(OxmMatchConstants.VLAN_PCP, new OxmVlanPcpDeserializer()); + helper.register(OxmMatchConstants.IP_DSCP, new OxmIpDscpDeserializer()); + helper.register(OxmMatchConstants.IP_ECN, new OxmIpEcnDeserializer()); + helper.register(OxmMatchConstants.IP_PROTO, new OxmIpProtoDeserializer()); + helper.register(OxmMatchConstants.IPV4_SRC, new OxmIpv4SrcDeserializer()); + helper.register(OxmMatchConstants.IPV4_DST, new OxmIpv4DstDeserializer()); + helper.register(OxmMatchConstants.TCP_SRC, new OxmTcpSrcDeserializer()); + helper.register(OxmMatchConstants.TCP_DST, new OxmTcpDstDeserializer()); + helper.register(OxmMatchConstants.UDP_SRC, new OxmUdpSrcDeserializer()); + helper.register(OxmMatchConstants.UDP_DST, new OxmUdpDstDeserializer()); + helper.register(OxmMatchConstants.SCTP_SRC, new OxmSctpSrcDeserializer()); + helper.register(OxmMatchConstants.SCTP_DST, new OxmSctpDstDeserializer()); + helper.register(OxmMatchConstants.ICMPV4_TYPE, new OxmIcmpv4TypeDeserializer()); + helper.register(OxmMatchConstants.ICMPV4_CODE, new OxmIcmpv4CodeDeserializer()); + helper.register(OxmMatchConstants.ARP_OP, new OxmArpOpDeserializer()); + helper.register(OxmMatchConstants.ARP_SPA, new OxmArpSpaDeserializer()); + helper.register(OxmMatchConstants.ARP_TPA, new OxmArpTpaDeserializer()); + helper.register(OxmMatchConstants.ARP_SHA, new OxmArpShaDeserializer()); + helper.register(OxmMatchConstants.ARP_THA, new OxmArpThaDeserializer()); + helper.register(OxmMatchConstants.IPV6_SRC, new OxmIpv6SrcDeserializer()); + helper.register(OxmMatchConstants.IPV6_DST, new OxmIpv6DstDeserializer()); + helper.register(OxmMatchConstants.IPV6_FLABEL, new OxmIpv6FlabelDeserializer()); + helper.register(OxmMatchConstants.ICMPV6_TYPE, new OxmIcmpv6TypeDeserializer()); + helper.register(OxmMatchConstants.ICMPV6_CODE, new OxmIcmpv6CodeDeserializer()); + helper.register(OxmMatchConstants.IPV6_ND_TARGET, new OxmIpv6NdTargetDeserializer()); + helper.register(OxmMatchConstants.IPV6_ND_SLL, new OxmIpv6NdSllDeserializer()); + helper.register(OxmMatchConstants.IPV6_ND_TLL, new OxmIpv6NdTllDeserializer()); + helper.register(OxmMatchConstants.MPLS_LABEL, new OxmMplsLabelDeserializer()); + helper.register(OxmMatchConstants.MPLS_TC, new OxmMplsTcDeserializer()); + helper.register(OxmMatchConstants.MPLS_BOS, new OxmMplsBosDeserializer()); + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java new file mode 100644 index 0000000000..79873cc1b4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageDeserializerInitializer.java @@ -0,0 +1,120 @@ +/* + * 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; + +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.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.OF10HelloMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PacketInMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10PortStatusMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10QueueGetConfigReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.OF10StatsReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.deserialization.factories.PacketInMessageFactory; +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.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; +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.PortStatusMessage; +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 { + + private MessageDeserializerInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers 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(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, 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKey.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKey.java new file mode 100644 index 0000000000..d623297e73 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKey.java @@ -0,0 +1,74 @@ +/* + * 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; + + +/** + * Class used as a key in {@link DeserializerRegistryImpl} + * @author michal.polkorab + * @author timotej.kubas + */ +public class MessageTypeCodeKey { + + private final short msgType; + private final short msgVersion; + + /** + * @param msgVersion protocol version + * @param msgType type code of message + */ + public MessageTypeCodeKey(short msgVersion, short msgType) { + this.msgType = msgType; + this.msgVersion = msgVersion; + } + + /** + * @return the msgType + */ + public short getMsgType() { + return msgType; + } + + /** + * @return the msgVersion + */ + public short getMsgVersion() { + return msgVersion; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + msgType; + result = prime * result + msgVersion; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + MessageTypeCodeKey other = (MessageTypeCodeKey) obj; + if (msgType != other.msgType) { + return false; + } + if (msgVersion != other.msgVersion) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java new file mode 100644 index 0000000000..61fe027f62 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializer.java @@ -0,0 +1,163 @@ +/* + * 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; + +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.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 { + + private TypeToClassMapInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Initializes standard types mapping. + * @param messageClassMap type to class map + */ + public static void initializeTypeToClassMap(final Map> messageClassMap) { + TypeToClassInitHelper helper; + + // init OF v1.0 mapping + 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); + helper.registerTypeToClass((short) 3, EchoOutput.class); + helper.registerTypeToClass((short) 4, ExperimenterMessage.class); + helper.registerTypeToClass((short) 6, GetFeaturesOutput.class); + helper.registerTypeToClass((short) 8, GetConfigOutput.class); + helper.registerTypeToClass((short) 10, PacketInMessage.class); + helper.registerTypeToClass((short) 11, FlowRemovedMessage.class); + helper.registerTypeToClass((short) 12, PortStatusMessage.class); + helper.registerTypeToClass((short) 17, MultipartReplyMessage.class); + helper.registerTypeToClass((short) 19, BarrierOutput.class); + helper.registerTypeToClass((short) 21, GetQueueConfigOutput.class); + + // 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); + helper.registerTypeToClass((short) 2, EchoRequestMessage.class); + helper.registerTypeToClass((short) 3, EchoOutput.class); + helper.registerTypeToClass((short) 4, ExperimenterMessage.class); + helper.registerTypeToClass((short) 6, GetFeaturesOutput.class); + helper.registerTypeToClass((short) 8, GetConfigOutput.class); + helper.registerTypeToClass((short) 10, PacketInMessage.class); + helper.registerTypeToClass((short) 11, FlowRemovedMessage.class); + helper.registerTypeToClass((short) 12, PortStatusMessage.class); + helper.registerTypeToClass((short) 19, MultipartReplyMessage.class); + helper.registerTypeToClass((short) 21, BarrierOutput.class); + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/AbstractActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/AbstractActionDeserializer.java new file mode 100644 index 0000000000..10c65f5b65 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/AbstractActionDeserializer.java @@ -0,0 +1,37 @@ +/* + * 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.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +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.action.rev150203.action.grouping.ActionChoice; +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; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractActionDeserializer implements OFDeserializer, + HeaderDeserializer { + + @Override + public Action deserializeHeader(ByteBuf input) { + ActionBuilder actionBuilder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + actionBuilder.setActionChoice(getType()); + return actionBuilder.build(); + } + + protected abstract ActionChoice getType(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10EnqueueActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10EnqueueActionDeserializer.java new file mode 100644 index 0000000000..d4416dcd6f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10EnqueueActionDeserializer.java @@ -0,0 +1,49 @@ +/* + * 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.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.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.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.enqueue._case.EnqueueActionBuilder; +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.common.types.rev130731.QueueId; + +/** + * @author michal.polkorab + * + */ +public class OF10EnqueueActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + EnqueueCaseBuilder caseBuilder = new EnqueueCaseBuilder(); + EnqueueActionBuilder actionBuilder = new EnqueueActionBuilder(); + actionBuilder.setPort(new PortNumber((long) input.readUnsignedShort())); + input.skipBytes(ActionConstants.PADDING_IN_ENQUEUE_ACTION); + actionBuilder.setQueueId(new QueueId(input.readUnsignedInt())); + caseBuilder.setEnqueueAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new OutputActionCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10OutputActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10OutputActionDeserializer.java new file mode 100644 index 0000000000..073e9c5fc1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10OutputActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.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.PortNumber; + +/** + * @author michal.polkorab + * + */ +public class OF10OutputActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder actionBuilder = new OutputActionBuilder(); + actionBuilder.setPort(new PortNumber((long) input.readUnsignedShort())); + actionBuilder.setMaxLength(input.readUnsignedShort()); + caseBuilder.setOutputAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new OutputActionCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java new file mode 100644 index 0000000000..d212eee886 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlDstActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetDlDstActionDeserializer extends AbstractActionDeserializer { + + @Override + 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(); + actionBuilder.setDlDstAddress(ByteBufUtils.readIetfMacAddress(input)); + caseBuilder.setSetDlDstAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetDlDstCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java new file mode 100644 index 0000000000..9ca56a9064 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetDlSrcActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetDlSrcActionDeserializer extends AbstractActionDeserializer { + + @Override + 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(); + actionBuilder.setDlSrcAddress(ByteBufUtils.readIetfMacAddress(input)); + caseBuilder.setSetDlSrcAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetDlSrcCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java new file mode 100644 index 0000000000..14ea5fcc61 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwDstActionDeserializer.java @@ -0,0 +1,43 @@ +/* + * 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.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.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; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwDstActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(final ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetNwDstCaseBuilder caseBuilder = new SetNwDstCaseBuilder(); + SetNwDstActionBuilder actionBuilder = new SetNwDstActionBuilder(); + actionBuilder.setIpAddress(ByteBufUtils.readIetfIpv4Address(input)); + caseBuilder.setSetNwDstAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetNwDstCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java new file mode 100644 index 0000000000..9c982c21a9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwSrcActionDeserializer.java @@ -0,0 +1,43 @@ +/* + * 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.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.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; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwSrcActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(final ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetNwSrcCaseBuilder caseBuilder = new SetNwSrcCaseBuilder(); + SetNwSrcActionBuilder actionBuilder = new SetNwSrcActionBuilder(); + actionBuilder.setIpAddress(ByteBufUtils.readIetfIpv4Address(input)); + caseBuilder.setSetNwSrcAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetNwSrcCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwTosActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwTosActionDeserializer.java new file mode 100644 index 0000000000..bec85f5086 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetNwTosActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetNwTosCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.tos._case.SetNwTosActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwTosActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetNwTosCaseBuilder caseBuilder = new SetNwTosCaseBuilder(); + SetNwTosActionBuilder tosBuilder = new SetNwTosActionBuilder(); + tosBuilder.setNwTos(input.readUnsignedByte()); + caseBuilder.setSetNwTosAction(tosBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_SET_NW_TOS_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetNwTosCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpDstActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpDstActionDeserializer.java new file mode 100644 index 0000000000..39643a8864 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpDstActionDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.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.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.SetTpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.tp.dst._case.SetTpDstActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetTpDstActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetTpDstCaseBuilder caseBuilder = new SetTpDstCaseBuilder(); + SetTpDstActionBuilder actionBuilder = new SetTpDstActionBuilder(); + actionBuilder.setPort(new PortNumber((long) input.readUnsignedShort())); + caseBuilder.setSetTpDstAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_TP_PORT_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetTpDstCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpSrcActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpSrcActionDeserializer.java new file mode 100644 index 0000000000..b07f69fc62 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetTpSrcActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetTpSrcCaseBuilder; +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.PortNumber; + +/** + * @author michal.polkorab + * + */ +public class OF10SetTpSrcActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetTpSrcCaseBuilder caseBuilder = new SetTpSrcCaseBuilder(); + SetTpSrcActionBuilder actionBuilder = new SetTpSrcActionBuilder(); + actionBuilder.setPort(new PortNumber((long) input.readUnsignedShort())); + caseBuilder.setSetTpSrcAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_TP_PORT_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetTpSrcCaseBuilder().build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanPcpActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanPcpActionDeserializer.java new file mode 100644 index 0000000000..5431f1bafe --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanPcpActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetVlanPcpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.vlan.pcp._case.SetVlanPcpActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetVlanPcpActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetVlanPcpCaseBuilder caseBuilder = new SetVlanPcpCaseBuilder(); + SetVlanPcpActionBuilder actionBuilder = new SetVlanPcpActionBuilder(); + actionBuilder.setVlanPcp(input.readUnsignedByte()); + caseBuilder.setSetVlanPcpAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_SET_VLAN_PCP_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetVlanPcpCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanVidActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanVidActionDeserializer.java new file mode 100644 index 0000000000..5bef7e195c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10SetVlanVidActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetVlanVidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.vlan.vid._case.SetVlanVidActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetVlanVidActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetVlanVidCaseBuilder caseBuilder = new SetVlanVidCaseBuilder(); + SetVlanVidActionBuilder actionBuilder = new SetVlanVidActionBuilder(); + actionBuilder.setVlanVid(input.readUnsignedShort()); + caseBuilder.setSetVlanVidAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.PADDING_IN_SET_VLAN_VID_ACTION); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetVlanVidCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10StripVlanActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10StripVlanActionDeserializer.java new file mode 100644 index 0000000000..d7c94e9ff8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF10StripVlanActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.StripVlanCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10StripVlanActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new StripVlanCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlInActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlInActionDeserializer.java new file mode 100644 index 0000000000..dbf2cc9ef4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlInActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.CopyTtlInCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13CopyTtlInActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new CopyTtlInCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlOutActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlOutActionDeserializer.java new file mode 100644 index 0000000000..a5997fcac2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13CopyTtlOutActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.CopyTtlOutCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13CopyTtlOutActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new CopyTtlOutCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecMplsTtlActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecMplsTtlActionDeserializer.java new file mode 100644 index 0000000000..2f19396228 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecMplsTtlActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.DecMplsTtlCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13DecMplsTtlActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new DecMplsTtlCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecNwTtlActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecNwTtlActionDeserializer.java new file mode 100644 index 0000000000..d2b9cf7c6d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13DecNwTtlActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.DecNwTtlCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13DecNwTtlActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new DecNwTtlCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13GroupActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13GroupActionDeserializer.java new file mode 100644 index 0000000000..15455bbc4b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13GroupActionDeserializer.java @@ -0,0 +1,43 @@ +/* + * 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.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.GroupCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.group._case.GroupActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13GroupActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + GroupCaseBuilder caseBuilder = new GroupCaseBuilder(); + GroupActionBuilder actionBuilder = new GroupActionBuilder(); + actionBuilder.setGroupId(input.readUnsignedInt()); + caseBuilder.setGroupAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new GroupCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13OutputActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13OutputActionDeserializer.java new file mode 100644 index 0000000000..47f0c72aed --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13OutputActionDeserializer.java @@ -0,0 +1,47 @@ +/* + * 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.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.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.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.PortNumber; + +/** + * @author michal.polkorab + * + */ +public class OF13OutputActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder actionBuilder = new OutputActionBuilder(); + actionBuilder.setPort(new PortNumber(input.readUnsignedInt())); + actionBuilder.setMaxLength(input.readUnsignedShort()); + caseBuilder.setOutputAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.OUTPUT_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new OutputActionCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopMplsActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopMplsActionDeserializer.java new file mode 100644 index 0000000000..3ab74229b8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopMplsActionDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.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.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.PopMplsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.pop.mpls._case.PopMplsActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13PopMplsActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + PopMplsCaseBuilder caseBuilder = new PopMplsCaseBuilder(); + PopMplsActionBuilder mplsBuilder = new PopMplsActionBuilder(); + mplsBuilder.setEthertype(new EtherType(input.readUnsignedShort())); + caseBuilder.setPopMplsAction(mplsBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.ETHERTYPE_ACTION_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PopMplsCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopPbbActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopPbbActionDeserializer.java new file mode 100644 index 0000000000..d67923b7bb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopPbbActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.PopPbbCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13PopPbbActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PopPbbCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopVlanActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopVlanActionDeserializer.java new file mode 100644 index 0000000000..28ad449068 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PopVlanActionDeserializer.java @@ -0,0 +1,40 @@ +/* + * 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.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.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.PopVlanCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13PopVlanActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setActionChoice(getType()); + input.skipBytes(ActionConstants.PADDING_IN_ACTION_HEADER); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PopVlanCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushMplsActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushMplsActionDeserializer.java new file mode 100644 index 0000000000..9419181ff5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushMplsActionDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.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.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.PushMplsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.mpls._case.PushMplsActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13PushMplsActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + PushMplsCaseBuilder caseBuilder = new PushMplsCaseBuilder(); + PushMplsActionBuilder mplsBuilder = new PushMplsActionBuilder(); + mplsBuilder.setEthertype(new EtherType(input.readUnsignedShort())); + caseBuilder.setPushMplsAction(mplsBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.ETHERTYPE_ACTION_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PushMplsCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushPbbActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushPbbActionDeserializer.java new file mode 100644 index 0000000000..085bbd7bb0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushPbbActionDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.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.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.PushPbbCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.pbb._case.PushPbbActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13PushPbbActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + PushPbbCaseBuilder caseBuilder = new PushPbbCaseBuilder(); + PushPbbActionBuilder pbbBuilder = new PushPbbActionBuilder(); + pbbBuilder.setEthertype(new EtherType(input.readUnsignedShort())); + caseBuilder.setPushPbbAction(pbbBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.ETHERTYPE_ACTION_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PushPbbCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushVlanActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushVlanActionDeserializer.java new file mode 100644 index 0000000000..d45356dd33 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13PushVlanActionDeserializer.java @@ -0,0 +1,46 @@ +/* + * 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.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.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.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; + +/** + * @author michal.polkorab + * + */ +public class OF13PushVlanActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + PushVlanCaseBuilder caseBuilder = new PushVlanCaseBuilder(); + PushVlanActionBuilder vlanBuilder = new PushVlanActionBuilder(); + vlanBuilder.setEthertype(new EtherType(input.readUnsignedShort())); + caseBuilder.setPushVlanAction(vlanBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.ETHERTYPE_ACTION_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new PushVlanCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetFieldActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetFieldActionDeserializer.java new file mode 100644 index 0000000000..442f6d9416 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetFieldActionDeserializer.java @@ -0,0 +1,78 @@ +/* + * 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.action; + +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.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.SetFieldCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.field._case.SetFieldActionBuilder; +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.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * @author michal.polkorab + * + */ +public class OF13SetFieldActionDeserializer extends AbstractActionDeserializer + implements DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + @Override + public Action deserialize(ByteBuf input) { + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + int startIndex = input.readerIndex(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetFieldCaseBuilder caseBuilder = new SetFieldCaseBuilder(); + SetFieldActionBuilder actionBuilder = new SetFieldActionBuilder(); + int oxmClass = input.getUnsignedShort(input.readerIndex()); + // get oxm_field & hasMask byte and extract the field value + int oxmField = input.getUnsignedByte(input.readerIndex() + + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1; + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + oxmClass, oxmField); + if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) { + long expId = input.getUnsignedInt(input.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES + + 2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + key.setExperimenterId(expId); + } + OFDeserializer matchDeserializer = registry.getDeserializer(key); + List entry = new ArrayList<>(); + entry.add(matchDeserializer.deserialize(input)); + actionBuilder.setMatchEntry(entry); + caseBuilder.setSetFieldAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + int paddingRemainder = (input.readerIndex() - startIndex) % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + input.skipBytes(EncodeConstants.PADDING - paddingRemainder); + } + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetFieldCaseBuilder().build(); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.registry = deserializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetMplsTtlActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetMplsTtlActionDeserializer.java new file mode 100644 index 0000000000..2f5abcb9ae --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetMplsTtlActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetMplsTtlCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.mpls.ttl._case.SetMplsTtlActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13SetMplsTtlActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetMplsTtlCaseBuilder caseBuilder = new SetMplsTtlCaseBuilder(); + SetMplsTtlActionBuilder actionBuilder = new SetMplsTtlActionBuilder(); + actionBuilder.setMplsTtl(input.readUnsignedByte()); + caseBuilder.setSetMplsTtlAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.SET_MPLS_TTL_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetMplsTtlCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetNwTtlActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetNwTtlActionDeserializer.java new file mode 100644 index 0000000000..9d1bcaa71f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetNwTtlActionDeserializer.java @@ -0,0 +1,45 @@ +/* + * 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.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.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.SetNwTtlCaseBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13SetNwTtlActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetNwTtlCaseBuilder caseBuilder = new SetNwTtlCaseBuilder(); + SetNwTtlActionBuilder actionBuilder = new SetNwTtlActionBuilder(); + actionBuilder.setNwTtl(input.readUnsignedByte()); + caseBuilder.setSetNwTtlAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + input.skipBytes(ActionConstants.SET_NW_TTL_PADDING); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetNwTtlCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetQueueActionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetQueueActionDeserializer.java new file mode 100644 index 0000000000..38d2b77d0e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/action/OF13SetQueueActionDeserializer.java @@ -0,0 +1,43 @@ +/* + * 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.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.SetQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.queue._case.SetQueueActionBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13SetQueueActionDeserializer extends AbstractActionDeserializer { + + @Override + public Action deserialize(ByteBuf input) { + ActionBuilder builder = new ActionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + SetQueueCaseBuilder caseBuilder = new SetQueueCaseBuilder(); + SetQueueActionBuilder actionBuilder = new SetQueueActionBuilder(); + actionBuilder.setQueueId(input.readUnsignedInt()); + caseBuilder.setSetQueueAction(actionBuilder.build()); + builder.setActionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + protected ActionChoice getType() { + return new SetQueueCaseBuilder().build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactory.java new file mode 100644 index 0000000000..2af6be440d --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java new file mode 100644 index 0000000000..4d5cf784bb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactory.java @@ -0,0 +1,32 @@ +/* + * 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.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.BarrierOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; + +/** + * Translates BarrierReply messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author michal.polkorab + * @author timotej.kubas + */ +public class BarrierReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { + + @Override + public BarrierOutput deserialize(ByteBuf rawMessage) { + BarrierOutputBuilder builder = new BarrierOutputBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java new file mode 100644 index 0000000000..217071fb16 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactory.java @@ -0,0 +1,39 @@ +/* + * 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.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.EchoOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutputBuilder; + +/** + * Translates EchoReply messages. + * OpenFlow protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { + + @Override + public EchoOutput deserialize(ByteBuf rawMessage) { + EchoOutputBuilder builder = new EchoOutputBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); + } + return builder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java new file mode 100644 index 0000000000..a765a2d3f1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactory.java @@ -0,0 +1,35 @@ +/* + * 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.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.EchoRequestMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; + +/** + * Translates EchoRequest messages. + * OpenFlow protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoRequestMessageFactory extends VersionAssignableFactory implements OFDeserializer{ + + @Override + public EchoRequestMessage deserialize(ByteBuf rawMessage) { + EchoRequestMessageBuilder builder = new EchoRequestMessageBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + builder.setData(data); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java new file mode 100644 index 0000000000..b11da58c36 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactory.java @@ -0,0 +1,254 @@ +/* + * 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.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.BadActionCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadInstructionCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadMatchCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadRequestCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.GroupModFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterModFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortModFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueOpFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.RoleRequestFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.SwitchConfigFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableFeaturesFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableModFailedCode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; + +/** + * Translates Error messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class ErrorMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final String UNKNOWN_CODE = "UNKNOWN_CODE"; + private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE"; + private DeserializerRegistry registry; + + @Override + public ErrorMessage deserialize(ByteBuf rawMessage) { + int startIndex = rawMessage.readerIndex(); + ErrorMessageBuilder builder = new ErrorMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + ErrorType errorType = ErrorType.forValue(type); + if (ErrorType.EXPERIMENTER.equals(errorType)) { + OFDeserializer deserializer = registry.getDeserializer( + ExperimenterDeserializerKeyFactory.createExperimenterErrorDeserializerKey( + EncodeConstants.OF13_VERSION_ID, rawMessage.getUnsignedInt( + rawMessage.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES))); + rawMessage.readerIndex(startIndex); + return deserializer.deserialize(rawMessage); + } + decodeType(builder, errorType, type); + decodeCode(rawMessage, builder, errorType); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); + } + return builder.build(); + } + + private static void decodeType(ErrorMessageBuilder builder, ErrorType type, int readValue) { + if (type != null) { + builder.setType(type.getIntValue()); + builder.setTypeString(type.name()); + } else { + builder.setType(readValue); + builder.setTypeString(UNKNOWN_TYPE); + } + } + + private static void decodeCode(ByteBuf rawMessage, ErrorMessageBuilder builder, + ErrorType type) { + int code = rawMessage.readUnsignedShort(); + if (type != null) { + switch (type) { + case HELLOFAILED: + { + HelloFailedCode errorCode = HelloFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADREQUEST: + { + BadRequestCode errorCode = BadRequestCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADACTION: + { + BadActionCode errorCode = BadActionCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADINSTRUCTION: + { + BadInstructionCode errorCode = BadInstructionCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADMATCH: + { + BadMatchCode errorCode = BadMatchCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case FLOWMODFAILED: + { + FlowModFailedCode errorCode = FlowModFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case GROUPMODFAILED: + { + GroupModFailedCode errorCode = GroupModFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case PORTMODFAILED: + { + PortModFailedCode errorCode = PortModFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case TABLEMODFAILED: + { + TableModFailedCode errorCode = TableModFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case QUEUEOPFAILED: + { + QueueOpFailedCode errorCode = QueueOpFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case SWITCHCONFIGFAILED: + { + SwitchConfigFailedCode errorCode = SwitchConfigFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case ROLEREQUESTFAILED: + { + RoleRequestFailedCode errorCode = RoleRequestFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case METERMODFAILED: + { + MeterModFailedCode errorCode = MeterModFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case TABLEFEATURESFAILED: + { + TableFeaturesFailedCode errorCode = TableFeaturesFailedCode.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + default: + setUnknownCode(builder, code); + break; + } + } else { + setUnknownCode(builder, code); + } + } + + private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) { + builder.setCode(readValue); + builder.setCodeString(UNKNOWN_CODE); + } + + private static void setCode(ErrorMessageBuilder builder, int code, String codeString) { + builder.setCode(code); + builder.setCodeString(codeString); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.registry = deserializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java new file mode 100644 index 0000000000..244b4bfa1a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactory.java @@ -0,0 +1,55 @@ +/* + * 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.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 ExperimenterMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private DeserializerRegistry deserializerRegistry; + + @Override + public ExperimenterMessage deserialize(ByteBuf message) { + 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, 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 + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.deserializerRegistry = deserializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactory.java new file mode 100644 index 0000000000..b599c208df --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactory.java @@ -0,0 +1,59 @@ +/* + * 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 java.math.BigInteger; + +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.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; + +/** + * Translates FeaturesReply messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class FeaturesReplyMessageFactory implements OFDeserializer{ + + private static final byte PADDING_IN_FEATURES_REPLY_HEADER = 2; + + @Override + public GetFeaturesOutput deserialize(ByteBuf rawMessage) { + GetFeaturesOutputBuilder builder = new GetFeaturesOutputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + byte[] datapathId = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(datapathId); + builder.setDatapathId(new BigInteger(1, datapathId)); + builder.setBuffers(rawMessage.readUnsignedInt()); + builder.setTables(rawMessage.readUnsignedByte()); + builder.setAuxiliaryId(rawMessage.readUnsignedByte()); + rawMessage.skipBytes(PADDING_IN_FEATURES_REPLY_HEADER); + builder.setCapabilities(createCapabilities(rawMessage.readUnsignedInt())); + builder.setReserved(rawMessage.readUnsignedInt()); + return builder.build(); + } + + private static Capabilities createCapabilities(long input) { + final Boolean flowStats = (input & (1 << 0)) != 0; + final Boolean tableStats = (input & (1 << 1)) != 0; + final Boolean portStats = (input & (1 << 2)) != 0; + final Boolean groupStats = (input & (1 << 3)) != 0; + final Boolean ipReasm = (input & (1 << 5)) != 0; + final Boolean queueStats = (input & (1 << 6)) != 0; + final Boolean portBlocked = (input & (1 << 8)) != 0; + return new Capabilities(flowStats, groupStats, ipReasm, + portBlocked, portStats, queueStats, tableStats); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactory.java new file mode 100644 index 0000000000..1531c8ebf0 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactory.java new file mode 100644 index 0000000000..05ababb3dd --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactory.java @@ -0,0 +1,67 @@ +/* + * 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 java.math.BigInteger; + +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.FlowRemovedReason; +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.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; + +/** + * Translates FlowRemoved messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class FlowRemovedMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + @Override + public FlowRemovedMessage deserialize(ByteBuf rawMessage) { + FlowRemovedMessageBuilder builder = new FlowRemovedMessageBuilder(); + 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)); + builder.setPriority(rawMessage.readUnsignedShort()); + builder.setReason(FlowRemovedReason.forValue(rawMessage.readUnsignedByte())); + builder.setTableId(new TableId((long)rawMessage.readUnsignedByte())); + builder.setDurationSec(rawMessage.readUnsignedInt()); + builder.setDurationNsec(rawMessage.readUnsignedInt()); + builder.setIdleTimeout(rawMessage.readUnsignedShort()); + builder.setHardTimeout(rawMessage.readUnsignedShort()); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(packetCount); + builder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(byteCount); + builder.setByteCount(new BigInteger(1, byteCount)); + OFDeserializer matchDeserializer = registry.getDeserializer(new MessageCodeKey( + EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class)); + builder.setMatch(matchDeserializer.deserialize(rawMessage)); + return builder.build(); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactory.java new file mode 100644 index 0000000000..39d757cc78 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactory.java @@ -0,0 +1,127 @@ +/* + * 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 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.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; + +/** + * Translates GetAsyncReply messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class GetAsyncReplyMessageFactory implements OFDeserializer { + + private static final byte SEPARATE_ROLES = 2; + + @Override + public GetAsyncOutput deserialize(ByteBuf rawMessage) { + GetAsyncOutputBuilder builder = new GetAsyncOutputBuilder(); + 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 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 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 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 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 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactory.java new file mode 100644 index 0000000000..6a3485ec18 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactory.java new file mode 100644 index 0000000000..84bb66faba --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..c8c8071cda --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactory.java @@ -0,0 +1,35 @@ +/* + * 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.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +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. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author michal.polkorab + * @author timotej.kubas + */ +public class GetConfigReplyMessageFactory extends VersionAssignableFactory implements OFDeserializer { + + @Override + public GetConfigOutput deserialize(ByteBuf rawMessage) { + GetConfigOutputBuilder builder = new GetConfigOutputBuilder(); + builder.setVersion(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setFlags(SwitchConfigFlag.forValue(rawMessage.readUnsignedShort())); + builder.setMissSendLen(rawMessage.readUnsignedShort()); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java new file mode 100644 index 0000000000..4295644c7c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputMessageFactory.java @@ -0,0 +1,25 @@ +/* + * 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.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; + +public class GetFeaturesInputMessageFactory implements OFDeserializer { + + @Override + public GetFeaturesInput deserialize(ByteBuf rawMessage) { + GetFeaturesInputBuilder builder = new GetFeaturesInputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + return builder.build(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactory.java new file mode 100644 index 0000000000..8b63dac547 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactory.java new file mode 100644 index 0000000000..5d7de02b1a --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java new file mode 100644 index 0000000000..50cf33c1c3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactory.java @@ -0,0 +1,79 @@ +/* + * 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 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; +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; + +/** + * Translates Hello messages. + * OF protocol versions: 1.3, 1.4, 1.5. + * @author michal.polkorab + * @author timotej.kubas + */ +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(getVersion()); + builder.setXid(rawMessage.readUnsignedInt()); + if (rawMessage.readableBytes() > 0) { + builder.setElements(readElement(rawMessage)); + } + return builder.build(); + } + + private static List readElement(ByteBuf input) { + List elementsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + ElementsBuilder elementsBuilder = new ElementsBuilder(); + int type = input.readUnsignedShort(); + int elementLength = input.readUnsignedShort(); + if (type == HelloElementType.VERSIONBITMAP.getIntValue()) { + elementsBuilder.setType(HelloElementType.forValue(type)); + int[] versionBitmap = new int[(elementLength - HELLO_ELEMENT_HEADER_SIZE) / 4]; + for (int i = 0; i < versionBitmap.length; i++) { + versionBitmap[i] = (int) input.readUnsignedInt(); + } + elementsBuilder.setVersionBitmap(readVersionBitmap(versionBitmap)); + int paddingRemainder = elementLength % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + input.readBytes(EncodeConstants.PADDING - paddingRemainder); + } + } else { + return elementsList; + } + elementsList.add(elementsBuilder.build()); + } + return elementsList; + } + + private static List readVersionBitmap(int[] input){ + List versionBitmapList = new ArrayList<>(); + for (int i = 0; i < input.length; i++) { + int mask = input[i]; + for (int j = 0; j < Integer.SIZE; j++) { + versionBitmapList.add((mask & (1 << j)) != 0); + } + } + return versionBitmapList; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactory.java new file mode 100644 index 0000000000..0196b4b42a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactory.java @@ -0,0 +1,108 @@ +/* + * 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.util.ExperimenterDeserializerKeyFactory; +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.MeterModInputBuilder; +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; +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 MeterModInputMessageFactory implements OFDeserializer, 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java new file mode 100644 index 0000000000..62ebf38f00 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactory.java @@ -0,0 +1,890 @@ +/* + * 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 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.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; +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.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.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.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; +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.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.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; +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.MultipartReplyTableFeaturesCase; +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; +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.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.MultipartReplyGroupFeaturesBuilder; +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.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.MultipartReplyMeterFeaturesBuilder; +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.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.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; +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; + +/** + * Translates MultipartReply messages + * + * @author timotej.kubas + * @author michal.polkorab + */ +public class MultipartReplyMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final byte PADDING_IN_MULTIPART_REPLY_HEADER = 4; + private static final int DESC_STR_LEN = 256; + private static final int SERIAL_NUM_LEN = 32; + private static final byte PADDING_IN_FLOW_STATS_HEADER_01 = 1; + private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 4; + private static final byte PADDING_IN_AGGREGATE_HEADER = 4; + private static final byte PADDING_IN_TABLE_HEADER = 3; + private static final byte PADDING_IN_MULTIPART_REPLY_TABLE_FEATURES = 5; + private static final byte MAX_TABLE_NAME_LENGTH = 32; + private static final byte MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH = 64; + private static final byte COMMON_PROPERTY_LENGTH = 4; + private static final byte PADDING_IN_PORT_STATS_HEADER = 4; + private static final byte PADDING_IN_GROUP_HEADER_01 = 2; + private static final byte PADDING_IN_GROUP_HEADER_02 = 4; + private static final byte BUCKET_COUNTER_LENGTH = 16; + private static final byte GROUP_BODY_LENGTH = 40; + private static final byte PADDING_IN_METER_FEATURES_HEADER = 2; + private static final byte PADDING_IN_METER_STATS_HEADER = 6; + private static final byte METER_BAND_STATS_LENGTH = 16; + private static final byte METER_BODY_LENGTH = 40; + private static final byte METER_CONFIG_LENGTH = 8; + private static final byte PADDING_IN_METER_BAND_DROP_HEADER = 4; + private static final byte PADDING_IN_METER_BAND_DSCP_HEADER = 3; + private static final byte PADDING_IN_PORT_DESC_HEADER_01 = 4; + private static final byte PADDING_IN_PORT_DESC_HEADER_02 = 2; + private static final int GROUP_TYPES = 4; + private static final byte PADDING_IN_GROUP_DESC_HEADER = 1; + private static final byte PADDING_IN_BUCKETS_HEADER = 4; + private static final byte GROUP_DESC_HEADER_LENGTH = 8; + private static final byte BUCKETS_HEADER_LENGTH = 16; + private DeserializerRegistry registry; + + @Override + public MultipartReplyMessage deserialize(final ByteBuf rawMessage) { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + builder.setType(MultipartType.forValue(type)); + builder.setFlags(new MultipartRequestFlags((rawMessage.readUnsignedShort() & 0x01) != 0)); + rawMessage.skipBytes(PADDING_IN_MULTIPART_REPLY_HEADER); + + 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 OFPMPGROUP: + builder.setMultipartReplyBody(setGroup(rawMessage)); + break; + case OFPMPGROUPDESC: + builder.setMultipartReplyBody(setGroupDesc(rawMessage)); + break; + case OFPMPGROUPFEATURES: + builder.setMultipartReplyBody(setGroupFeatures(rawMessage)); + break; + case OFPMPMETER: + builder.setMultipartReplyBody(setMeter(rawMessage)); + break; + case OFPMPMETERCONFIG: + builder.setMultipartReplyBody(setMeterConfig(rawMessage)); + break; + case OFPMPMETERFEATURES: + builder.setMultipartReplyBody(setMeterFeatures(rawMessage)); + break; + case OFPMPTABLEFEATURES: + builder.setMultipartReplyBody(setTableFeatures(rawMessage)); + break; + case OFPMPPORTDESC: + builder.setMultipartReplyBody(setPortDesc(rawMessage)); + break; + case OFPMPEXPERIMENTER: + builder.setMultipartReplyBody(setExperimenter(rawMessage)); + break; + default: + break; + } + + return builder.build(); + } + + private static MultipartReplyDescCase setDesc(final ByteBuf input) { + MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder(); + byte[] mfrDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(mfrDescBytes); + String mfrDesc = new String(mfrDescBytes); + descBuilder.setMfrDesc(mfrDesc.trim()); + byte[] hwDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(hwDescBytes); + String hwDesc = new String(hwDescBytes); + descBuilder.setHwDesc(hwDesc.trim()); + byte[] swDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(swDescBytes); + String swDesc = new String(swDescBytes); + descBuilder.setSwDesc(swDesc.trim()); + byte[] serialNumBytes = new byte[SERIAL_NUM_LEN]; + input.readBytes(serialNumBytes); + String serialNum = new String(serialNumBytes); + descBuilder.setSerialNum(serialNum.trim()); + byte[] dpDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(dpDescBytes); + String dpDesc = new String(dpDescBytes); + descBuilder.setDpDesc(dpDesc.trim()); + caseBuilder.setMultipartReplyDesc(descBuilder.build()); + return caseBuilder.build(); + } + + private MultipartReplyFlowCase setFlow(final ByteBuf input) { + MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder(); + MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder(); + List flowStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder(); + int flowRecordLength = input.readUnsignedShort(); + ByteBuf subInput = input.readSlice(flowRecordLength - EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + flowStatsBuilder.setTableId(subInput.readUnsignedByte()); + subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_01); + flowStatsBuilder.setDurationSec(subInput.readUnsignedInt()); + flowStatsBuilder.setDurationNsec(subInput.readUnsignedInt()); + flowStatsBuilder.setPriority(subInput.readUnsignedShort()); + flowStatsBuilder.setIdleTimeout(subInput.readUnsignedShort()); + flowStatsBuilder.setHardTimeout(subInput.readUnsignedShort()); + flowStatsBuilder.setFlags(createFlowModFlagsFromBitmap(subInput.readUnsignedShort())); + subInput.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + subInput.readBytes(cookie); + flowStatsBuilder.setCookie(new BigInteger(1, cookie)); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + subInput.readBytes(packetCount); + flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + subInput.readBytes(byteCount); + flowStatsBuilder.setByteCount(new BigInteger(1, byteCount)); + OFDeserializer matchDeserializer = registry.getDeserializer(new MessageCodeKey( + EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class)); + flowStatsBuilder.setMatch(matchDeserializer.deserialize(subInput)); + CodeKeyMaker keyMaker = CodeKeyMakerFactory + .createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List instructions = ListDeserializer.deserializeList( + EncodeConstants.OF13_VERSION_ID, subInput.readableBytes(), subInput, keyMaker, registry); + flowStatsBuilder.setInstruction(instructions); + flowStatsList.add(flowStatsBuilder.build()); + } + flowBuilder.setFlowStats(flowStatsList); + caseBuilder.setMultipartReplyFlow(flowBuilder.build()); + return caseBuilder.build(); + } + + 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; + final Boolean fmfNOPKTCOUNTS = (input & (1 << 3)) != 0; + final Boolean fmfNOBYTCOUNTS = (input & (1 << 4)) != 0; + return new FlowModFlags(fmfCHECKOVERLAP, fmfNOBYTCOUNTS, fmfNOPKTCOUNTS, fmfRESETCOUNTS, fmfSENDFLOWREM); + } + + 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]; + input.readBytes(packetCount); + builder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteCount); + builder.setByteCount(new BigInteger(1, byteCount)); + builder.setFlowCount(input.readUnsignedInt()); + input.skipBytes(PADDING_IN_AGGREGATE_HEADER); + caseBuilder.setMultipartReplyAggregate(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyTableCase setTable(final ByteBuf input) { + MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder(); + MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder(); + List tableStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + TableStatsBuilder tableStatsBuilder = new TableStatsBuilder(); + tableStatsBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_TABLE_HEADER); + tableStatsBuilder.setActiveCount(input.readUnsignedInt()); + byte[] lookupCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(lookupCount); + tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount)); + byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(matchedCount); + tableStatsBuilder.setMatchedCount(new BigInteger(1, matchedCount)); + tableStatsList.add(tableStatsBuilder.build()); + } + builder.setTableStats(tableStatsList); + caseBuilder.setMultipartReplyTable(builder.build()); + return caseBuilder.build(); + } + + private MultipartReplyTableFeaturesCase setTableFeatures(final ByteBuf input) { + MultipartReplyTableFeaturesCaseBuilder caseBuilder = new MultipartReplyTableFeaturesCaseBuilder(); + MultipartReplyTableFeaturesBuilder builder = new MultipartReplyTableFeaturesBuilder(); + 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_REPLY_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(metadataMatch); + byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataWrite); + featuresBuilder.setMetadataWrite(metadataWrite); + featuresBuilder.setConfig(createTableConfig(input.readUnsignedInt())); + featuresBuilder.setMaxEntries(input.readUnsignedInt()); + featuresBuilder.setTableFeatureProperties(createTableFeaturesProperties(input, + length - MULTIPART_REPLY_TABLE_FEATURES_STRUCTURE_LENGTH)); + features.add(featuresBuilder.build()); + } + builder.setTableFeatures(features); + caseBuilder.setMultipartReplyTableFeatures(builder.build()); + return caseBuilder.build(); + } + + private static TableConfig createTableConfig(final long input) { + boolean deprecated = (input & 3) != 0; + return new TableConfig(deprecated); + } + + private List createTableFeaturesProperties(final ByteBuf input, final 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 MultipartReplyPortStatsCase setPortStats(final ByteBuf input) { + MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder(); + MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder(); + List portStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + PortStatsBuilder portStatsBuilder = new PortStatsBuilder(); + portStatsBuilder.setPortNo(input.readUnsignedInt()); + input.skipBytes(PADDING_IN_PORT_STATS_HEADER); + byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxPackets); + portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets)); + byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txPackets); + portStatsBuilder.setTxPackets(new BigInteger(1, txPackets)); + byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxBytes); + portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes)); + byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txBytes); + portStatsBuilder.setTxBytes(new BigInteger(1, txBytes)); + byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxDropped); + portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped)); + byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txDropped); + portStatsBuilder.setTxDropped(new BigInteger(1, txDropped)); + byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxErrors); + portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors)); + byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txErrors); + portStatsBuilder.setTxErrors(new BigInteger(1, txErrors)); + byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxFrameErr); + portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr)); + byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxOverErr); + portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr)); + byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxCrcErr); + portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr)); + byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(collisions); + portStatsBuilder.setCollisions(new BigInteger(1, collisions)); + portStatsBuilder.setDurationSec(input.readUnsignedInt()); + portStatsBuilder.setDurationNsec(input.readUnsignedInt()); + portStatsList.add(portStatsBuilder.build()); + } + builder.setPortStats(portStatsList); + caseBuilder.setMultipartReplyPortStats(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyQueueCase setQueue(final ByteBuf input) { + MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder(); + MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder(); + List queueStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder(); + queueStatsBuilder.setPortNo(input.readUnsignedInt()); + queueStatsBuilder.setQueueId(input.readUnsignedInt()); + byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txBytes); + queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes)); + byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txPackets); + queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets)); + byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txErrors); + queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors)); + queueStatsBuilder.setDurationSec(input.readUnsignedInt()); + queueStatsBuilder.setDurationNsec(input.readUnsignedInt()); + queueStatsList.add(queueStatsBuilder.build()); + } + builder.setQueueStats(queueStatsList); + caseBuilder.setMultipartReplyQueue(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyGroupCase setGroup(final ByteBuf input) { + MultipartReplyGroupCaseBuilder caseBuilder = new MultipartReplyGroupCaseBuilder(); + MultipartReplyGroupBuilder builder = new MultipartReplyGroupBuilder(); + List groupStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + GroupStatsBuilder groupStatsBuilder = new GroupStatsBuilder(); + int bodyLength = input.readUnsignedShort(); + input.skipBytes(PADDING_IN_GROUP_HEADER_01); + groupStatsBuilder.setGroupId(new GroupId(input.readUnsignedInt())); + groupStatsBuilder.setRefCount(input.readUnsignedInt()); + input.skipBytes(PADDING_IN_GROUP_HEADER_02); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetCount); + groupStatsBuilder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteCount); + groupStatsBuilder.setByteCount(new BigInteger(1, byteCount)); + groupStatsBuilder.setDurationSec(input.readUnsignedInt()); + groupStatsBuilder.setDurationNsec(input.readUnsignedInt()); + int actualLength = GROUP_BODY_LENGTH; + List bucketStatsList = new ArrayList<>(); + while (actualLength < bodyLength) { + BucketStatsBuilder bucketStatsBuilder = new BucketStatsBuilder(); + byte[] packetCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetCountBucket); + bucketStatsBuilder.setPacketCount(new BigInteger(1, packetCountBucket)); + byte[] byteCountBucket = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteCountBucket); + bucketStatsBuilder.setByteCount(new BigInteger(1, byteCountBucket)); + bucketStatsList.add(bucketStatsBuilder.build()); + actualLength += BUCKET_COUNTER_LENGTH; + } + groupStatsBuilder.setBucketStats(bucketStatsList); + groupStatsList.add(groupStatsBuilder.build()); + } + builder.setGroupStats(groupStatsList); + caseBuilder.setMultipartReplyGroup(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyMeterFeaturesCase setMeterFeatures(final ByteBuf input) { + MultipartReplyMeterFeaturesCaseBuilder caseBuilder = new MultipartReplyMeterFeaturesCaseBuilder(); + MultipartReplyMeterFeaturesBuilder builder = new MultipartReplyMeterFeaturesBuilder(); + builder.setMaxMeter(input.readUnsignedInt()); + builder.setBandTypes(createMeterBandsBitmap(input.readUnsignedInt())); + builder.setCapabilities(createMeterFlags(input.readUnsignedInt())); + builder.setMaxBands(input.readUnsignedByte()); + builder.setMaxColor(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_METER_FEATURES_HEADER); + caseBuilder.setMultipartReplyMeterFeatures(builder.build()); + return caseBuilder.build(); + } + + 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; + final Boolean mfSTATS = (input & (1 << 3)) != 0; + return new MeterFlags(mfBURST, mfKBPS, mfPKTPS, mfSTATS); + } + + 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(final ByteBuf input) { + MultipartReplyMeterCaseBuilder caseBuilder = new MultipartReplyMeterCaseBuilder(); + MultipartReplyMeterBuilder builder = new MultipartReplyMeterBuilder(); + List meterStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + MeterStatsBuilder meterStatsBuilder = new MeterStatsBuilder(); + meterStatsBuilder.setMeterId(new MeterId(input.readUnsignedInt())); + int meterStatsBodyLength = input.readUnsignedShort(); + input.skipBytes(PADDING_IN_METER_STATS_HEADER); + meterStatsBuilder.setFlowCount(input.readUnsignedInt()); + byte[] packetInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetInCount); + meterStatsBuilder.setPacketInCount(new BigInteger(1, packetInCount)); + byte[] byteInCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteInCount); + meterStatsBuilder.setByteInCount(new BigInteger(1, byteInCount)); + meterStatsBuilder.setDurationSec(input.readUnsignedInt()); + meterStatsBuilder.setDurationNsec(input.readUnsignedInt()); + int actualLength = METER_BODY_LENGTH; + List meterBandStatsList = new ArrayList<>(); + while (actualLength < meterStatsBodyLength) { + MeterBandStatsBuilder meterBandStatsBuilder = new MeterBandStatsBuilder(); + byte[] packetBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetBandCount); + meterBandStatsBuilder.setPacketBandCount(new BigInteger(1, packetBandCount)); + byte[] byteBandCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteBandCount); + meterBandStatsBuilder.setByteBandCount(new BigInteger(1, byteBandCount)); + meterBandStatsList.add(meterBandStatsBuilder.build()); + actualLength += METER_BAND_STATS_LENGTH; + } + meterStatsBuilder.setMeterBandStats(meterBandStatsList); + meterStatsList.add(meterStatsBuilder.build()); + } + builder.setMeterStats(meterStatsList); + caseBuilder.setMultipartReplyMeter(builder.build()); + return caseBuilder.build(); + } + + private MultipartReplyMeterConfigCase setMeterConfig(final ByteBuf input) { + MultipartReplyMeterConfigCaseBuilder caseBuilder = new MultipartReplyMeterConfigCaseBuilder(); + MultipartReplyMeterConfigBuilder builder = new MultipartReplyMeterConfigBuilder(); + List meterConfigList = new ArrayList<>(); + while (input.readableBytes() > 0) { + MeterConfigBuilder meterConfigBuilder = new MeterConfigBuilder(); + int meterConfigBodyLength = input.readUnsignedShort(); + meterConfigBuilder.setFlags(createMeterFlags(input.readUnsignedShort())); + meterConfigBuilder.setMeterId(new MeterId(input.readUnsignedInt())); + int actualLength = METER_CONFIG_LENGTH; + List bandsList = new ArrayList<>(); + while (actualLength < meterConfigBodyLength) { + int bandStartIndex = input.readerIndex(); + BandsBuilder bandsBuilder = new BandsBuilder(); + int bandType = input.readUnsignedShort(); + switch (bandType) { + case 1: + MeterBandDropCaseBuilder bandDropCaseBuilder = new MeterBandDropCaseBuilder(); + MeterBandDropBuilder bandDropBuilder = new MeterBandDropBuilder(); + bandDropBuilder.setType(MeterBandType.forValue(bandType)); + actualLength += input.readUnsignedShort(); + bandDropBuilder.setRate(input.readUnsignedInt()); + bandDropBuilder.setBurstSize(input.readUnsignedInt()); + input.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)); + actualLength += input.readUnsignedShort(); + bandDscpRemarkBuilder.setRate(input.readUnsignedInt()); + bandDscpRemarkBuilder.setBurstSize(input.readUnsignedInt()); + bandDscpRemarkBuilder.setPrecLevel(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_METER_BAND_DSCP_HEADER); + bandDscpRemarkCaseBuilder.setMeterBandDscpRemark(bandDscpRemarkBuilder.build()); + bandsBuilder.setMeterBand(bandDscpRemarkCaseBuilder.build()); + break; + case 0xFFFF: + actualLength += input.readUnsignedShort(); + long expId = input.getUnsignedInt(input.readerIndex() + 2 * EncodeConstants.SIZE_OF_INT_IN_BYTES); + input.readerIndex(bandStartIndex); + OFDeserializer deserializer = registry.getDeserializer( + ExperimenterDeserializerKeyFactory.createMeterBandDeserializerKey( + EncodeConstants.OF13_VERSION_ID, expId)); + bandsBuilder.setMeterBand(deserializer.deserialize(input)); + break; + default: + break; + } + bandsList.add(bandsBuilder.build()); + } + meterConfigBuilder.setBands(bandsList); + meterConfigList.add(meterConfigBuilder.build()); + } + builder.setMeterConfig(meterConfigList); + caseBuilder.setMultipartReplyMeterConfig(builder.build()); + return caseBuilder.build(); + } + + 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(final ByteBuf input) { + MultipartReplyPortDescCaseBuilder caseBuilder = new MultipartReplyPortDescCaseBuilder(); + MultipartReplyPortDescBuilder builder = new MultipartReplyPortDescBuilder(); + List portsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + PortsBuilder portsBuilder = new PortsBuilder(); + portsBuilder.setPortNo(input.readUnsignedInt()); + input.skipBytes(PADDING_IN_PORT_DESC_HEADER_01); + 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())); + portsBuilder.setState(createPortState(input.readUnsignedInt())); + portsBuilder.setCurrentFeatures(createPortFeatures(input.readUnsignedInt())); + portsBuilder.setAdvertisedFeatures(createPortFeatures(input.readUnsignedInt())); + portsBuilder.setSupportedFeatures(createPortFeatures(input.readUnsignedInt())); + portsBuilder.setPeerFeatures(createPortFeatures(input.readUnsignedInt())); + portsBuilder.setCurrSpeed(input.readUnsignedInt()); + portsBuilder.setMaxSpeed(input.readUnsignedInt()); + portsList.add(portsBuilder.build()); + } + builder.setPorts(portsList); + caseBuilder.setMultipartReplyPortDesc(builder.build()); + return caseBuilder.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 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(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(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++) { + maxGroupsList.add(rawMessage.readUnsignedInt()); + } + featuresBuilder.setMaxGroups(maxGroupsList); + List actionBitmaps = new ArrayList<>(); + for (int i = 0; i < GROUP_TYPES; i++) { + actionBitmaps.add(createActionBitmap(rawMessage.readUnsignedInt())); + } + featuresBuilder.setActionsBitmap(actionBitmaps); + caseBuilder.setMultipartReplyGroupFeatures(featuresBuilder.build()); + return caseBuilder.build(); + } + + 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, + atPopPBB, atPopVLAN, atPushMPLS, atPushPBB, atPushVLAN, + atSetField, atSetMplsTTL, atSetNWTTL, atSetQueue); + } + + 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(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(final ByteBuf input) { + MultipartReplyGroupDescCaseBuilder caseBuilder = new MultipartReplyGroupDescCaseBuilder(); + MultipartReplyGroupDescBuilder builder = new MultipartReplyGroupDescBuilder(); + List groupDescsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + GroupDescBuilder groupDescBuilder = new GroupDescBuilder(); + int bodyLength = input.readUnsignedShort(); + groupDescBuilder.setType(GroupType.forValue(input.readUnsignedByte())); + input.skipBytes(PADDING_IN_GROUP_DESC_HEADER); + groupDescBuilder.setGroupId(new GroupId(input.readUnsignedInt())); + int actualLength = GROUP_DESC_HEADER_LENGTH; + List bucketsList = new ArrayList<>(); + while (actualLength < bodyLength) { + BucketsListBuilder bucketsBuilder = new BucketsListBuilder(); + int bucketsLength = input.readUnsignedShort(); + bucketsBuilder.setWeight(input.readUnsignedShort()); + bucketsBuilder.setWatchPort(new PortNumber(input.readUnsignedInt())); + bucketsBuilder.setWatchGroup(input.readUnsignedInt()); + input.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, input, keyMaker, registry); + bucketsBuilder.setAction(actions); + bucketsList.add(bucketsBuilder.build()); + actualLength += bucketsLength; + } + groupDescBuilder.setBucketsList(bucketsList); + groupDescsList.add(groupDescBuilder.build()); + } + builder.setGroupDesc(groupDescsList); + caseBuilder.setMultipartReplyGroupDesc(builder.build()); + return caseBuilder.build(); + } + + @Override + public void injectDeserializerRegistry( + final DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestInputMessageFactory.java new file mode 100644 index 0000000000..008b22c3ac --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java new file mode 100644 index 0000000000..aa8b9c8d53 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactory.java @@ -0,0 +1,146 @@ +/* + * 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.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.BadActionCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.BadRequestCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorTypeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFailedCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloFailedCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortModFailedCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.QueueOpFailedCodeV10; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; + +/** + * Translates Error messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10ErrorMessageFactory implements OFDeserializer { + + private static final String UNKNOWN_TYPE = "UNKNOWN_TYPE"; + private static final String UNKNOWN_CODE = "UNKNOWN_CODE"; + + @Override + public ErrorMessage deserialize(ByteBuf rawMessage) { + ErrorMessageBuilder builder = new ErrorMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + ErrorTypeV10 errorType = ErrorTypeV10.forValue(type); + decodeType(builder, errorType, type); + decodeCode(rawMessage, builder, errorType); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + byte[] data = new byte[remainingBytes]; + rawMessage.readBytes(data); + builder.setData(data); + } + return builder.build(); + } + + private static void decodeType(ErrorMessageBuilder builder, ErrorTypeV10 type, int readValue) { + if (type != null) { + builder.setType(type.getIntValue()); + builder.setTypeString(type.name()); + } else { + builder.setType(readValue); + builder.setTypeString(UNKNOWN_TYPE); + } + } + + private static void decodeCode(ByteBuf rawMessage, ErrorMessageBuilder builder, + ErrorTypeV10 type) { + int code = rawMessage.readUnsignedShort(); + if (type != null) { + switch (type) { + case HELLOFAILED: + { + HelloFailedCodeV10 errorCode = HelloFailedCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADREQUEST: + { + BadRequestCodeV10 errorCode = BadRequestCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case BADACTION: + { + BadActionCodeV10 errorCode = BadActionCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case FLOWMODFAILED: + { + FlowModFailedCodeV10 errorCode = FlowModFailedCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case PORTMODFAILED: + { + PortModFailedCodeV10 errorCode = PortModFailedCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + case QUEUEOPFAILED: + { + QueueOpFailedCodeV10 errorCode = QueueOpFailedCodeV10.forValue(code); + if (errorCode != null) { + setCode(builder, errorCode.getIntValue(), errorCode.name()); + } else { + setUnknownCode(builder, code); + } + break; + } + default: + setUnknownCode(builder, code); + break; + } + } else { + setUnknownCode(builder, code); + } + } + + private static void setUnknownCode(ErrorMessageBuilder builder, int readValue) { + builder.setCode(readValue); + builder.setCodeString(UNKNOWN_CODE); + } + + private static void setCode(ErrorMessageBuilder builder, int code, String codeString) { + builder.setCode(code); + builder.setCodeString(codeString); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java new file mode 100644 index 0000000000..c94b0d1138 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactory.java @@ -0,0 +1,100 @@ +/* + * 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 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.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; +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; + +/** + * Translates FeaturesReply messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10FeaturesReplyMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_FEATURES_REPLY_HEADER = 3; + + @Override + public GetFeaturesOutput deserialize(final ByteBuf rawMessage) { + GetFeaturesOutputBuilder builder = new GetFeaturesOutputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + byte[] datapathId = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(datapathId); + builder.setDatapathId(new BigInteger(1, datapathId)); + builder.setBuffers(rawMessage.readUnsignedInt()); + builder.setTables(rawMessage.readUnsignedByte()); + rawMessage.skipBytes(PADDING_IN_FEATURES_REPLY_HEADER); + builder.setCapabilitiesV10(createCapabilitiesV10(rawMessage.readUnsignedInt())); + builder.setActionsV10(createActionsV10(rawMessage.readUnsignedInt())); + List ports = new ArrayList<>(); + while (rawMessage.readableBytes() > 0) { + ports.add(deserializePort(rawMessage)); + } + builder.setPhyPort(ports); + return builder.build(); + } + + private static CapabilitiesV10 createCapabilitiesV10(final long input) { + final Boolean flowStats = (input & (1 << 0)) != 0; + final Boolean tableStats = (input & (1 << 1)) != 0; + final Boolean portStats = (input & (1 << 2)) != 0; + final Boolean stp = (input & (1 << 3)) != 0; + final Boolean reserved = (input & (1 << 4)) != 0; + final Boolean ipReasm = (input & (1 << 5)) != 0; + final Boolean queueStats = (input & (1 << 6)) != 0; + final Boolean arpMatchIp = (input & (1 << 7)) != 0; + return new CapabilitiesV10(arpMatchIp, flowStats, ipReasm, + portStats, queueStats, reserved, stp, tableStats); + } + + private static ActionTypeV10 createActionsV10(final long input) { + final Boolean output = (input & (1 << 0)) != 0; + final Boolean setVLANvid = (input & (1 << 1)) != 0; + final Boolean setVLANpcp = (input & (1 << 2)) != 0; + final Boolean stripVLAN = (input & (1 << 3)) != 0; + final Boolean setDLsrc = (input & (1 << 4)) != 0; + final Boolean setDLdst = (input & (1 << 5)) != 0; + final Boolean setNWsrc = (input & (1 << 6)) != 0; + final Boolean setNWdst = (input & (1 << 7)) != 0; + final Boolean setNWtos = (input & (1 << 8)) != 0; + final Boolean setTPsrc = (input & (1 << 9)) != 0; + final Boolean setTPdst = (input & (1 << 10)) != 0; + final Boolean enqueue = (input & (1 << 11)) != 0; + final Boolean vendor = (input & (1 << 12)) != 0; + return new ActionTypeV10(enqueue, output, setDLdst, setDLsrc, + setNWdst, setNWsrc, setNWtos, setTPdst, setTPsrc, + setVLANpcp, setVLANvid, stripVLAN, vendor); + } + + private static PhyPort deserializePort(final ByteBuf rawMessage) { + PhyPortBuilder builder = new PhyPortBuilder(); + builder.setPortNo((long) rawMessage.readUnsignedShort()); + builder.setHwAddr(ByteBufUtils.readIetfMacAddress(rawMessage)); + builder.setName(ByteBufUtils.decodeNullTerminatedString(rawMessage, EncodeConstants.MAX_PORT_NAME_LENGTH)); + builder.setConfigV10(OpenflowUtils.createPortConfig(rawMessage.readUnsignedInt())); + builder.setStateV10(OpenflowUtils.createPortState(rawMessage.readUnsignedInt())); + builder.setCurrentFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setAdvertisedFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setSupportedFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setPeerFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + return builder.build(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactory.java new file mode 100644 index 0000000000..1ff8c7a1e5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactory.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.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10FeaturesRequestMessageFactory implements OFDeserializer { + + @Override + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactory.java new file mode 100644 index 0000000000..3357995a41 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactory.java new file mode 100644 index 0000000000..b110e2d5a0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactory.java @@ -0,0 +1,67 @@ +/* + * 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 java.math.BigInteger; + +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.FlowRemovedReason; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; + +/** + * Translates FlowRemoved messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10FlowRemovedMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final byte PADDING_IN_FLOW_REMOVED_MESSAGE = 1; + private static final byte PADDING_IN_FLOW_REMOVED_MESSAGE_2 = 2; + private DeserializerRegistry registry; + + @Override + public FlowRemovedMessage deserialize(ByteBuf rawMessage) { + FlowRemovedMessageBuilder builder = new FlowRemovedMessageBuilder(); + 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.setPriority(rawMessage.readUnsignedShort()); + builder.setReason(FlowRemovedReason.forValue(rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING_IN_FLOW_REMOVED_MESSAGE); + builder.setDurationSec(rawMessage.readUnsignedInt()); + builder.setDurationNsec(rawMessage.readUnsignedInt()); + builder.setIdleTimeout(rawMessage.readUnsignedShort()); + rawMessage.skipBytes(PADDING_IN_FLOW_REMOVED_MESSAGE_2); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(packetCount); + builder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(byteCount); + builder.setByteCount(new BigInteger(1, byteCount)); + return builder.build(); + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.java new file mode 100644 index 0000000000..7584a734a6 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactory.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.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 OF10GetQueueConfigInputMessageFactory implements OFDeserializer { + + @Override + public GetQueueConfigInput deserialize(ByteBuf rawMessage) { + GetQueueConfigInputBuilder builder = new GetQueueConfigInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setPort(new PortNumber((long) rawMessage.readUnsignedShort())); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactory.java new file mode 100644 index 0000000000..51a18867c2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactory.java @@ -0,0 +1,35 @@ +/* + * 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.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.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; + +/** + * Translates Hello messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10HelloMessageFactory implements OFDeserializer { + + @Override + public HelloMessage deserialize(ByteBuf rawMessage) { + HelloMessageBuilder builder = new HelloMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + if (rawMessage.readableBytes() > 0) { + rawMessage.skipBytes(rawMessage.readableBytes()); + } + return builder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactory.java new file mode 100644 index 0000000000..b381944534 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactory.java @@ -0,0 +1,44 @@ +/* + * 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.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.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; + +/** + * Translates PacketIn messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10PacketInMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_PACKET_IN_HEADER = 1; + + @Override + public PacketInMessage deserialize(final ByteBuf rawMessage) { + PacketInMessageBuilder builder = new PacketInMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setTotalLen(rawMessage.readUnsignedShort()); + builder.setInPort(rawMessage.readUnsignedShort()); + builder.setReason(PacketInReason.forValue(rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING_IN_PACKET_IN_HEADER); + int remainingBytes = rawMessage.readableBytes(); + if (remainingBytes > 0) { + final byte[] buf = new byte[remainingBytes]; + rawMessage.readBytes(buf); + builder.setData(buf); + } + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactory.java new file mode 100644 index 0000000000..94cce9b1d0 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactory.java new file mode 100644 index 0000000000..025f7ba405 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java new file mode 100644 index 0000000000..2bab42b6f7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactory.java @@ -0,0 +1,50 @@ +/* + * 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.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.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; + +/** + * Translates PortStatus messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10PortStatusMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_PORT_STATUS_HEADER = 7; + + @Override + public PortStatusMessage deserialize(final ByteBuf rawMessage) { + PortStatusMessageBuilder builder = new PortStatusMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setReason(PortReason.forValue(rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING_IN_PORT_STATUS_HEADER); + deserializePort(rawMessage, builder); + return builder.build(); + } + + private static void deserializePort(final ByteBuf rawMessage, final PortStatusMessageBuilder builder) { + builder.setPortNo((long) rawMessage.readUnsignedShort()); + builder.setHwAddr(ByteBufUtils.readIetfMacAddress(rawMessage)); + builder.setName(ByteBufUtils.decodeNullTerminatedString(rawMessage, EncodeConstants.MAX_PORT_NAME_LENGTH)); + builder.setConfigV10(OpenflowUtils.createPortConfig(rawMessage.readUnsignedInt())); + builder.setStateV10(OpenflowUtils.createPortState(rawMessage.readUnsignedInt())); + builder.setCurrentFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setAdvertisedFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setSupportedFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + builder.setPeerFeaturesV10(OpenflowUtils.createPortFeatures(rawMessage.readUnsignedInt())); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..6ca9474e72 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactory.java @@ -0,0 +1,85 @@ +/* + * 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 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.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; + +/** + * Translates QueueGetConfigReply messages (OpenFlow v1.0) + * @author michal.polkorab + */ +public class OF10QueueGetConfigReplyMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER = 6; + private static final byte PADDING_IN_PACKET_QUEUE_HEADER = 2; + private static final byte PADDING_IN_QUEUE_PROPERTY_HEADER = 4; + private static final byte PADDING_IN_RATE_QUEUE_PROPERTY = 6; + private static final byte PACKET_QUEUE_HEADER_LENGTH = 8; + + @Override + public GetQueueConfigOutput deserialize(ByteBuf rawMessage) { + GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setPort(new PortNumber((long) rawMessage.readUnsignedShort())); + rawMessage.skipBytes(PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER); + builder.setQueues(createQueuesList(rawMessage)); + return builder.build(); + } + + private static List createQueuesList(ByteBuf input){ + List queuesList = new ArrayList<>(); + while (input.readableBytes() > 0) { + QueuesBuilder queueBuilder = new QueuesBuilder(); + queueBuilder.setQueueId(new QueueId(input.readUnsignedInt())); + int length = input.readUnsignedShort(); + input.skipBytes(PADDING_IN_PACKET_QUEUE_HEADER); + queueBuilder.setQueueProperty(createPropertiesList(input, length - PACKET_QUEUE_HEADER_LENGTH)); + queuesList.add(queueBuilder.build()); + } + return queuesList; + } + + private static List createPropertiesList(ByteBuf input, int length){ + int propertiesLength = length; + List propertiesList = new ArrayList<>(); + while (propertiesLength > 0) { + QueuePropertyBuilder propertiesBuilder = new QueuePropertyBuilder(); + QueueProperties property = QueueProperties.forValue(input.readUnsignedShort()); + propertiesBuilder.setProperty(property); + propertiesLength -= input.readUnsignedShort(); + input.skipBytes(PADDING_IN_QUEUE_PROPERTY_HEADER); + if (property.equals(QueueProperties.OFPQTMINRATE)) { + RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder(); + rateBuilder.setRate(input.readUnsignedShort()); + propertiesBuilder.addAugmentation(RateQueueProperty.class, rateBuilder.build()); + input.skipBytes(PADDING_IN_RATE_QUEUE_PROPERTY); + } + propertiesList.add(propertiesBuilder.build()); + } + return propertiesList; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactory.java new file mode 100644 index 0000000000..f099928536 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactory.java @@ -0,0 +1,324 @@ +/* + * 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 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.protocol.impl.util.OF10MatchDeserializer; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; +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.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.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.MultipartReplyMessageBuilder; +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.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.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.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.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; +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.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; + +/** + * Translates StatsReply messages (OpenFlow v1.0) + * + * @author michal.polkorab + */ +public class OF10StatsReplyMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final int DESC_STR_LEN = 256; + private static final int SERIAL_NUM_LEN = 32; + private static final byte PADDING_IN_FLOW_STATS_HEADER = 1; + private static final byte PADDING_IN_FLOW_STATS_HEADER_02 = 6; + private static final byte PADDING_IN_AGGREGATE_HEADER = 4; + private static final byte PADDING_IN_TABLE_HEADER = 3; + private static final byte MAX_TABLE_NAME_LENGTH = 32; + private static final byte PADDING_IN_PORT_STATS_HEADER = 6; + private static final byte PADDING_IN_QUEUE_HEADER = 2; + private static final byte LENGTH_OF_FLOW_STATS = 88; + private static final int TABLE_STATS_LENGTH = 64; + private DeserializerRegistry registry; + + @Override + public MultipartReplyMessage deserialize(ByteBuf rawMessage) { + MultipartReplyMessageBuilder builder = new MultipartReplyMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + int type = rawMessage.readUnsignedShort(); + 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; + } + return builder.build(); + } + + private static MultipartReplyDescCase setDesc(ByteBuf input) { + MultipartReplyDescCaseBuilder caseBuilder = new MultipartReplyDescCaseBuilder(); + MultipartReplyDescBuilder descBuilder = new MultipartReplyDescBuilder(); + byte[] mfrDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(mfrDescBytes); + String mfrDesc = new String(mfrDescBytes); + descBuilder.setMfrDesc(mfrDesc.trim()); + byte[] hwDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(hwDescBytes); + String hwDesc = new String(hwDescBytes); + descBuilder.setHwDesc(hwDesc.trim()); + byte[] swDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(swDescBytes); + String swDesc = new String(swDescBytes); + descBuilder.setSwDesc(swDesc.trim()); + byte[] serialNumBytes = new byte[SERIAL_NUM_LEN]; + input.readBytes(serialNumBytes); + String serialNum = new String(serialNumBytes); + descBuilder.setSerialNum(serialNum.trim()); + byte[] dpDescBytes = new byte[DESC_STR_LEN]; + input.readBytes(dpDescBytes); + String dpDesc = new String(dpDescBytes); + descBuilder.setDpDesc(dpDesc.trim()); + caseBuilder.setMultipartReplyDesc(descBuilder.build()); + return caseBuilder.build(); + } + + private MultipartReplyFlowCase setFlow(ByteBuf input) { + MultipartReplyFlowCaseBuilder caseBuilder = new MultipartReplyFlowCaseBuilder(); + MultipartReplyFlowBuilder flowBuilder = new MultipartReplyFlowBuilder(); + List flowStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + FlowStatsBuilder flowStatsBuilder = new FlowStatsBuilder(); + int length = input.readUnsignedShort(); + flowStatsBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_FLOW_STATS_HEADER); + OFDeserializer matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + flowStatsBuilder.setMatchV10(matchDeserializer.deserialize(input)); + flowStatsBuilder.setDurationSec(input.readUnsignedInt()); + flowStatsBuilder.setDurationNsec(input.readUnsignedInt()); + flowStatsBuilder.setPriority(input.readUnsignedShort()); + flowStatsBuilder.setIdleTimeout(input.readUnsignedShort()); + flowStatsBuilder.setHardTimeout(input.readUnsignedShort()); + input.skipBytes(PADDING_IN_FLOW_STATS_HEADER_02); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(cookie); + flowStatsBuilder.setCookie(new BigInteger(1, cookie)); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetCount); + flowStatsBuilder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteCount); + flowStatsBuilder.setByteCount(new BigInteger(1, byteCount)); + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF10_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF10_VERSION_ID, + length - LENGTH_OF_FLOW_STATS, input, keyMaker, registry); + flowStatsBuilder.setAction(actions); + flowStatsList.add(flowStatsBuilder.build()); + } + flowBuilder.setFlowStats(flowStatsList); + caseBuilder.setMultipartReplyFlow(flowBuilder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyAggregateCase setAggregate(ByteBuf input) { + MultipartReplyAggregateCaseBuilder caseBuilder = new MultipartReplyAggregateCaseBuilder(); + MultipartReplyAggregateBuilder builder = new MultipartReplyAggregateBuilder(); + byte[] packetCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(packetCount); + builder.setPacketCount(new BigInteger(1, packetCount)); + byte[] byteCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(byteCount); + builder.setByteCount(new BigInteger(1, byteCount)); + builder.setFlowCount(input.readUnsignedInt()); + input.skipBytes(PADDING_IN_AGGREGATE_HEADER); + caseBuilder.setMultipartReplyAggregate(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyTableCase setTable(ByteBuf input) { + MultipartReplyTableCaseBuilder caseBuilder = new MultipartReplyTableCaseBuilder(); + MultipartReplyTableBuilder builder = new MultipartReplyTableBuilder(); + List tableStatsList = new ArrayList<>(); + // TODO - replace ">= TABLE_STATS_LENGTH" with "> 0" after fix in OVS switch + while (input.readableBytes() >= TABLE_STATS_LENGTH) { + TableStatsBuilder tableStatsBuilder = new TableStatsBuilder(); + tableStatsBuilder.setTableId(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_TABLE_HEADER); + tableStatsBuilder.setName(ByteBufUtils.decodeNullTerminatedString(input, MAX_TABLE_NAME_LENGTH)); + long wildcards = input.readUnsignedInt(); + tableStatsBuilder.setWildcards(OF10MatchDeserializer.createWildcards(wildcards)); + tableStatsBuilder.setNwSrcMask(OF10MatchDeserializer.decodeNwSrcMask(wildcards)); + tableStatsBuilder.setNwDstMask(OF10MatchDeserializer.decodeNwDstMask(wildcards)); + tableStatsBuilder.setMaxEntries(input.readUnsignedInt()); + tableStatsBuilder.setActiveCount(input.readUnsignedInt()); + byte[] lookupCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(lookupCount); + tableStatsBuilder.setLookupCount(new BigInteger(1, lookupCount)); + byte[] matchedCount = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(matchedCount); + tableStatsBuilder.setMatchedCount(new BigInteger(1, matchedCount)); + tableStatsList.add(tableStatsBuilder.build()); + } + input.skipBytes(input.readableBytes()); + builder.setTableStats(tableStatsList); + caseBuilder.setMultipartReplyTable(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyPortStatsCase setPortStats(ByteBuf input) { + MultipartReplyPortStatsCaseBuilder caseBuilder = new MultipartReplyPortStatsCaseBuilder(); + MultipartReplyPortStatsBuilder builder = new MultipartReplyPortStatsBuilder(); + List portStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + PortStatsBuilder portStatsBuilder = new PortStatsBuilder(); + portStatsBuilder.setPortNo((long) input.readUnsignedShort()); + input.skipBytes(PADDING_IN_PORT_STATS_HEADER); + byte[] rxPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxPackets); + portStatsBuilder.setRxPackets(new BigInteger(1, rxPackets)); + byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txPackets); + portStatsBuilder.setTxPackets(new BigInteger(1, txPackets)); + byte[] rxBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxBytes); + portStatsBuilder.setRxBytes(new BigInteger(1, rxBytes)); + byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txBytes); + portStatsBuilder.setTxBytes(new BigInteger(1, txBytes)); + byte[] rxDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxDropped); + portStatsBuilder.setRxDropped(new BigInteger(1, rxDropped)); + byte[] txDropped = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txDropped); + portStatsBuilder.setTxDropped(new BigInteger(1, txDropped)); + byte[] rxErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxErrors); + portStatsBuilder.setRxErrors(new BigInteger(1, rxErrors)); + byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txErrors); + portStatsBuilder.setTxErrors(new BigInteger(1, txErrors)); + byte[] rxFrameErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxFrameErr); + portStatsBuilder.setRxFrameErr(new BigInteger(1, rxFrameErr)); + byte[] rxOverErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxOverErr); + portStatsBuilder.setRxOverErr(new BigInteger(1, rxOverErr)); + byte[] rxCrcErr = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(rxCrcErr); + portStatsBuilder.setRxCrcErr(new BigInteger(1, rxCrcErr)); + byte[] collisions = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(collisions); + portStatsBuilder.setCollisions(new BigInteger(1, collisions)); + portStatsList.add(portStatsBuilder.build()); + } + builder.setPortStats(portStatsList); + caseBuilder.setMultipartReplyPortStats(builder.build()); + return caseBuilder.build(); + } + + private static MultipartReplyQueueCase setQueue(ByteBuf input) { + MultipartReplyQueueCaseBuilder caseBuilder = new MultipartReplyQueueCaseBuilder(); + MultipartReplyQueueBuilder builder = new MultipartReplyQueueBuilder(); + List queueStatsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + QueueStatsBuilder queueStatsBuilder = new QueueStatsBuilder(); + queueStatsBuilder.setPortNo((long) input.readUnsignedShort()); + input.skipBytes(PADDING_IN_QUEUE_HEADER); + queueStatsBuilder.setQueueId(input.readUnsignedInt()); + byte[] txBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txBytes); + queueStatsBuilder.setTxBytes(new BigInteger(1, txBytes)); + byte[] txPackets = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txPackets); + queueStatsBuilder.setTxPackets(new BigInteger(1, txPackets)); + byte[] txErrors = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(txErrors); + queueStatsBuilder.setTxErrors(new BigInteger(1, txErrors)); + queueStatsList.add(queueStatsBuilder.build()); + } + builder.setQueueStats(queueStatsList); + caseBuilder.setMultipartReplyQueue(builder.build()); + return caseBuilder.build(); + } + + private MultipartReplyExperimenterCase setExperimenter(ByteBuf input) { + 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 + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFactory.java new file mode 100644 index 0000000000..4f49f1953c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java new file mode 100644 index 0000000000..a69baeea91 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactory.java @@ -0,0 +1,64 @@ +/* + * 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 java.math.BigInteger; + +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.PacketInReason; +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.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder; + +/** + * Translates PacketIn messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class PacketInMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final byte PADDING_IN_PACKET_IN_HEADER = 2; + private static final MessageCodeKey MATCH_KEY = new MessageCodeKey( + EncodeConstants.OF13_VERSION_ID, EncodeConstants.EMPTY_VALUE, Match.class); + private DeserializerRegistry registry; + + @Override + public PacketInMessage deserialize(final ByteBuf rawMessage) { + PacketInMessageBuilder builder = new PacketInMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setBufferId(rawMessage.readUnsignedInt()); + builder.setTotalLen(rawMessage.readUnsignedShort()); + builder.setReason(PacketInReason.forValue(rawMessage.readUnsignedByte())); + builder.setTableId(new TableId((long)rawMessage.readUnsignedByte())); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + rawMessage.readBytes(cookie); + builder.setCookie(new BigInteger(1, cookie)); + OFDeserializer matchDeserializer = registry.getDeserializer(MATCH_KEY); + builder.setMatch(matchDeserializer.deserialize(rawMessage)); + rawMessage.skipBytes(PADDING_IN_PACKET_IN_HEADER); + byte[] data = new byte[rawMessage.readableBytes()]; + rawMessage.readBytes(data); + builder.setData(data); + return builder.build(); + } + + @Override + public void injectDeserializerRegistry(final DeserializerRegistry deserializerRegistry) { + registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactory.java new file mode 100644 index 0000000000..919a8e7401 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactory.java new file mode 100644 index 0000000000..55209d5d4a --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java new file mode 100644 index 0000000000..5310aa2f01 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactory.java @@ -0,0 +1,91 @@ +/* + * 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.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.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; + +/** + * Translates PortStatus messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class PortStatusMessageFactory implements OFDeserializer { + + private static final byte PADDING_IN_PORT_STATUS_HEADER = 7; + private static final byte PADDING_IN_OFP_PORT_HEADER_1 = 4; + private static final byte PADDING_IN_OFP_PORT_HEADER_2 = 2; + + @Override + public PortStatusMessage deserialize(final ByteBuf rawMessage) { + PortStatusMessageBuilder builder = new PortStatusMessageBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setReason(PortReason.forValue(rawMessage.readUnsignedByte())); + rawMessage.skipBytes(PADDING_IN_PORT_STATUS_HEADER); + builder.setPortNo(rawMessage.readUnsignedInt()); + rawMessage.skipBytes(PADDING_IN_OFP_PORT_HEADER_1); + builder.setHwAddr(ByteBufUtils.readIetfMacAddress(rawMessage)); + rawMessage.skipBytes(PADDING_IN_OFP_PORT_HEADER_2); + builder.setName(ByteBufUtils.decodeNullTerminatedString(rawMessage, EncodeConstants.MAX_PORT_NAME_LENGTH)); + builder.setConfig(createPortConfig(rawMessage.readUnsignedInt())); + builder.setState(createPortState(rawMessage.readUnsignedInt())); + builder.setCurrentFeatures(createPortFeatures(rawMessage.readUnsignedInt())); + builder.setAdvertisedFeatures(createPortFeatures(rawMessage.readUnsignedInt())); + builder.setSupportedFeatures(createPortFeatures(rawMessage.readUnsignedInt())); + builder.setPeerFeatures(createPortFeatures(rawMessage.readUnsignedInt())); + builder.setCurrSpeed(rawMessage.readUnsignedInt()); + builder.setMaxSpeed(rawMessage.readUnsignedInt()); + return builder.build(); + } + + 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 PortState createPortState(final long input){ + final Boolean psLinkDown = ((input) & (1<<0)) != 0; + final Boolean psBblocked = ((input) & (1<<1)) != 0; + final Boolean psLive = ((input) & (1<<2)) != 0; + return new PortState(psBblocked, psLinkDown, psLive); + } + + private static PortConfig createPortConfig(final long input){ + final Boolean pcPortDown = ((input) & (1<<0)) != 0; + final Boolean pcNoRecv = ((input) & (1<<2)) != 0; + final Boolean pcNoFwd = ((input) & (1<<5)) != 0; + final Boolean pcNoPacketIn = ((input) & (1<<6)) != 0; + return new PortConfig(pcNoFwd, pcNoPacketIn, pcNoRecv, pcPortDown); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..6d6f774775 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java @@ -0,0 +1,107 @@ +/* + * 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 java.util.ArrayList; +import java.util.List; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.util.ExperimenterDeserializerKeyFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.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; + +/** + * Translates QueueGetConfigReply messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class QueueGetConfigReplyMessageFactory implements OFDeserializer, + DeserializerRegistryInjector { + + private static final byte PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER = 4; + private static final byte PADDING_IN_PACKET_QUEUE_HEADER = 6; + private static final byte PADDING_IN_QUEUE_PROPERTY_HEADER = 4; + private static final int PADDING_IN_RATE_QUEUE_PROPERTY = 6; + private static final byte PACKET_QUEUE_LENGTH = 16; + private DeserializerRegistry registry; + + @Override + public GetQueueConfigOutput deserialize(ByteBuf rawMessage) { + GetQueueConfigOutputBuilder builder = new GetQueueConfigOutputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid((rawMessage.readUnsignedInt())); + builder.setPort(new PortNumber(rawMessage.readUnsignedInt())); + rawMessage.skipBytes(PADDING_IN_QUEUE_GET_CONFIG_REPLY_HEADER); + builder.setQueues(createQueuesList(rawMessage)); + return builder.build(); + } + + private List createQueuesList(ByteBuf input){ + List queuesList = new ArrayList<>(); + while (input.readableBytes() > 0) { + QueuesBuilder queueBuilder = new QueuesBuilder(); + queueBuilder.setQueueId(new QueueId(input.readUnsignedInt())); + queueBuilder.setPort(new PortNumber(input.readUnsignedInt())); + int length = input.readUnsignedShort(); + input.skipBytes(PADDING_IN_PACKET_QUEUE_HEADER); + queueBuilder.setQueueProperty(createPropertiesList(input, length - PACKET_QUEUE_LENGTH)); + queuesList.add(queueBuilder.build()); + } + return queuesList; + } + + private List createPropertiesList(ByteBuf input, int length){ + int propertiesLength = length; + List propertiesList = new ArrayList<>(); + while (propertiesLength > 0) { + int propertyStartIndex = input.readerIndex(); + QueuePropertyBuilder propertiesBuilder = new QueuePropertyBuilder(); + QueueProperties property = QueueProperties.forValue(input.readUnsignedShort()); + propertiesBuilder.setProperty(property); + int currentPropertyLength = input.readUnsignedShort(); + propertiesLength -= currentPropertyLength; + input.skipBytes(PADDING_IN_QUEUE_PROPERTY_HEADER); + if (property.equals(QueueProperties.OFPQTMINRATE) || property.equals(QueueProperties.OFPQTMAXRATE)) { + RateQueuePropertyBuilder rateBuilder = new RateQueuePropertyBuilder(); + rateBuilder.setRate(input.readUnsignedShort()); + propertiesBuilder.addAugmentation(RateQueueProperty.class, rateBuilder.build()); + input.skipBytes(PADDING_IN_RATE_QUEUE_PROPERTY); + } else if (property.equals(QueueProperties.OFPQTEXPERIMENTER)) { + long expId = input.readUnsignedInt(); + input.readerIndex(propertyStartIndex); + OFDeserializer deserializer = registry.getDeserializer( + ExperimenterDeserializerKeyFactory.createQueuePropertyDeserializerKey( + EncodeConstants.OF13_VERSION_ID, expId)); + propertiesList.add(deserializer.deserialize(input)); + continue; + } + propertiesList.add(propertiesBuilder.build()); + } + return propertiesList; + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactory.java new file mode 100644 index 0000000000..f42bd84d7b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactory.java @@ -0,0 +1,42 @@ +/* + * 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 java.math.BigInteger; + +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.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; + +/** + * Translates RoleReply messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class RoleReplyMessageFactory implements OFDeserializer{ + + private static final byte PADDING_IN_ROLE_REPLY_HEADER = 4; + + @Override + public RoleRequestOutput deserialize(ByteBuf rawMessage) { + RoleRequestOutputBuilder builder = new RoleRequestOutputBuilder(); + builder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + builder.setXid(rawMessage.readUnsignedInt()); + builder.setRole(ControllerRole.forValue((int) rawMessage.readUnsignedInt())); + rawMessage.skipBytes(PADDING_IN_ROLE_REPLY_HEADER); + byte[] generationID = new byte[8]; + rawMessage.readBytes(generationID); + builder.setGenerationId(new BigInteger(1, generationID)); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactory.java new file mode 100644 index 0000000000..1627f2b589 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactory.java @@ -0,0 +1,38 @@ +/* + * 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.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.ControllerRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInputBuilder; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class RoleRequestInputMessageFactory 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactory.java new file mode 100644 index 0000000000..af18069e52 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java new file mode 100644 index 0000000000..5dc4c9b507 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactory.java @@ -0,0 +1,34 @@ +/* + * 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.common.types.rev130731.SwitchConfigFlag; +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 SetConfig messages. + * OF protocol versions: 1.0, 1.3, 1.4, 1.5. + * @author giuseppex.petralia@intel.com + */ +public class SetConfigInputMessageFactory extends VersionAssignableFactory implements OFDeserializer { + + @Override + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactory.java new file mode 100644 index 0000000000..425bc579e6 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java new file mode 100644 index 0000000000..9461da1c9c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactory.java @@ -0,0 +1,51 @@ +/* + * 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.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 DeserializerRegistry deserializerRegistry; + + @Override + public ExperimenterMessage deserialize(ByteBuf message) { + final long xid = message.readUnsignedInt(); + final long expId = message.readUnsignedInt(); + OFDeserializer deserializer = deserializerRegistry.getDeserializer( + ExperimenterDeserializerKeyFactory.createVendorMessageDeserializerKey( + EncodeConstants.OF10_VERSION_ID, expId)); + 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 + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.deserializerRegistry = deserializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractActionInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractActionInstructionDeserializer.java new file mode 100644 index 0000000000..2d17ed63ee --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractActionInstructionDeserializer.java @@ -0,0 +1,51 @@ +/* + * 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.instruction; + +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.InstructionConstants; +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.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractActionInstructionDeserializer implements OFDeserializer, + DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + protected List deserializeActions(ByteBuf input, int instructionLength) { + int length = instructionLength - InstructionConstants.STANDARD_INSTRUCTION_LENGTH; + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeList( + EncodeConstants.OF13_VERSION_ID, length, input, keyMaker, getRegistry()); + return actions; + } + + protected DeserializerRegistry getRegistry() { + return registry; + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ApplyActionsInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ApplyActionsInstructionDeserializer.java new file mode 100644 index 0000000000..ff5bffce92 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ApplyActionsInstructionDeserializer.java @@ -0,0 +1,50 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.apply.actions._case.ApplyActionsBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class ApplyActionsInstructionDeserializer extends AbstractActionInstructionDeserializer + implements HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + int instructionLength = input.readUnsignedShort(); + input.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + ApplyActionsCaseBuilder caseBuilder = new ApplyActionsCaseBuilder(); + ApplyActionsBuilder actionsBuilder = new ApplyActionsBuilder(); + actionsBuilder.setAction(deserializeActions(input, instructionLength)); + caseBuilder.setApplyActions(actionsBuilder.build()); + builder.setInstructionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new ApplyActionsCaseBuilder().build()); + return builder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ClearActionsInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ClearActionsInstructionDeserializer.java new file mode 100644 index 0000000000..24fe5cfba7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/ClearActionsInstructionDeserializer.java @@ -0,0 +1,44 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder; + +/** + * @author michal.polkorab + * + */ +public class ClearActionsInstructionDeserializer implements OFDeserializer, + HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + input.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + builder.setInstructionChoice(new ClearActionsCaseBuilder().build()); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new ClearActionsCaseBuilder().build()); + return builder.build(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/GoToTableInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/GoToTableInstructionDeserializer.java new file mode 100644 index 0000000000..31191b1d70 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/GoToTableInstructionDeserializer.java @@ -0,0 +1,49 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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._goto.table._case.GotoTableBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class GoToTableInstructionDeserializer implements OFDeserializer, + HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + GotoTableCaseBuilder caseBuilder = new GotoTableCaseBuilder(); + GotoTableBuilder instructionBuilder = new GotoTableBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + instructionBuilder.setTableId(input.readUnsignedByte()); + caseBuilder.setGotoTable(instructionBuilder.build()); + builder.setInstructionChoice(caseBuilder.build()); + input.skipBytes(InstructionConstants.PADDING_IN_GOTO_TABLE); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new GotoTableCaseBuilder().build()); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/MeterInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/MeterInstructionDeserializer.java new file mode 100644 index 0000000000..4667a4d8fa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/MeterInstructionDeserializer.java @@ -0,0 +1,48 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +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.instruction.rev130731.instruction.grouping.instruction.choice.MeterCaseBuilder; +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.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.InstructionBuilder; + +/** + * @author michal.polkorab + * + */ +public class MeterInstructionDeserializer implements OFDeserializer, + HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + MeterCaseBuilder caseBuilder = new MeterCaseBuilder(); + MeterBuilder instructionBuilder = new MeterBuilder(); + instructionBuilder.setMeterId(input.readUnsignedInt()); + caseBuilder.setMeter(instructionBuilder.build()); + builder.setInstructionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new MeterCaseBuilder().build()); + return builder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteActionsInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteActionsInstructionDeserializer.java new file mode 100644 index 0000000000..4699ef6994 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteActionsInstructionDeserializer.java @@ -0,0 +1,50 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.write.actions._case.WriteActionsBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class WriteActionsInstructionDeserializer extends AbstractActionInstructionDeserializer + implements HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + int instructionLength = input.readUnsignedShort(); + input.skipBytes(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + WriteActionsCaseBuilder caseBuilder = new WriteActionsCaseBuilder(); + WriteActionsBuilder actionsBuilder = new WriteActionsBuilder(); + actionsBuilder.setAction(deserializeActions(input, instructionLength)); + caseBuilder.setWriteActions(actionsBuilder.build()); + builder.setInstructionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new WriteActionsCaseBuilder().build()); + return builder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteMetadataInstructionDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteMetadataInstructionDeserializer.java new file mode 100644 index 0000000000..919fc50d2a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/WriteMetadataInstructionDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.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; + +/** + * @author michal.polkorab + * + */ +public class WriteMetadataInstructionDeserializer implements OFDeserializer, + HeaderDeserializer { + + @Override + public Instruction deserialize(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + input.skipBytes(InstructionConstants.PADDING_IN_WRITE_METADATA); + WriteMetadataCaseBuilder caseBuilder = new WriteMetadataCaseBuilder(); + WriteMetadataBuilder metadataBuilder = new WriteMetadataBuilder(); + byte[] metadata = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadata); + metadataBuilder.setMetadata(metadata); + byte[] metadataMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataMask); + metadataBuilder.setMetadataMask(metadataMask); + caseBuilder.setWriteMetadata(metadataBuilder.build()); + builder.setInstructionChoice(caseBuilder.build()); + return builder.build(); + } + + @Override + public Instruction deserializeHeader(ByteBuf input) { + InstructionBuilder builder = new InstructionBuilder(); + input.skipBytes(2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setInstructionChoice(new WriteMetadataCaseBuilder().build()); + return builder.build(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/AbstractOxmMatchEntryDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/AbstractOxmMatchEntryDeserializer.java new file mode 100644 index 0000000000..7eb478086b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/AbstractOxmMatchEntryDeserializer.java @@ -0,0 +1,64 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractOxmMatchEntryDeserializer implements HeaderDeserializer { + + @Override + public MatchEntry deserializeHeader(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + return builder.build(); + } + + /** + * @return oxm_field class + */ + protected abstract Class getOxmField(); + + /** + * @return oxm_class class + */ + protected abstract Class getOxmClass(); + + /** + * Prepares match entry header - sets oxm_class, oxm_field, hasMask + * + sets the buffer.readerIndex() to the end of match entry + * - where augmentation starts + * @param oxmClass oxm class type + * @param oxmField oxm field type + * @param input input bytebuf + * @return MatchEntriesBuilder which can be filled with MatchEntry augmentation + */ + protected MatchEntryBuilder processHeader(Class oxmClass, + Class oxmField, ByteBuf input) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(oxmClass); + // skip oxm_class (provided) + input.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + builder.setOxmMatchField(oxmField); + boolean hasMask = (input.readUnsignedByte() & 1) != 0; + builder.setHasMask(hasMask); + // skip match entry length - not needed + input.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + return builder; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpOpDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpOpDeserializer.java new file mode 100644 index 0000000000..ebfa516061 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpOpDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpOp; +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; +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.ArpOpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.op._case.ArpOpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpOpDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addArpOpValue(input, builder); + return builder.build(); + } + + private static void addArpOpValue(ByteBuf input, MatchEntryBuilder builder) { + ArpOpCaseBuilder caseBuilder = new ArpOpCaseBuilder(); + ArpOpBuilder opBuilder = new ArpOpBuilder(); + opBuilder.setOpCode(input.readUnsignedShort()); + caseBuilder.setArpOp(opBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return ArpOp.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpShaDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpShaDeserializer.java new file mode 100644 index 0000000000..91b4514e6a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpShaDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSha; +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; +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.ArpShaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.sha._case.ArpShaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpShaDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addArpShaValue(input, builder); + return builder.build(); + } + + private static void addArpShaValue(ByteBuf input, MatchEntryBuilder builder) { + ArpShaCaseBuilder caseBuilder = new ArpShaCaseBuilder(); + ArpShaBuilder shaBuilder = new ArpShaBuilder(); + shaBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + if (builder.isHasMask()) { + shaBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.MAC_ADDRESS_LENGTH)); + } + caseBuilder.setArpSha(shaBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return ArpSha.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java new file mode 100644 index 0000000000..ea24709810 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpSpaDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpSpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.spa._case.ArpSpaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpSpaDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addArpSpaValue(input, builder); + return builder.build(); + } + + private static void addArpSpaValue(final ByteBuf input, final MatchEntryBuilder builder) { + ArpSpaCaseBuilder caseBuilder = new ArpSpaCaseBuilder(); + ArpSpaBuilder arpBuilder = new ArpSpaBuilder(); + arpBuilder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); + if (builder.isHasMask()) { + arpBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); + } + caseBuilder.setArpSpa(arpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return ArpSpa.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpThaDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpThaDeserializer.java new file mode 100644 index 0000000000..0e034c1f5f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpThaDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTha; +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; +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.ArpThaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tha._case.ArpThaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpThaDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addArpThaValue(input, builder); + return builder.build(); + } + + private static void addArpThaValue(ByteBuf input, MatchEntryBuilder builder) { + ArpThaCaseBuilder caseBuilder = new ArpThaCaseBuilder(); + ArpThaBuilder thaBuilder = new ArpThaBuilder(); + thaBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + if (builder.isHasMask()) { + thaBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.MAC_ADDRESS_LENGTH)); + } + caseBuilder.setArpTha(thaBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return ArpTha.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java new file mode 100644 index 0000000000..da5dfee6eb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmArpTpaDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpTpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tpa._case.ArpTpaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpTpaDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addArpTpaValue(input, builder); + return builder.build(); + } + + private static void addArpTpaValue(final ByteBuf input, final MatchEntryBuilder builder) { + ArpTpaCaseBuilder caseBuilder = new ArpTpaCaseBuilder(); + ArpTpaBuilder arpBuilder = new ArpTpaBuilder(); + arpBuilder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); + if (builder.isHasMask()) { + arpBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); + } + caseBuilder.setArpTpa(arpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return ArpTpa.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java new file mode 100644 index 0000000000..c28ba5c26d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmDeserializerHelper.java @@ -0,0 +1,47 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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 + * + */ +public final class OxmDeserializerHelper { + + private OxmDeserializerHelper() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Converts binary data into binary mask (for match entries) + * @param input input ByteBuf + * @param matchEntryLength mask length + * @return binary mask + */ + public static byte[] convertMask(final ByteBuf input, final int matchEntryLength) { + byte[] mask = new byte[matchEntryLength]; + input.readBytes(mask); + return mask; + } + + /** + * Converts binary data into mac address + * @param input input ByteBuf + * @return mac address + */ + public static MacAddress convertMacAddress(final ByteBuf input) { + byte[] address = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + input.readBytes(address); + return IetfYangUtil.INSTANCE.macAddressFor(address); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthDstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthDstDeserializer.java new file mode 100644 index 0000000000..1229ff137c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthDstDeserializer.java @@ -0,0 +1,58 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst; +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; +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.EthDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthDstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addEthDstValue(input, builder); + return builder.build(); + } + + private static void addEthDstValue(ByteBuf input, MatchEntryBuilder builder) { + EthDstCaseBuilder caseBuilder = new EthDstCaseBuilder(); + EthDstBuilder ethBuilder = new EthDstBuilder(); + ethBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + if (builder.isHasMask()) { + ethBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.MAC_ADDRESS_LENGTH)); + } + caseBuilder.setEthDst(ethBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return EthDst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthSrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthSrcDeserializer.java new file mode 100644 index 0000000000..dc7bb80383 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthSrcDeserializer.java @@ -0,0 +1,58 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc; +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; +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.EthSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthSrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addEthSrcValue(input, builder); + return builder.build(); + } + + private static void addEthSrcValue(ByteBuf input, MatchEntryBuilder builder) { + EthSrcCaseBuilder caseBuilder = new EthSrcCaseBuilder(); + EthSrcBuilder ethBuilder = new EthSrcBuilder(); + ethBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + if (builder.isHasMask()) { + ethBuilder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.MAC_ADDRESS_LENGTH)); + } + caseBuilder.setEthSrc(ethBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return EthSrc.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthTypeDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthTypeDeserializer.java new file mode 100644 index 0000000000..5da869e0b4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmEthTypeDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType; +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; +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.EthTypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthTypeDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addEthTypeValue(input, builder); + return builder.build(); + } + + private static void addEthTypeValue(ByteBuf input, MatchEntryBuilder builder) { + EthTypeCaseBuilder caseBuilder = new EthTypeCaseBuilder(); + EthTypeBuilder ethBuilder = new EthTypeBuilder(); + ethBuilder.setEthType(new EtherType(input.readUnsignedShort())); + caseBuilder.setEthType(ethBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return EthType.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4CodeDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4CodeDeserializer.java new file mode 100644 index 0000000000..87a35d4e6c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4CodeDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Code; +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; +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.Icmpv4CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.code._case.Icmpv4CodeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4CodeDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIcmpv4CodeValue(input, builder); + return builder.build(); + } + + private static void addIcmpv4CodeValue(ByteBuf input, MatchEntryBuilder builder) { + Icmpv4CodeCaseBuilder caseBuilder = new Icmpv4CodeCaseBuilder(); + Icmpv4CodeBuilder icmpBuilder = new Icmpv4CodeBuilder(); + icmpBuilder.setIcmpv4Code(input.readUnsignedByte()); + caseBuilder.setIcmpv4Code(icmpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Icmpv4Code.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4TypeDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4TypeDeserializer.java new file mode 100644 index 0000000000..60aedde2cf --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv4TypeDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Type; +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; +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.Icmpv4TypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.type._case.Icmpv4TypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4TypeDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIcmpv4TypeValue(input, builder); + return builder.build(); + } + + private static void addIcmpv4TypeValue(ByteBuf input, MatchEntryBuilder builder) { + Icmpv4TypeCaseBuilder caseBuilder = new Icmpv4TypeCaseBuilder(); + Icmpv4TypeBuilder icmpBuilder = new Icmpv4TypeBuilder(); + icmpBuilder.setIcmpv4Type(input.readUnsignedByte()); + caseBuilder.setIcmpv4Type(icmpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Icmpv4Type.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6CodeDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6CodeDeserializer.java new file mode 100644 index 0000000000..52221c7843 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6CodeDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Code; +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; +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.Icmpv6CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.code._case.Icmpv6CodeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6CodeDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIcmpv6CodeValue(input, builder); + return builder.build(); + } + + private static void addIcmpv6CodeValue(ByteBuf input, MatchEntryBuilder builder) { + Icmpv6CodeCaseBuilder caseBuilder = new Icmpv6CodeCaseBuilder(); + Icmpv6CodeBuilder icmpBuilder = new Icmpv6CodeBuilder(); + icmpBuilder.setIcmpv6Code(input.readUnsignedByte()); + caseBuilder.setIcmpv6Code(icmpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Icmpv6Code.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6TypeDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6TypeDeserializer.java new file mode 100644 index 0000000000..5d112185d4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIcmpv6TypeDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Type; +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; +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.Icmpv6TypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.type._case.Icmpv6TypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6TypeDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIcmpv6TypeValue(input, builder); + return builder.build(); + } + + private static void addIcmpv6TypeValue(ByteBuf input, MatchEntryBuilder builder) { + Icmpv6TypeCaseBuilder caseBuilder = new Icmpv6TypeCaseBuilder(); + Icmpv6TypeBuilder icmpBuilder = new Icmpv6TypeBuilder(); + icmpBuilder.setIcmpv6Type(input.readUnsignedByte()); + caseBuilder.setIcmpv6Type(icmpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Icmpv6Type.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPhyPortDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPhyPortDeserializer.java new file mode 100644 index 0000000000..8f44c8f00d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPhyPortDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPhyPort; +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; +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.in.phy.port._case.InPhyPortBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmInPhyPortDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addInPhyPortValue(input, builder); + return builder.build(); + } + + private static void addInPhyPortValue(ByteBuf input, MatchEntryBuilder builder) { + InPhyPortCaseBuilder caseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(input.readUnsignedInt())); + caseBuilder.setInPhyPort(inPhyPortBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return InPhyPort.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPortDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPortDeserializer.java new file mode 100644 index 0000000000..3f08f5e934 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmInPortDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort; +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; +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.InPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.port._case.InPortBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmInPortDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addInPortValue(input, builder); + return builder.build(); + } + + private static void addInPortValue(ByteBuf input, MatchEntryBuilder builder) { + InPortCaseBuilder caseBuilder = new InPortCaseBuilder(); + InPortBuilder inPortBuilder = new InPortBuilder(); + inPortBuilder.setPortNumber(new PortNumber(input.readUnsignedInt())); + caseBuilder.setInPort(inPortBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return InPort.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java new file mode 100644 index 0000000000..98c49af8ae --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpDscpDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpDscpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.dscp._case.IpDscpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpDscpDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpDscpValue(input, builder); + return builder.build(); + } + + private static void addIpDscpValue(ByteBuf input, MatchEntryBuilder builder) { + IpDscpCaseBuilder caseBuilder = new IpDscpCaseBuilder(); + IpDscpBuilder dscpBuilder = new IpDscpBuilder(); + dscpBuilder.setDscp(new Dscp(input.readUnsignedByte())); + caseBuilder.setIpDscp(dscpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return IpDscp.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpEcnDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpEcnDeserializer.java new file mode 100644 index 0000000000..9dd928d84f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpEcnDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpEcn; +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; +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.IpEcnCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.ecn._case.IpEcnBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpEcnDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpEcnValue(input, builder); + return builder.build(); + } + + private static void addIpEcnValue(ByteBuf input, MatchEntryBuilder builder) { + IpEcnCaseBuilder caseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ecnBuilder = new IpEcnBuilder(); + ecnBuilder.setEcn(input.readUnsignedByte()); + caseBuilder.setIpEcn(ecnBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return IpEcn.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpProtoDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpProtoDeserializer.java new file mode 100644 index 0000000000..4861841de2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpProtoDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.IpProto; +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; +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.IpProtoCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.proto._case.IpProtoBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpProtoDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpProtoValue(input, builder); + return builder.build(); + } + + private static void addIpProtoValue(ByteBuf input, MatchEntryBuilder builder) { + IpProtoCaseBuilder caseBuilder = new IpProtoCaseBuilder(); + IpProtoBuilder protoBuilder = new IpProtoBuilder(); + protoBuilder.setProtocolNumber(input.readUnsignedByte()); + caseBuilder.setIpProto(protoBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return IpProto.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java new file mode 100644 index 0000000000..6664538de8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4DstDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4DstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4DstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv4DstValue(input, builder); + return builder.build(); + } + + private static void addIpv4DstValue(final ByteBuf input, final MatchEntryBuilder builder) { + Ipv4DstCaseBuilder caseBuilder = new Ipv4DstCaseBuilder(); + Ipv4DstBuilder ipv4Builder = new Ipv4DstBuilder(); + ipv4Builder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); + if (builder.isHasMask()) { + ipv4Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); + } + caseBuilder.setIpv4Dst(ipv4Builder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv4Dst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java new file mode 100644 index 0000000000..5b0cc22d15 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv4SrcDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4SrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4SrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv4SrcValue(input, builder); + return builder.build(); + } + + private static void addIpv4SrcValue(final ByteBuf input, final MatchEntryBuilder builder) { + Ipv4SrcCaseBuilder caseBuilder = new Ipv4SrcCaseBuilder(); + Ipv4SrcBuilder ipv4Builder = new Ipv4SrcBuilder(); + ipv4Builder.setIpv4Address(ByteBufUtils.readIetfIpv4Address(input)); + if (builder.isHasMask()) { + ipv4Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.GROUPS_IN_IPV4_ADDRESS)); + } + caseBuilder.setIpv4Src(ipv4Builder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv4Src.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java new file mode 100644 index 0000000000..4d88c269ff --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6DstDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.dst._case.Ipv6DstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6DstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6DstValue(input, builder); + return builder.build(); + } + + private static void addIpv6DstValue(final ByteBuf input, final MatchEntryBuilder builder) { + Ipv6DstCaseBuilder caseBuilder = new Ipv6DstCaseBuilder(); + Ipv6DstBuilder ipv6Builder = new Ipv6DstBuilder(); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); + if (builder.isHasMask()) { + ipv6Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES)); + } + caseBuilder.setIpv6Dst(ipv6Builder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6Dst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializer.java new file mode 100644 index 0000000000..9b17035bd8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializer.java @@ -0,0 +1,73 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +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; +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.Ipv6ExthdrCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.exthdr._case.Ipv6ExthdrBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6ExtHdrDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6ExtHdrValue(input, builder); + return builder.build(); + } + + private static void addIpv6ExtHdrValue(ByteBuf input, MatchEntryBuilder builder) { + Ipv6ExthdrCaseBuilder caseBuilder = new Ipv6ExthdrCaseBuilder(); + Ipv6ExthdrBuilder extHdrBuilder = new Ipv6ExthdrBuilder(); + extHdrBuilder.setPseudoField(convertPseudofields(input)); + if (builder.isHasMask()) { + extHdrBuilder.setMask(OxmDeserializerHelper + .convertMask(input, EncodeConstants.SIZE_OF_SHORT_IN_BYTES)); + } + caseBuilder.setIpv6Exthdr(extHdrBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + private static Ipv6ExthdrFlags convertPseudofields(ByteBuf input) { + int bitmap = input.readUnsignedShort(); + final Boolean nonext = ((bitmap) & (1<<0)) != 0; + final Boolean esp = ((bitmap) & (1<<1)) != 0; + final Boolean auth = ((bitmap) & (1<<2)) != 0; + final Boolean dest = ((bitmap) & (1<<3)) != 0; + final Boolean frag = ((bitmap) & (1<<4)) != 0; + final Boolean router = ((bitmap) & (1<<5)) != 0; + final Boolean hop = ((bitmap) & (1<<6)) != 0; + final Boolean unrep = ((bitmap) & (1<<7)) != 0; + final Boolean unseq = ((bitmap) & (1<<8)) != 0; + return new Ipv6ExthdrFlags(auth, dest, esp, frag, hop, nonext, router, unrep, unseq); + } + + @Override + protected Class getOxmField() { + return Ipv6Exthdr.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java new file mode 100644 index 0000000000..4ef1944aaa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializer.java @@ -0,0 +1,60 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6FlabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.flabel._case.Ipv6FlabelBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6FlabelDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6FlabelValue(input, builder); + return builder.build(); + } + + private static void addIpv6FlabelValue(ByteBuf input, MatchEntryBuilder builder) { + Ipv6FlabelCaseBuilder caseBuilder = new Ipv6FlabelCaseBuilder(); + Ipv6FlabelBuilder labelBuilder = new Ipv6FlabelBuilder(); + labelBuilder.setIpv6Flabel(new Ipv6FlowLabel(input.readUnsignedInt())); + if (builder.isHasMask()) { + labelBuilder.setMask(OxmDeserializerHelper.convertMask(input, + EncodeConstants.SIZE_OF_INT_IN_BYTES)); + } + caseBuilder.setIpv6Flabel(labelBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6Flabel.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdSllDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdSllDeserializer.java new file mode 100644 index 0000000000..ad37cd0ea4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdSllDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdSll; +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; +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.Ipv6NdSllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.sll._case.Ipv6NdSllBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdSllDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6NdSllValue(input, builder); + return builder.build(); + } + + private static void addIpv6NdSllValue(ByteBuf input, MatchEntryBuilder builder) { + Ipv6NdSllCaseBuilder caseBuilder = new Ipv6NdSllCaseBuilder(); + Ipv6NdSllBuilder ndBuilder = new Ipv6NdSllBuilder(); + ndBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + caseBuilder.setIpv6NdSll(ndBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6NdSll.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java new file mode 100644 index 0000000000..99c52c95a5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTargetDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTargetCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.target._case.Ipv6NdTargetBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdTargetDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6NdTargetValue(input, builder); + return builder.build(); + } + + private static void addIpv6NdTargetValue(final ByteBuf input, final MatchEntryBuilder builder) { + Ipv6NdTargetCaseBuilder caseBuilder = new Ipv6NdTargetCaseBuilder(); + Ipv6NdTargetBuilder ipv6Builder = new Ipv6NdTargetBuilder(); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); + caseBuilder.setIpv6NdTarget(ipv6Builder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6NdTarget.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTllDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTllDeserializer.java new file mode 100644 index 0000000000..449c01ca84 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6NdTllDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTll; +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; +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.Ipv6NdTllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.tll._case.Ipv6NdTllBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdTllDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6NdTllValue(input, builder); + return builder.build(); + } + + private static void addIpv6NdTllValue(ByteBuf input, MatchEntryBuilder builder) { + Ipv6NdTllCaseBuilder caseBuilder = new Ipv6NdTllCaseBuilder(); + Ipv6NdTllBuilder ndBuilder = new Ipv6NdTllBuilder(); + ndBuilder.setMacAddress(OxmDeserializerHelper.convertMacAddress(input)); + caseBuilder.setIpv6NdTll(ndBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6NdTll.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java new file mode 100644 index 0000000000..22b9ccef87 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6SrcDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6SrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6SrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(final ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addIpv6SrcValue(input, builder); + return builder.build(); + } + + private static void addIpv6SrcValue(final ByteBuf input, final MatchEntryBuilder builder) { + Ipv6SrcCaseBuilder caseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder ipv6Builder = new Ipv6SrcBuilder(); + ipv6Builder.setIpv6Address(ByteBufUtils.readIetfIpv6Address(input)); + if (builder.isHasMask()) { + ipv6Builder.setMask(OxmDeserializerHelper.convertMask(input, EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES)); + } + caseBuilder.setIpv6Src(ipv6Builder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Ipv6Src.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializer.java new file mode 100644 index 0000000000..0f16de8a1d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializer.java @@ -0,0 +1,60 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.metadata._case.MetadataBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMetadataDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addMetadataValue(input, builder); + return builder.build(); + } + + private static void addMetadataValue(ByteBuf input, MatchEntryBuilder builder) { + MetadataCaseBuilder caseBuilder = new MetadataCaseBuilder(); + MetadataBuilder metadataBuilder = new MetadataBuilder(); + byte[] metadataBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataBytes); + metadataBuilder.setMetadata(metadataBytes); + if (builder.isHasMask()) { + metadataBuilder.setMask(OxmDeserializerHelper + .convertMask(input, EncodeConstants.SIZE_OF_LONG_IN_BYTES)); + } + caseBuilder.setMetadata(metadataBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return Metadata.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializer.java new file mode 100644 index 0000000000..ec68bef8fd --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializer.java @@ -0,0 +1,57 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsBos; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsBosCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.bos._case.MplsBosBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsBosDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addMplsBosValue(input, builder); + return builder.build(); + } + + private static void addMplsBosValue(ByteBuf input, MatchEntryBuilder builder) { + MplsBosCaseBuilder caseBuilder = new MplsBosCaseBuilder(); + MplsBosBuilder bosBuilder = new MplsBosBuilder(); + if (input.readUnsignedByte() != 0) { + bosBuilder.setBos(true); + } else { + bosBuilder.setBos(false); + } + caseBuilder.setMplsBos(bosBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return MplsBos.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsLabelDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsLabelDeserializer.java new file mode 100644 index 0000000000..afc41d2704 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsLabelDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsLabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsLabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.label._case.MplsLabelBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsLabelDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addMplsLabelValue(input, builder); + return builder.build(); + } + + private static void addMplsLabelValue(ByteBuf input, MatchEntryBuilder builder) { + MplsLabelCaseBuilder caseBuilder = new MplsLabelCaseBuilder(); + MplsLabelBuilder labelBuilder = new MplsLabelBuilder(); + labelBuilder.setMplsLabel(input.readUnsignedInt()); + caseBuilder.setMplsLabel(labelBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return MplsLabel.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsTcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsTcDeserializer.java new file mode 100644 index 0000000000..ed77c9025f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsTcDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsTc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsTcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.tc._case.MplsTcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsTcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addMplsTcValue(input, builder); + return builder.build(); + } + + private static void addMplsTcValue(ByteBuf input, MatchEntryBuilder builder) { + MplsTcCaseBuilder caseBuilder = new MplsTcCaseBuilder(); + MplsTcBuilder tcBuilder = new MplsTcBuilder(); + tcBuilder.setTc(input.readUnsignedByte()); + caseBuilder.setMplsTc(tcBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return MplsTc.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializer.java new file mode 100644 index 0000000000..5c5b159237 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializer.java @@ -0,0 +1,59 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.PbbIsid; +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.PbbIsidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.pbb.isid._case.PbbIsidBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmPbbIsidDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addPbbIsidValue(input, builder); + return builder.build(); + } + + private static void addPbbIsidValue(ByteBuf input, MatchEntryBuilder builder) { + PbbIsidCaseBuilder caseBuilder = new PbbIsidCaseBuilder(); + PbbIsidBuilder isidBuilder = new PbbIsidBuilder(); + Integer isid = input.readUnsignedMedium(); + isidBuilder.setIsid(isid.longValue()); + if (builder.isHasMask()) { + isidBuilder.setMask(OxmDeserializerHelper + .convertMask(input, EncodeConstants.SIZE_OF_3_BYTES)); + } + caseBuilder.setPbbIsid(isidBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return PbbIsid.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java new file mode 100644 index 0000000000..cac4f80696 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpDstDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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.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.SctpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.dst._case.SctpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpDstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addSctpDstValue(input, builder); + return builder.build(); + } + + private static void addSctpDstValue(ByteBuf input, MatchEntryBuilder builder) { + SctpDstCaseBuilder caseBuilder = new SctpDstCaseBuilder(); + SctpDstBuilder sctpBuilder = new SctpDstBuilder(); + sctpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setSctpDst(sctpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return SctpDst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java new file mode 100644 index 0000000000..8dc17a59a3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmSctpSrcDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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.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.SctpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.src._case.SctpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpSrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addSctpSrcValue(input, builder); + return builder.build(); + } + + private static void addSctpSrcValue(ByteBuf input, MatchEntryBuilder builder) { + SctpSrcCaseBuilder caseBuilder = new SctpSrcCaseBuilder(); + SctpSrcBuilder sctpBuilder = new SctpSrcBuilder(); + sctpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setSctpSrc(sctpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return SctpSrc.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java new file mode 100644 index 0000000000..7b3869b7a2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpDstDeserializer.java @@ -0,0 +1,55 @@ +/* + * 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.match; + +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.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; +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.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.TcpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.dst._case.TcpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpDstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addTcpDstValue(input, builder); + return builder.build(); + } + + private static void addTcpDstValue(ByteBuf input, MatchEntryBuilder builder) { + TcpDstCaseBuilder caseBuilder = new TcpDstCaseBuilder(); + TcpDstBuilder tcpBuilder = new TcpDstBuilder(); + tcpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setTcpDst(tcpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return TcpDst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java new file mode 100644 index 0000000000..5e8a759675 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTcpSrcDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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.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.TcpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.src._case.TcpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpSrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addTcpSrcValue(input, builder); + return builder.build(); + } + + private static void addTcpSrcValue(ByteBuf input, MatchEntryBuilder builder) { + TcpSrcCaseBuilder caseBuilder = new TcpSrcCaseBuilder(); + TcpSrcBuilder tcpBuilder = new TcpSrcBuilder(); + tcpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setTcpSrc(tcpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return TcpSrc.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTunnelIdDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTunnelIdDeserializer.java new file mode 100644 index 0000000000..86e1865b93 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmTunnelIdDeserializer.java @@ -0,0 +1,60 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TunnelId; +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.TunnelIdCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tunnel.id._case.TunnelIdBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTunnelIdDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addTunnelIdValue(input, builder); + return builder.build(); + } + + private static void addTunnelIdValue(ByteBuf input, MatchEntryBuilder builder) { + TunnelIdCaseBuilder caseBuilder = new TunnelIdCaseBuilder(); + TunnelIdBuilder tunnelIdBuilder = new TunnelIdBuilder(); + byte[] metadataBytes = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + input.readBytes(metadataBytes); + tunnelIdBuilder.setTunnelId(metadataBytes); + if (builder.isHasMask()) { + tunnelIdBuilder.setMask(OxmDeserializerHelper + .convertMask(input, EncodeConstants.SIZE_OF_LONG_IN_BYTES)); + } + caseBuilder.setTunnelId(tunnelIdBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return TunnelId.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java new file mode 100644 index 0000000000..9a97842201 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpDstDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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.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.UdpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.dst._case.UdpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpDstDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addUdpDstValue(input, builder); + return builder.build(); + } + + private static void addUdpDstValue(ByteBuf input, MatchEntryBuilder builder) { + UdpDstCaseBuilder caseBuilder = new UdpDstCaseBuilder(); + UdpDstBuilder udpBuilder = new UdpDstBuilder(); + udpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setUdpDst(udpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return UdpDst.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java new file mode 100644 index 0000000000..501e70c38b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmUdpSrcDeserializer.java @@ -0,0 +1,54 @@ +/* + * 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.match; + +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.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; +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.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.UdpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.src._case.UdpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpSrcDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addUdpSrcValue(input, builder); + return builder.build(); + } + + private static void addUdpSrcValue(ByteBuf input, MatchEntryBuilder builder) { + UdpSrcCaseBuilder caseBuilder = new UdpSrcCaseBuilder(); + UdpSrcBuilder udpBuilder = new UdpSrcBuilder(); + udpBuilder.setPort(new PortNumber(input.readUnsignedShort())); + caseBuilder.setUdpSrc(udpBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return UdpSrc.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanPcpDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanPcpDeserializer.java new file mode 100644 index 0000000000..28c60783ff --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanPcpDeserializer.java @@ -0,0 +1,53 @@ +/* + * 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.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanPcp; +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.VlanPcpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.pcp._case.VlanPcpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanPcpDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addVlanPcpValue(input, builder); + return builder.build(); + } + + private static void addVlanPcpValue(ByteBuf input, MatchEntryBuilder builder) { + VlanPcpCaseBuilder caseBuilder = new VlanPcpCaseBuilder(); + VlanPcpBuilder vlanBuilder = new VlanPcpBuilder(); + vlanBuilder.setVlanPcp(input.readUnsignedByte()); + caseBuilder.setVlanPcp(vlanBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return VlanPcp.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializer.java new file mode 100644 index 0000000000..7292e61f61 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializer.java @@ -0,0 +1,60 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; +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.VlanVidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanVidDeserializer extends AbstractOxmMatchEntryDeserializer + implements OFDeserializer { + + @Override + public MatchEntry deserialize(ByteBuf input) { + MatchEntryBuilder builder = processHeader(getOxmClass(), getOxmField(), input); + addVlanVidValue(input, builder); + return builder.build(); + } + + private static void addVlanVidValue(ByteBuf input, MatchEntryBuilder builder) { + VlanVidCaseBuilder caseBuilder = new VlanVidCaseBuilder(); + VlanVidBuilder vlanBuilder = new VlanVidBuilder(); + int vidEntryValue = input.readUnsignedShort(); + vlanBuilder.setCfiBit((vidEntryValue & (1 << 12)) != 0); // cfi is 13-th bit + vlanBuilder.setVlanVid(vidEntryValue & ((1 << 12) - 1)); // value without 13-th bit + if (builder.isHasMask()) { + vlanBuilder.setMask(OxmDeserializerHelper + .convertMask(input, EncodeConstants.SIZE_OF_SHORT_IN_BYTES)); + } + caseBuilder.setVlanVid(vlanBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + } + + @Override + protected Class getOxmField() { + return VlanVid.class; + } + + @Override + protected Class getOxmClass() { + return OpenflowBasicClass.class; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/AbstractOxmExperimenterMatchEntryDeserializer.java new file mode 100644 index 0000000000..e9535d8e4a --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/ext/OnfOxmTcpFlagsDeserializer.java new file mode 100644 index 0000000000..e03ed77aa3 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/ActionsInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/ActionsInitializer.java new file mode 100644 index 0000000000..91de3e43f7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/ActionsInitializer.java @@ -0,0 +1,120 @@ +/* + * 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.serialization; + +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10EnqueueActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10OutputActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetDlDstActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetDlSrcActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetNwDstActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetNwSrcActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetNwTosActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetTpDstActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetTpSrcActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetVlanPcpActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10SetVlanVidActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF10StripVlanActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13CopyTtlInActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13CopyTtlOutActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13DecMplsTtlActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13DecNwTtlActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13GroupActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13OutputActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PopMplsActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PopPbbActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PopVlanActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PushMplsActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PushPbbActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13PushVlanActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13SetFieldActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13SetMplsTtlActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13SetNwTtlActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.action.OF13SetQueueActionSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.ActionSerializerRegistryHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlOutCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecNwTtlCase; +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.GroupCase; +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.PopMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCase; +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.action.grouping.action.choice.SetDlSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetFieldCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetMplsTtlCase; +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.action.grouping.action.choice.SetNwSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTosCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanPcpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanVidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.StripVlanCase; +//import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev130731.Group; + +/** + * Initializes serializer registry with action serializers + * @author michal.polkorab + */ +public final class ActionsInitializer { + + private ActionsInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers action serializers into provided registry + * @param serializerRegistry registry to be initialized with action serializers + */ + public static void registerActionSerializers(SerializerRegistry serializerRegistry) { + // register OF v1.0 action serializers + ActionSerializerRegistryHelper helper = new ActionSerializerRegistryHelper( + EncodeConstants.OF10_VERSION_ID, serializerRegistry); + helper.registerSerializer(OutputActionCase.class, new OF10OutputActionSerializer()); + helper.registerSerializer(SetVlanVidCase.class, new OF10SetVlanVidActionSerializer()); + helper.registerSerializer(SetVlanPcpCase.class, new OF10SetVlanPcpActionSerializer()); + helper.registerSerializer(StripVlanCase.class, new OF10StripVlanActionSerializer()); + helper.registerSerializer(SetDlSrcCase.class, new OF10SetDlSrcActionSerializer()); + helper.registerSerializer(SetDlDstCase.class, new OF10SetDlDstActionSerializer()); + helper.registerSerializer(SetNwSrcCase.class, new OF10SetNwSrcActionSerializer()); + helper.registerSerializer(SetNwDstCase.class, new OF10SetNwDstActionSerializer()); + helper.registerSerializer(SetNwTosCase.class, new OF10SetNwTosActionSerializer()); + helper.registerSerializer(SetTpSrcCase.class, new OF10SetTpSrcActionSerializer()); + helper.registerSerializer(SetTpDstCase.class, new OF10SetTpDstActionSerializer()); + helper.registerSerializer(EnqueueCase.class, new OF10EnqueueActionSerializer()); + // register OF v1.0 action serializers + helper = new ActionSerializerRegistryHelper( + EncodeConstants.OF13_VERSION_ID, serializerRegistry); + helper.registerSerializer(OutputActionCase.class, new OF13OutputActionSerializer()); + helper.registerSerializer(CopyTtlOutCase.class, new OF13CopyTtlOutActionSerializer()); + helper.registerSerializer(CopyTtlInCase.class, new OF13CopyTtlInActionSerializer()); + helper.registerSerializer(SetMplsTtlCase.class, new OF13SetMplsTtlActionSerializer()); + helper.registerSerializer(DecMplsTtlCase.class, new OF13DecMplsTtlActionSerializer()); + helper.registerSerializer(PushVlanCase.class, new OF13PushVlanActionSerializer()); + helper.registerSerializer(PopVlanCase.class, new OF13PopVlanActionSerializer()); + helper.registerSerializer(PushMplsCase.class, new OF13PushMplsActionSerializer()); + helper.registerSerializer(PopMplsCase.class, new OF13PopMplsActionSerializer()); + helper.registerSerializer(SetQueueCase.class, new OF13SetQueueActionSerializer()); + helper.registerSerializer(GroupCase.class, new OF13GroupActionSerializer()); + helper.registerSerializer(SetNwTtlCase.class, new OF13SetNwTtlActionSerializer()); + helper.registerSerializer(DecNwTtlCase.class, new OF13DecNwTtlActionSerializer()); + helper.registerSerializer(SetFieldCase.class, new OF13SetFieldActionSerializer()); + helper.registerSerializer(PushPbbCase.class, new OF13PushPbbActionSerializer()); + helper.registerSerializer(PopPbbCase.class, new OF13PopPbbActionSerializer()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/AdditionalMessageFactoryInitializer.java new file mode 100644 index 0000000000..85bcbda686 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/InstructionsInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/InstructionsInitializer.java new file mode 100644 index 0000000000..3c9ff80be6 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/InstructionsInitializer.java @@ -0,0 +1,52 @@ +/* + * 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.serialization; + +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.ApplyActionsInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.ClearActionsInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.GoToTableInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.MeterInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.WriteActionsInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.instruction.WriteMetadataInstructionSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionSerializerRegistryHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCase; + +/** + * @author michal.polkorab + * + */ +public final class InstructionsInitializer { + + private InstructionsInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers instruction serializers into provided registry + * @param serializerRegistry registry to be initialized with instruction serializers + */ + public static void registerInstructionSerializers(SerializerRegistry serializerRegistry) { + // register OF v1.3 instruction serializers + InstructionSerializerRegistryHelper helper= new InstructionSerializerRegistryHelper( + EncodeConstants.OF13_VERSION_ID, serializerRegistry); + helper.registerSerializer(GotoTableCase.class, new GoToTableInstructionSerializer()); + helper.registerSerializer(WriteMetadataCase.class, new WriteMetadataInstructionSerializer()); + helper.registerSerializer(WriteActionsCase.class, new WriteActionsInstructionSerializer()); + helper.registerSerializer(ApplyActionsCase.class, new ApplyActionsInstructionSerializer()); + helper.registerSerializer(ClearActionsCase.class, new ClearActionsInstructionSerializer()); + helper.registerSerializer(MeterCase.class, new MeterInstructionSerializer()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java new file mode 100644 index 0000000000..a787978835 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MatchEntriesInitializer.java @@ -0,0 +1,162 @@ +/* + * 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.serialization; + +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmArpOpSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmArpShaSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmArpSpaSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmArpThaSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmArpTpaSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmEthDstSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmEthSrcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmEthTypeSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIcmpv4CodeSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIcmpv4TypeSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIcmpv6CodeSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIcmpv6TypeSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmInPhyPortSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmInPortSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpDscpSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpEcnSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpProtoSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv4DstSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv4SrcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6DstSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6ExtHdrSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6FlabelSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6NdSllSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6NdTargetSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6NdTllSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmIpv6SrcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmMetadataSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmMplsBosSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmMplsLabelSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmMplsTcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmPbbIsidSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmSctpDstSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmSctpSrcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmTcpDstSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmTcpSrcSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmTunnelIdSerializer; +import org.opendaylight.openflowjava.protocol.impl.serialization.match.OxmUdpDstSerializer; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTha; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTpa; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Type; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Type; +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.IpDscp; +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.Ipv4Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdSll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTarget; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsBos; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsLabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsTc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.PbbIsid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TunnelId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanPcp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; + +/** + * Initializes serializer registry with match entry serializers. + * @author michal.polkorab + */ +public final class MatchEntriesInitializer { + + private MatchEntriesInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Registers match entry serializers into provided registry. + * @param serializerRegistry registry to be initialized with match entry serializers + */ + public static void registerMatchEntrySerializers(SerializerRegistry serializerRegistry) { + // register OF v1.3 OpenflowBasicClass match entry serializers + Class oxmClass = OpenflowBasicClass.class; + MatchEntrySerializerRegistryHelper helper = + new MatchEntrySerializerRegistryHelper<>(EncodeConstants.OF13_VERSION_ID, + oxmClass, serializerRegistry); + helper.registerSerializer(InPort.class, new OxmInPortSerializer()); + helper.registerSerializer(InPhyPort.class, new OxmInPhyPortSerializer()); + helper.registerSerializer(Metadata.class, new OxmMetadataSerializer()); + helper.registerSerializer(EthDst.class, new OxmEthDstSerializer()); + helper.registerSerializer(EthSrc.class, new OxmEthSrcSerializer()); + helper.registerSerializer(EthType.class, new OxmEthTypeSerializer()); + helper.registerSerializer(VlanVid.class, new OxmVlanVidSerializer()); + helper.registerSerializer(VlanPcp.class, new OxmVlanPcpSerializer()); + helper.registerSerializer(IpDscp.class, new OxmIpDscpSerializer()); + helper.registerSerializer(IpEcn.class, new OxmIpEcnSerializer()); + helper.registerSerializer(IpProto.class, new OxmIpProtoSerializer()); + helper.registerSerializer(Ipv4Src.class, new OxmIpv4SrcSerializer()); + helper.registerSerializer(Ipv4Dst.class, new OxmIpv4DstSerializer()); + helper.registerSerializer(TcpSrc.class, new OxmTcpSrcSerializer()); + helper.registerSerializer(TcpDst.class, new OxmTcpDstSerializer()); + helper.registerSerializer(UdpSrc.class, new OxmUdpSrcSerializer()); + helper.registerSerializer(UdpDst.class, new OxmUdpDstSerializer()); + helper.registerSerializer(SctpSrc.class, new OxmSctpSrcSerializer()); + helper.registerSerializer(SctpDst.class, new OxmSctpDstSerializer()); + helper.registerSerializer(Icmpv4Type.class, new OxmIcmpv4TypeSerializer()); + helper.registerSerializer(Icmpv4Code.class, new OxmIcmpv4CodeSerializer()); + helper.registerSerializer(ArpOp.class, new OxmArpOpSerializer()); + helper.registerSerializer(ArpSpa.class, new OxmArpSpaSerializer()); + helper.registerSerializer(ArpTpa.class, new OxmArpTpaSerializer()); + helper.registerSerializer(ArpSha.class, new OxmArpShaSerializer()); + helper.registerSerializer(ArpTha.class, new OxmArpThaSerializer()); + helper.registerSerializer(Ipv6Src.class, new OxmIpv6SrcSerializer()); + helper.registerSerializer(Ipv6Dst.class, new OxmIpv6DstSerializer()); + helper.registerSerializer(Ipv6Flabel.class, new OxmIpv6FlabelSerializer()); + helper.registerSerializer(Icmpv6Type.class, new OxmIcmpv6TypeSerializer()); + helper.registerSerializer(Icmpv6Code.class, new OxmIcmpv6CodeSerializer()); + helper.registerSerializer(Ipv6NdTarget.class, new OxmIpv6NdTargetSerializer()); + helper.registerSerializer(Ipv6NdSll.class, new OxmIpv6NdSllSerializer()); + helper.registerSerializer(Ipv6NdTll.class, new OxmIpv6NdTllSerializer()); + helper.registerSerializer(MplsLabel.class, new OxmMplsLabelSerializer()); + helper.registerSerializer(MplsTc.class, new OxmMplsTcSerializer()); + helper.registerSerializer(MplsBos.class, new OxmMplsBosSerializer()); + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java new file mode 100644 index 0000000000..23551bb753 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/MessageFactoryInitializer.java @@ -0,0 +1,115 @@ +/* + * 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.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.BarrierInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.EchoReplyInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.ExperimenterInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.FlowModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetAsyncRequestMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetFeaturesInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GetQueueConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.GroupModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.HelloInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MeterModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10BarrierInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10FlowModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10HelloInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10PacketOutInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10PortModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10QueueGetConfigInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.OF10StatsRequestInputFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.PacketOutInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.PortModInputMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.RoleRequestInputMessageFactory; +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; +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.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.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.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 serializers. + * @author michal.polkorab + */ +public final class MessageFactoryInitializer { + + private MessageFactoryInitializer() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * 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 + 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 VendorInputMessageFactory()); + registryHelper.registerSerializer(FlowModInput.class, new OF10FlowModInputMessageFactory()); + registryHelper.registerSerializer(GetConfigInput.class, new GetConfigInputMessageFactory()); + registryHelper.registerSerializer(GetFeaturesInput.class, new GetFeaturesInputMessageFactory()); + registryHelper.registerSerializer(GetQueueConfigInput.class, new OF10QueueGetConfigInputMessageFactory()); + registryHelper.registerSerializer(HelloInput.class, new OF10HelloInputMessageFactory()); + registryHelper.registerSerializer(MultipartRequestInput.class, new OF10StatsRequestInputFactory()); + registryHelper.registerSerializer(PacketOutInput.class, new OF10PacketOutInputMessageFactory()); + registryHelper.registerSerializer(PortModInput.class, new OF10PortModInputMessageFactory()); + registryHelper.registerSerializer(SetConfigInput.class, new SetConfigMessageFactory()); + + // register OF v1.3 message serializers + 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()); + registryHelper.registerSerializer(ExperimenterInput.class, new ExperimenterInputMessageFactory()); + registryHelper.registerSerializer(FlowModInput.class, new FlowModInputMessageFactory()); + registryHelper.registerSerializer(GetAsyncInput.class, new GetAsyncRequestMessageFactory()); + registryHelper.registerSerializer(GetConfigInput.class, new GetConfigInputMessageFactory()); + registryHelper.registerSerializer(GetFeaturesInput.class, new GetFeaturesInputMessageFactory()); + registryHelper.registerSerializer(GetQueueConfigInput.class, new GetQueueConfigInputMessageFactory()); + registryHelper.registerSerializer(GroupModInput.class, new GroupModInputMessageFactory()); + registryHelper.registerSerializer(HelloInput.class, new HelloInputMessageFactory()); + registryHelper.registerSerializer(MeterModInput.class, new MeterModInputMessageFactory()); + registryHelper.registerSerializer(MultipartRequestInput.class, new MultipartRequestInputFactory()); + registryHelper.registerSerializer(PacketOutInput.class, new PacketOutInputMessageFactory()); + 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(TableModInput.class, new TableModInputMessageFactory()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java new file mode 100644 index 0000000000..e7456afe91 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactory.java @@ -0,0 +1,45 @@ +/* + * 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.serialization; + +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.keys.MessageTypeKey; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author michal.polkorab + * @author timotej.kubas + */ +public class SerializationFactory { + + private SerializerRegistry registry; + + /** + * Transforms POJO message into ByteBuf + * @param version version used for encoding received message + * @param out ByteBuf for storing and sending transformed message + * @param message POJO message + */ + public void messageToBuffer(short version, ByteBuf out, DataObject message) { + OFSerializer serializer = registry.getSerializer( + new MessageTypeKey<>(version, message.getImplementedInterface())); + serializer.serialize(message, out); + } + + /** + * @param serializerRegistry registry with serializers + */ + public void setSerializerTable(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java new file mode 100644 index 0000000000..9383187866 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImpl.java @@ -0,0 +1,105 @@ +/* + * 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.serialization; + +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; +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.OF10MatchSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.OF13MatchSerializer; +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.v10.grouping.MatchV10; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 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 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()); + + // match entry serializers + MatchEntriesInitializer.registerMatchEntrySerializers(this); + // action serializers + ActionsInitializer.registerActionSerializers(this); + // instruction serializers + InstructionsInitializer.registerInstructionSerializers(this); + } + + /** + * @param msgTypeKey + * @return encoder for current type of message (msgTypeKey) + */ + @Override + @SuppressWarnings("unchecked") + public S getSerializer(MessageTypeKey msgTypeKey) { + OFGeneralSerializer serializer = registry.get(msgTypeKey); + if (serializer == null) { + throw new IllegalStateException("Serializer for key: " + msgTypeKey + + " was not found - please verify that you are using correct message" + + " combination (e.g. OF v1.0 message to OF v1.0 device)"); + } + return (S) serializer; + } + + @Override + 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) { + 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); + } + } + + @Override + public boolean unregisterSerializer(MessageTypeKey msgTypeKey) { + if (msgTypeKey == null) { + throw new IllegalArgumentException("MessageTypeKey is null"); + } + OFGeneralSerializer serializer = registry.remove(msgTypeKey); + if (serializer == null) { + return false; + } + return true; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/AbstractActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/AbstractActionSerializer.java new file mode 100644 index 0000000000..22c96c953c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/AbstractActionSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractActionSerializer implements OFSerializer, + HeaderSerializer{ + + @Override + public void serialize(Action input, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(getLength()); + } + + @Override + public void serializeHeader(Action input, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(ActionConstants.ACTION_IDS_LENGTH); + } + + /** + * @return numeric representation of action type + */ + protected abstract int getType(); + + /** + * @return action length + */ + protected abstract int getLength(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10EnqueueActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10EnqueueActionSerializer.java new file mode 100644 index 0000000000..282aca9161 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10EnqueueActionSerializer.java @@ -0,0 +1,43 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10EnqueueActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((EnqueueCase) action.getActionChoice()).getEnqueueAction() + .getPort().getValue().intValue()); + outBuffer.writeZero(ActionConstants.PADDING_IN_ENQUEUE_ACTION); + outBuffer.writeInt(((EnqueueCase) action.getActionChoice()).getEnqueueAction() + .getQueueId().getValue().intValue()); + } + + @Override + protected int getType() { + return ActionConstants.ENQUEUE_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.LARGER_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10OutputActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10OutputActionSerializer.java new file mode 100644 index 0000000000..4f90a40ca1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10OutputActionSerializer.java @@ -0,0 +1,42 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10OutputActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((OutputActionCase) action.getActionChoice()) + .getOutputAction().getPort().getValue().intValue()); + outBuffer.writeShort(((OutputActionCase) action.getActionChoice()) + .getOutputAction().getMaxLength()); + } + + @Override + protected int getType() { + return ActionConstants.OUTPUT_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java new file mode 100644 index 0000000000..f735a4446a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlDstActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetDlDstActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(final Action action, final ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(((SetDlDstCase) action.getActionChoice()) + .getSetDlDstAction().getDlDstAddress())); + outBuffer.writeZero(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_DL_DST_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.LARGER_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java new file mode 100644 index 0000000000..dae1b31897 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetDlSrcActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetDlSrcActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(final Action action, final ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(((SetDlSrcCase) action.getActionChoice()) + .getSetDlSrcAction().getDlSrcAddress())); + outBuffer.writeZero(ActionConstants.PADDING_IN_DL_ADDRESS_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_DL_SRC_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.LARGER_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java new file mode 100644 index 0000000000..a0f9f53f2f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwDstActionSerializer.java @@ -0,0 +1,39 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwDstActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(final Action action, final ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes( + ((SetNwDstCase) action.getActionChoice()).getSetNwDstAction().getIpAddress())); + } + + @Override + protected int getType() { + return ActionConstants.SET_NW_DST_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java new file mode 100644 index 0000000000..77e2be3df8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwSrcActionSerializer.java @@ -0,0 +1,39 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwSrcActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(final Action action, final ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes( + ((SetNwSrcCase) action.getActionChoice()).getSetNwSrcAction().getIpAddress())); + } + + @Override + protected int getType() { + return ActionConstants.SET_NW_SRC_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwTosActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwTosActionSerializer.java new file mode 100644 index 0000000000..8df8c573d2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetNwTosActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTosCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10SetNwTosActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeByte(((SetNwTosCase) action.getActionChoice()).getSetNwTosAction().getNwTos()); + outBuffer.writeZero(ActionConstants.PADDING_IN_SET_NW_TOS_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_NW_TOS_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpDstActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpDstActionSerializer.java new file mode 100644 index 0000000000..d11a1fae2a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpDstActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10SetTpDstActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((SetTpDstCase) action.getActionChoice()).getSetTpDstAction() + .getPort().getValue().intValue()); + outBuffer.writeZero(ActionConstants.PADDING_IN_TP_PORT_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_TP_DST_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpSrcActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpSrcActionSerializer.java new file mode 100644 index 0000000000..ac6ad917de --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetTpSrcActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10SetTpSrcActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((SetTpSrcCase) action.getActionChoice()).getSetTpSrcAction() + .getPort().getValue().intValue()); + outBuffer.writeZero(ActionConstants.PADDING_IN_TP_PORT_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_TP_SRC_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanPcpActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanPcpActionSerializer.java new file mode 100644 index 0000000000..eec2fdadff --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanPcpActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanPcpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10SetVlanPcpActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeByte(((SetVlanPcpCase) action.getActionChoice()).getSetVlanPcpAction().getVlanPcp()); + outBuffer.writeZero(ActionConstants.PADDING_IN_SET_VLAN_PCP_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_VLAN_PCP_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanVidActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanVidActionSerializer.java new file mode 100644 index 0000000000..87ee182197 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10SetVlanVidActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanVidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10SetVlanVidActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((SetVlanVidCase) action.getActionChoice()).getSetVlanVidAction().getVlanVid()); + outBuffer.writeZero(ActionConstants.PADDING_IN_SET_VLAN_VID_ACTION); + } + + @Override + protected int getType() { + return ActionConstants.SET_VLAN_VID_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10StripVlanActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10StripVlanActionSerializer.java new file mode 100644 index 0000000000..77df4755c4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF10StripVlanActionSerializer.java @@ -0,0 +1,39 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + + +/** + * @author michal.polkorab + * + */ +public class OF10StripVlanActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.STRIP_VLAN_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlInActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlInActionSerializer.java new file mode 100644 index 0000000000..5ea47c52d7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlInActionSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13CopyTtlInActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.COPY_TTL_IN_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlOutActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlOutActionSerializer.java new file mode 100644 index 0000000000..16e5d69b02 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13CopyTtlOutActionSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13CopyTtlOutActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.COPY_TTL_OUT_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecMplsTtlActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecMplsTtlActionSerializer.java new file mode 100644 index 0000000000..ec89d2adaa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecMplsTtlActionSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13DecMplsTtlActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.DEC_MPLS_TTL_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecNwTtlActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecNwTtlActionSerializer.java new file mode 100644 index 0000000000..cb5e92e3df --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13DecNwTtlActionSerializer.java @@ -0,0 +1,39 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + + +/** + * @author michal.polkorab + * + */ +public class OF13DecNwTtlActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.DEC_NW_TTL_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13GroupActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13GroupActionSerializer.java new file mode 100644 index 0000000000..055066435a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13GroupActionSerializer.java @@ -0,0 +1,39 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.GroupCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13GroupActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeInt(((GroupCase) action.getActionChoice()).getGroupAction().getGroupId().intValue()); + } + + @Override + protected int getType() { + return ActionConstants.GROUP_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13OutputActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13OutputActionSerializer.java new file mode 100644 index 0000000000..05f78d98b8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13OutputActionSerializer.java @@ -0,0 +1,42 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13OutputActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeInt(((OutputActionCase) action.getActionChoice()).getOutputAction() + .getPort().getValue().intValue()); + outBuffer.writeShort(((OutputActionCase) action.getActionChoice()).getOutputAction().getMaxLength()); + outBuffer.writeZero(ActionConstants.OUTPUT_PADDING); + } + + @Override + protected int getType() { + return ActionConstants.OUTPUT_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.LARGER_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopMplsActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopMplsActionSerializer.java new file mode 100644 index 0000000000..4cfebf7b29 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopMplsActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13PopMplsActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((PopMplsCase) action.getActionChoice()) + .getPopMplsAction().getEthertype().getValue()); + outBuffer.writeZero(ActionConstants.ETHERTYPE_ACTION_PADDING); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.POP_MPLS_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopPbbActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopPbbActionSerializer.java new file mode 100644 index 0000000000..fc3be2b9c7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopPbbActionSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13PopPbbActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.POP_PBB_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopVlanActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopVlanActionSerializer.java new file mode 100644 index 0000000000..863d64a135 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PopVlanActionSerializer.java @@ -0,0 +1,38 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13PopVlanActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeZero(ActionConstants.PADDING_IN_ACTION_HEADER); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.POP_VLAN_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushMplsActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushMplsActionSerializer.java new file mode 100644 index 0000000000..f9d027579a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushMplsActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13PushMplsActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((PushMplsCase) action.getActionChoice()) + .getPushMplsAction().getEthertype().getValue()); + outBuffer.writeZero(ActionConstants.ETHERTYPE_ACTION_PADDING); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.PUSH_MPLS_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushPbbActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushPbbActionSerializer.java new file mode 100644 index 0000000000..d3b68eb83f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushPbbActionSerializer.java @@ -0,0 +1,41 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13PushPbbActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((PushPbbCase) action.getActionChoice()) + .getPushPbbAction().getEthertype().getValue()); + outBuffer.writeZero(ActionConstants.ETHERTYPE_ACTION_PADDING); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.PUSH_PBB_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushVlanActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushVlanActionSerializer.java new file mode 100644 index 0000000000..696aa59f3b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13PushVlanActionSerializer.java @@ -0,0 +1,42 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + + +/** + * @author michal.polkorab + * + */ +public class OF13PushVlanActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeShort(((PushVlanCase) action.getActionChoice()) + .getPushVlanAction().getEthertype().getValue()); + outBuffer.writeZero(ActionConstants.ETHERTYPE_ACTION_PADDING); + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + + @Override + protected int getType() { + return ActionConstants.PUSH_VLAN_CODE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializer.java new file mode 100644 index 0000000000..59a3e3dfa8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializer.java @@ -0,0 +1,71 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer; +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.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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.common.action.rev150203.action.grouping.action.choice.SetFieldCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * @author michal.polkorab + * + */ +public class OF13SetFieldActionSerializer implements OFSerializer, + HeaderSerializer, SerializerRegistryInjector { + + private SerializerRegistry registry; + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + int startIndex = outBuffer.writerIndex(); + outBuffer.writeShort(ActionConstants.SET_FIELD_CODE); + int lengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + MatchEntry entry = ((SetFieldCase) action.getActionChoice()).getSetFieldAction() + .getMatchEntry().get(0); + MatchEntrySerializerKey key = new MatchEntrySerializerKey<>( + EncodeConstants.OF13_VERSION_ID, entry.getOxmClass(), entry.getOxmMatchField()); + if (entry.getOxmClass().equals(ExperimenterClass.class)) { + ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) entry.getMatchEntryValue(); + key.setExperimenterId(experimenterIdCase.getExperimenter().getExperimenter().getValue()); + } else { + key.setExperimenterId(null); + } + OFSerializer serializer = registry.getSerializer(key); + serializer.serialize(entry, outBuffer); + int paddingRemainder = (outBuffer.writerIndex() - startIndex) % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + outBuffer.writeZero(EncodeConstants.PADDING - paddingRemainder); + } + outBuffer.setShort(lengthIndex, outBuffer.writerIndex() - startIndex); + } + + @Override + public void serializeHeader(Action input, ByteBuf outBuffer) { + outBuffer.writeShort(ActionConstants.SET_FIELD_CODE); + outBuffer.writeShort(ActionConstants.ACTION_IDS_LENGTH); + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetMplsTtlActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetMplsTtlActionSerializer.java new file mode 100644 index 0000000000..95c950afca --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetMplsTtlActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13SetMplsTtlActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeByte(((SetMplsTtlCase) action.getActionChoice()).getSetMplsTtlAction().getMplsTtl()); + outBuffer.writeZero(ActionConstants.SET_MPLS_TTL_PADDING); + } + + @Override + protected int getType() { + return ActionConstants.SET_MPLS_TTL_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetNwTtlActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetNwTtlActionSerializer.java new file mode 100644 index 0000000000..7262fba05c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetNwTtlActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13SetNwTtlActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeByte(((SetNwTtlCase) action.getActionChoice()).getSetNwTtlAction().getNwTtl()); + outBuffer.writeZero(ActionConstants.SET_NW_TTL_PADDING); + } + + @Override + protected int getType() { + return ActionConstants.SET_NW_TTL_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetQueueActionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetQueueActionSerializer.java new file mode 100644 index 0000000000..8a2a0d8518 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetQueueActionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.action; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF13SetQueueActionSerializer extends AbstractActionSerializer { + + @Override + public void serialize(Action action, ByteBuf outBuffer) { + super.serialize(action, outBuffer); + outBuffer.writeInt(((SetQueueCase) action.getActionChoice()).getSetQueueAction() + .getQueueId().intValue()); + } + + @Override + protected int getType() { + return ActionConstants.SET_QUEUE_CODE; + } + + @Override + protected int getLength() { + return ActionConstants.GENERAL_ACTION_LENGTH; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactory.java new file mode 100644 index 0000000000..157dcc9a29 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactory.java @@ -0,0 +1,33 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; + +/** + * Translates BarrierRequest messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class BarrierInputMessageFactory implements OFSerializer { + + /** Code type of BarrierRequest message */ + private static final byte MESSAGE_TYPE = 20; + + @Override + public void serialize(BarrierInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactory.java new file mode 100644 index 0000000000..3212f7849d --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactory.java new file mode 100644 index 0000000000..23c0c03168 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactory.java @@ -0,0 +1,38 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput; + +/** + * Translates EchoRequest messages (both OpenFlow v1.0 and OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoInputMessageFactory implements OFSerializer { + + /** Code type of EchoRequest message */ + private static final byte MESSAGE_TYPE = 2; + + @Override + public void serialize(EchoInput 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactory.java new file mode 100644 index 0000000000..3a244db3fb --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactory.java new file mode 100644 index 0000000000..8b9bf8ae70 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactory.java @@ -0,0 +1,38 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; + +/** + * Translates EchoReply messages (both OpenFlow v1.0 and OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoReplyInputMessageFactory implements OFSerializer{ + + /** Code type of EchoReply message */ + private static final byte MESSAGE_TYPE = 3; + + @Override + public void serialize(EchoReplyInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + byte[] data = message.getData(); + if (data != null) { + outBuffer.writeBytes(data); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactory.java new file mode 100644 index 0000000000..9f5076cd20 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactory.java new file mode 100644 index 0000000000..2eeaf76eee --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java new file mode 100644 index 0000000000..b544a8ffd1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactory.java @@ -0,0 +1,53 @@ +/* + * 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.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.ExperimenterOfMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; + +/** + * Translates Experimenter messages (both: symmetric request and single reply) + * @author michal.polkorab + */ +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(ExperimenterOfMessage message, ByteBuf outBuffer) { + long expId = message.getExperimenter().getValue(); + OFSerializer serializer = registry.getSerializer( + ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( + 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 + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterMessageFactory.java new file mode 100644 index 0000000000..dc6e66c81e --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java new file mode 100644 index 0000000000..336b3d0347 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactory.java @@ -0,0 +1,75 @@ +/* + * 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.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.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.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.FlowMod; + +/** + * Translates FlowMod messages. + * OF protocol versions: 1.3. + * @author timotej.kubas + * @author michal.polkorab + */ +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 = + TypeKeyMakerFactory.createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID); + private SerializerRegistry registry; + + @Override + public void serialize(final FlowMod message, final ByteBuf outBuffer) { + int index = outBuffer.writerIndex(); + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeLong(message.getCookie().longValue()); + outBuffer.writeLong(message.getCookieMask().longValue()); + outBuffer.writeByte(message.getTableId().getValue().byteValue()); + outBuffer.writeByte(message.getCommand().getIntValue()); + outBuffer.writeShort(message.getIdleTimeout()); + outBuffer.writeShort(message.getHardTimeout()); + outBuffer.writeShort(message.getPriority()); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeInt(message.getOutPort().getValue().intValue()); + outBuffer.writeInt(message.getOutGroup().intValue()); + outBuffer.writeShort(createFlowModFlagsBitmask(message.getFlags())); + outBuffer.writeZero(PADDING_IN_FLOW_MOD_MESSAGE); + registry.>getSerializer(new MessageTypeKey<>(message.getVersion(), Match.class)) + .serialize(message.getMatch(), outBuffer); + ListSerializer.serializeList(message.getInstruction(), INSTRUCTION_KEY_MAKER, registry, outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer, index); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + + private static int createFlowModFlagsBitmask(final FlowModFlags flags) { + return ByteBufUtils.fillBitMask(0, + flags.isOFPFFSENDFLOWREM(), + flags.isOFPFFCHECKOVERLAP(), + flags.isOFPFFRESETCOUNTS(), + flags.isOFPFFNOPKTCOUNTS(), + flags.isOFPFFNOBYTCOUNTS()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactory.java new file mode 100644 index 0000000000..11c2948bbd --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactory.java new file mode 100644 index 0000000000..4ba876c461 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncRequestMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncRequestMessageFactory.java new file mode 100644 index 0000000000..dd6c922f4f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncRequestMessageFactory.java @@ -0,0 +1,31 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput; + +/** + * Translates GetAsyncRequest messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class GetAsyncRequestMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 26; + + @Override + public void serialize(GetAsyncInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactory.java new file mode 100644 index 0000000000..2686abc820 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactory.java @@ -0,0 +1,33 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput; + +/** + * Translates GetConfigRequest messages (both OpenFlow v1.0 and OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class GetConfigInputMessageFactory implements OFSerializer { + + /** Code type of GetConfigRequest message */ + private static final byte MESSAGE_TYPE = 7; + + @Override + public void serialize(GetConfigInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..d711b864ed --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactory.java new file mode 100644 index 0000000000..515bb8a020 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactory.java @@ -0,0 +1,33 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput; + +/** + * Translates FeaturesRequest messages (both OpenFlow v1.0 and OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class GetFeaturesInputMessageFactory implements OFSerializer{ + + /** Code type of FeaturesRequest message */ + private static final byte MESSAGE_TYPE = 5; + + @Override + public void serialize(GetFeaturesInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactory.java new file mode 100644 index 0000000000..2a2fdc2a84 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactory.java new file mode 100644 index 0000000000..f8ac9f7c73 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactory.java @@ -0,0 +1,36 @@ +/* + * 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.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.GetQueueConfigInput; + +/** + * Translates QueueGetConfigRequest messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class GetQueueConfigInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 22; + private static final byte PADDING_IN_GET_QUEUE_CONFIG_MESSAGE = 4; + + @Override + public void serialize(GetQueueConfigInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getPort().getValue().intValue()); + outBuffer.writeZero(PADDING_IN_GET_QUEUE_CONFIG_MESSAGE); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java new file mode 100644 index 0000000000..db8142a54f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactory.java @@ -0,0 +1,68 @@ +/* + * 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.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.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.GroupMod; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.buckets.grouping.BucketsList; + +/** + * Translates GroupMod messages. + * OF protocol versions: 1.3. + * @author timotej.kubas + * @author michal.polkorab + */ +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(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, index); + } + + private void serializerBuckets(List buckets, ByteBuf outBuffer) { + if (buckets != null) { + for (BucketsList currentBucket : buckets) { + int bucketLengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(currentBucket.getWeight().shortValue()); + outBuffer.writeInt(currentBucket.getWatchPort().getValue().intValue()); + outBuffer.writeInt(currentBucket.getWatchGroup().intValue()); + outBuffer.writeZero(PADDING_IN_BUCKET); + ListSerializer.serializeList(currentBucket.getAction(), TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, outBuffer); + outBuffer.setShort(bucketLengthIndex, outBuffer.writerIndex() - bucketLengthIndex); + } + } + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactory.java new file mode 100644 index 0000000000..bd87e16f67 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactory.java @@ -0,0 +1,66 @@ +/* + * 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.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.common.types.rev130731.HelloElementType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements; + +/** + * Translates Hello messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class HelloInputMessageFactory implements OFSerializer{ + + /** Code type of Hello message */ + private static final byte MESSAGE_TYPE = 0; + private static final byte HELLO_ELEMENT_HEADER_SIZE = 4; + + private static void serializeElementsList(HelloInput message, ByteBuf output) { + int[] versionBitmap; + if (message.getElements() != null) { + for (Elements currElement : message.getElements()) { + int elementStartIndex = output.writerIndex(); + output.writeShort(currElement.getType().getIntValue()); + if (currElement.getType().equals(HelloElementType.VERSIONBITMAP)) { + int elementLengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + versionBitmap = ByteBufUtils.fillBitMaskFromList(currElement.getVersionBitmap()); + for (int i = 0; i < versionBitmap.length; i++) { + output.writeInt(versionBitmap[i]); + } + int length = output.writerIndex() - elementStartIndex; + int padding = length - versionBitmap.length * 4 - HELLO_ELEMENT_HEADER_SIZE; + output.writeZero(padding); + output.setShort(elementLengthIndex, output.writerIndex() - elementStartIndex); + } + } + } + } + + @Override + public void serialize(HelloInput message, ByteBuf outBuffer) { + int startWriterIndex = outBuffer.writerIndex(); + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + serializeElementsList(message, outBuffer); + int endWriterIndex = outBuffer.writerIndex(); + int paddingRemainder = (endWriterIndex - startWriterIndex) % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + outBuffer.writeZero(EncodeConstants.PADDING - paddingRemainder); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloMessageFactory.java new file mode 100644 index 0000000000..b3ccbbe70a --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java new file mode 100755 index 0000000000..36eb64f5f2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactory.java @@ -0,0 +1,118 @@ +/* + * 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.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.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; +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.meter.mod.Bands; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Translates MeterMod messages + * @author timotej.kubas + * @author michal.polkorab + */ +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; + private static final short PADDING_IN_METER_BAND_DSCP_REMARK = 3; + private SerializerRegistry registry; + + @Override + public void serialize(final MeterModInput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getCommand().getIntValue()); + outBuffer.writeShort(createMeterFlagsBitmask(message.getFlags())); + outBuffer.writeInt(message.getMeterId().getValue().intValue()); + serializeBands(message.getBands(), outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private static int createMeterFlagsBitmask(final MeterFlags flags) { + return ByteBufUtils.fillBitMask(0, + flags.isOFPMFKBPS(), + flags.isOFPMFPKTPS(), + flags.isOFPMFBURST(), + flags.isOFPMFSTATS()); + } + + private void serializeBands(final List bands, final ByteBuf outBuffer) { + if (bands != null) { + for (Bands currentBand : bands) { + MeterBand meterBand = currentBand.getMeterBand(); + if (meterBand instanceof MeterBandDropCase) { + MeterBandDropCase dropBandCase = (MeterBandDropCase) meterBand; + MeterBandDrop dropBand = dropBandCase.getMeterBandDrop(); + writeBandCommonFields(dropBand, outBuffer); + outBuffer.writeZero(PADDING_IN_METER_BAND_DROP); + } else if (meterBand instanceof MeterBandDscpRemarkCase) { + MeterBandDscpRemarkCase dscpRemarkBandCase = (MeterBandDscpRemarkCase) meterBand; + MeterBandDscpRemark dscpRemarkBand = dscpRemarkBandCase.getMeterBandDscpRemark(); + writeBandCommonFields(dscpRemarkBand, outBuffer); + outBuffer.writeByte(dscpRemarkBand.getPrecLevel()); + outBuffer.writeZero(PADDING_IN_METER_BAND_DSCP_REMARK); + } else if (meterBand instanceof MeterBandExperimenterCase) { + MeterBandExperimenterCase experimenterBandCase = (MeterBandExperimenterCase) meterBand; + MeterBandExperimenter experimenterBand = experimenterBandCase.getMeterBandExperimenter(); + 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); + } + } + } + } + } + } + + 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()); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + registry = serializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactory.java new file mode 100644 index 0000000000..4c5bd83a17 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java new file mode 100644 index 0000000000..daa208d530 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactory.java @@ -0,0 +1,414 @@ +/* + * 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.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.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.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.MultipartRequestFlags; +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.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; +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.MultipartRequestFlowCase; +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.MultipartRequestGroupDescCase; +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.MultipartRequestMeterCase; +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.MultipartRequestMeterFeaturesCase; +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.MultipartRequestPortStatsCase; +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.MultipartRequestTableCase; +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.multipart.request.aggregate._case.MultipartRequestAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.group._case.MultipartRequestGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter._case.MultipartRequestMeter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.meter.config._case.MultipartRequestMeterConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.table.features._case.MultipartRequestTableFeatures; +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.table.features.properties.grouping.TableFeatureProperties; + +/** + * Translates MultipartRequest messages. + * @author timotej.kubas + * @author michal.polkorab + */ +public class MultipartRequestInputFactory implements OFSerializer, SerializerRegistryInjector { + private static final byte MESSAGE_TYPE = 18; + private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4; + 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; + private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3; + private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01 = 3; + private static final byte PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02 = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4; + private static final byte PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY = 5; + private SerializerRegistry registry; + + @Override + public void serialize(final MultipartRequestInput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getType().getIntValue()); + outBuffer.writeShort(createMultipartRequestFlagsBitmask(message.getFlags())); + outBuffer.writeZero(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + + if (message.getMultipartRequestBody() instanceof MultipartRequestDescCase){ + serializeDescBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlowCase) { + serializeFlowBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregateCase) { + serializeAggregateBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableCase) { + serializeTableBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStatsCase) { + serializePortStatsBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestQueueCase) { + serializeQueueBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupCase) { + serializeeGroupStatsBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupDescCase) { + serializeGroupDescBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestGroupFeaturesCase) { + serializeGroupFeaturesBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterCase) { + serializeMeterBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterConfigCase) { + serializeMeterConfigBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestMeterFeaturesCase) { + serializeMeterFeaturesBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableFeaturesCase) { + serializeTableFeaturesBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortDescCase) { + serializePortDescBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenterCase) { + serializeExperimenterBody(message, outBuffer); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private void serializeExperimenterBody(final MultipartRequestInput message, + final ByteBuf outBuffer) { + MultipartRequestExperimenterCase expCase = + (MultipartRequestExperimenterCase) message.getMultipartRequestBody(); + MultipartRequestExperimenter experimenter = expCase.getMultipartRequestExperimenter(); + 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, expType)); + serializer.serialize(experimenter.getExperimenterDataOfChoice(), outBuffer); + } + + private static int createMultipartRequestFlagsBitmask(final MultipartRequestFlags flags) { + return ByteBufUtils.fillBitMask(0, flags.isOFPMPFREQMORE()); + } + + private void serializeDescBody() { + // The body of MultiPartRequestDesc is empty + } + + private void serializeTableBody() { + // The body of MultiPartTable is empty + } + + private void serializeGroupDescBody() { + // The body of MultiPartRequestGroupDesc is empty + } + + private void serializeGroupFeaturesBody() { + // The body of MultiPartRequestGroupFeatures is empty + } + + private void serializeMeterFeaturesBody() { + // The body of MultiPartMeterFeatures is empty + } + + private void serializePortDescBody() { + // The body of MultiPartPortDesc is empty + } + + private void serializeFlowBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestFlowCase flowCase = (MultipartRequestFlowCase) multipartRequestBody; + MultipartRequestFlow flow = flowCase.getMultipartRequestFlow(); + output.writeByte(flow.getTableId().byteValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01); + output.writeInt(flow.getOutPort().intValue()); + output.writeInt(flow.getOutGroup().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02); + output.writeLong(flow.getCookie().longValue()); + output.writeLong(flow.getCookieMask().longValue()); + OFSerializer serializer = registry.getSerializer(new MessageTypeKey<>( + EncodeConstants.OF13_VERSION_ID, Match.class)); + serializer.serialize(flow.getMatch(), output); + } + + private void serializeAggregateBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestAggregateCase aggregateCase = (MultipartRequestAggregateCase) multipartRequestBody; + MultipartRequestAggregate aggregate = aggregateCase.getMultipartRequestAggregate(); + output.writeByte(aggregate.getTableId().byteValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_01); + output.writeInt(aggregate.getOutPort().intValue()); + output.writeInt(aggregate.getOutGroup().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_AGREGGATE_BODY_02); + output.writeLong(aggregate.getCookie().longValue()); + output.writeLong(aggregate.getCookieMask().longValue()); + OFSerializer serializer = registry.getSerializer(new MessageTypeKey<>( + EncodeConstants.OF13_VERSION_ID, Match.class)); + serializer.serialize(aggregate.getMatch(), output); + } + + private static void serializePortStatsBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestPortStatsCase portstatsCase = (MultipartRequestPortStatsCase) multipartRequestBody; + MultipartRequestPortStats portstats = portstatsCase.getMultipartRequestPortStats(); + output.writeInt(portstats.getPortNo().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY); + } + + private static void serializeQueueBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestQueueCase queueCase = (MultipartRequestQueueCase) multipartRequestBody; + MultipartRequestQueue queue = queueCase.getMultipartRequestQueue(); + output.writeInt(queue.getPortNo().intValue()); + output.writeInt(queue.getQueueId().intValue()); + } + + private static void serializeeGroupStatsBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestGroupCase groupStatsCase = (MultipartRequestGroupCase) multipartRequestBody; + MultipartRequestGroup groupStats = groupStatsCase.getMultipartRequestGroup(); + output.writeInt(groupStats.getGroupId().getValue().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY); + } + + private static void serializeMeterBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestMeterCase meterCase = (MultipartRequestMeterCase) multipartRequestBody; + MultipartRequestMeter meter = meterCase.getMultipartRequestMeter(); + output.writeInt(meter.getMeterId().getValue().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_METER_BODY); + } + + private static void serializeMeterConfigBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestMeterConfigCase meterConfigCase = (MultipartRequestMeterConfigCase) multipartRequestBody; + MultipartRequestMeterConfig meterConfig = meterConfigCase.getMultipartRequestMeterConfig(); + output.writeInt(meterConfig.getMeterId().getValue().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY); + } + + private void serializeTableFeaturesBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + if (multipartRequestBody != null) { + MultipartRequestTableFeaturesCase tableFeaturesCase = (MultipartRequestTableFeaturesCase) multipartRequestBody; + MultipartRequestTableFeatures tableFeatures = tableFeaturesCase.getMultipartRequestTableFeatures(); + if(tableFeatures.getTableFeatures() != null) { + for (TableFeatures currTableFeature : tableFeatures.getTableFeatures()) { + int tableFeatureLengthIndex = output.writerIndex(); + output.writeShort(EncodeConstants.EMPTY_LENGTH); + output.writeByte(currTableFeature.getTableId()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_TABLE_FEATURES_BODY); + output.writeBytes(currTableFeature.getName().getBytes()); + output.writeZero(32 - currTableFeature.getName().getBytes().length); + output.writeLong(currTableFeature.getMetadataMatch().longValue()); + output.writeLong(currTableFeature.getMetadataWrite().longValue()); + output.writeInt(createTableConfigBitmask(currTableFeature.getConfig())); + output.writeInt(currTableFeature.getMaxEntries().intValue()); + writeTableFeatureProperties(output, currTableFeature.getTableFeatureProperties()); + output.setShort(tableFeatureLengthIndex, output.writerIndex() - tableFeatureLengthIndex); + } + } + } + } + + private void writeTableFeatureProperties(final ByteBuf output, final List props) { + if (props != null) { + for (TableFeatureProperties property : props) { + TableFeaturesPropType type = property.getType(); + if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONS)) { + writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS)) { + writeInstructionRelatedTableProperty(output, property, INSTRUCTIONS_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLES)) { + writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTNEXTTABLESMISS)) { + writeNextTableRelatedTableProperty(output, property, NEXT_TABLE_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONS)) { + writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS)) { + writeActionsRelatedTableProperty(output, property, WRITE_ACTIONS_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONS)) { + writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS)) { + writeActionsRelatedTableProperty(output, property, APPLY_ACTIONS_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTMATCH)) { + writeOxmRelatedTableProperty(output, property, MATCH_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWILDCARDS)) { + writeOxmRelatedTableProperty(output, property, WILDCARDS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELD)) { + writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS)) { + writeOxmRelatedTableProperty(output, property, WRITE_SETFIELD_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELD)) { + writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS)) { + writeOxmRelatedTableProperty(output, property, APPLY_SETFIELD_MISS_CODE); + } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTER)) { + writeExperimenterRelatedTableProperty(output, property); + } else if (type.equals(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS)) { + writeExperimenterRelatedTableProperty(output, property); + } + } + } + } + + 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 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 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 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 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 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 static int createTableConfigBitmask(final TableConfig tableConfig) { + return ByteBufUtils.fillBitMask(3, tableConfig.isOFPTCDEPRECATEDMASK()); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactory.java new file mode 100644 index 0000000000..cb1fce88d4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactory.java @@ -0,0 +1,31 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; + +/** + * Translates BarrierRequest messages + * @author michal.polkorab + */ +public class OF10BarrierInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 18; + + @Override + public void serialize(BarrierInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactory.java new file mode 100644 index 0000000000..2e317a1d44 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactory.java new file mode 100644 index 0000000000..0df774dfba --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactory.java new file mode 100644 index 0000000000..790f0df9ea --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactory.java @@ -0,0 +1,67 @@ +/* + * 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.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.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.FlowModFlagsV10; +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; + +/** + * Translates FlowMod messages + * @author michal.polkorab + */ +public class OF10FlowModInputMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 14; + private static final TypeKeyMaker ACTION_KEY_MAKER = + TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF10_VERSION_ID); + private SerializerRegistry registry; + + @Override + public void serialize(final FlowModInput message, final 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.getCommand().getIntValue()); + outBuffer.writeShort(message.getIdleTimeout().intValue()); + outBuffer.writeShort(message.getHardTimeout().intValue()); + outBuffer.writeShort(message.getPriority()); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeShort(message.getOutPort().getValue().intValue()); + outBuffer.writeShort(createFlowModFlagsBitmask(message.getFlagsV10())); + ListSerializer.serializeList(message.getAction(), ACTION_KEY_MAKER, registry, outBuffer); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + private static int createFlowModFlagsBitmask(final FlowModFlagsV10 flags) { + return ByteBufUtils.fillBitMask(0, + flags.isOFPFFSENDFLOWREM(), + flags.isOFPFFCHECKOVERLAP(), + flags.isOFPFFEMERG()); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactory.java new file mode 100644 index 0000000000..71b5a28b1c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactory.java new file mode 100644 index 0000000000..73a7b81c2c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactory.java @@ -0,0 +1,31 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; + +/** + * Translates Hello messages + * @author michal.polkorab + */ +public class OF10HelloInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 0; + + @Override + public void serialize(HelloInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactory.java new file mode 100644 index 0000000000..d2a1812fdd --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactory.java new file mode 100644 index 0000000000..a83c1a6d4e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactory.java @@ -0,0 +1,54 @@ +/* + * 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.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.util.ByteBufUtils; +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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput; + +/** + * Translates PacketOut messages + * @author michal.polkorab + */ +public class OF10PacketOutInputMessageFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 13; + private SerializerRegistry registry; + + @Override + public void serialize(PacketOutInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeShort(message.getInPort().getValue().intValue()); + int actionsLengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + int actionsStartIndex = outBuffer.writerIndex(); + ListSerializer.serializeList(message.getAction(), TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF10_VERSION_ID), registry, outBuffer); + outBuffer.setShort(actionsLengthIndex, outBuffer.writerIndex() - actionsStartIndex); + byte[] data = message.getData(); + if (data != null) { + outBuffer.writeBytes(data); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java new file mode 100644 index 0000000000..e4822a264a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactory.java @@ -0,0 +1,72 @@ +/* + * 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.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.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; + +/** + * Translates PortMod messages + * @author michal.polkorab + */ +public class OF10PortModInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 15; + private static final byte PADDING_IN_PORT_MOD_MESSAGE = 4; + + @Override + public void serialize(final PortModInput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getPortNo().getValue().intValue()); + outBuffer.writeBytes(IetfYangUtil.INSTANCE.bytesFor(message.getHwAddress())); + outBuffer.writeInt(createPortConfigBitmask(message.getConfigV10())); + outBuffer.writeInt(createPortConfigBitmask(message.getMaskV10())); + outBuffer.writeInt(createPortFeaturesBitmask(message.getAdvertiseV10())); + outBuffer.writeZero(PADDING_IN_PORT_MOD_MESSAGE); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + /** + * @param config + * @return port config bitmask + */ + private static int createPortConfigBitmask(final PortConfigV10 config) { + return ByteBufUtils.fillBitMask(0, + config.isPortDown(), + config.isNoStp(), + config.isNoRecv(), + config.isNoRecvStp(), + config.isNoFlood(), + config.isNoFwd(), + config.isNoPacketIn()); + } + + private static int createPortFeaturesBitmask(final PortFeaturesV10 feature) { + return ByteBufUtils.fillBitMask(0, + feature.is_10mbHd(), + feature.is_10mbFd(), + feature.is_100mbHd(), + feature.is_100mbFd(), + feature.is_1gbHd(), + feature.is_1gbFd(), + feature.is_10gbFd(), + feature.isCopper(), + feature.isFiber(), + feature.isAutoneg(), + feature.isPause(), + feature.isPauseAsym()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactory.java new file mode 100644 index 0000000000..25d0f5ceaf --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactory.java @@ -0,0 +1,110 @@ +/* + * 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.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.PortStatusMessage; + +/** + * @author giuseppex.petralia@intel.com + * + */ +public class OF10PortStatusMessageFactory 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactory.java new file mode 100644 index 0000000000..7afa4bc25c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactory.java @@ -0,0 +1,35 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput; + +/** + * Translates QueueGetConfigRequest messages + * @author michal.polkorab + */ +public class OF10QueueGetConfigInputMessageFactory implements OFSerializer { + + private static final byte MESSAGE_TYPE = 20; + private static final byte PADDING_IN_GET_QUEUE_CONFIG_MESSAGE = 2; + + @Override + public void serialize(GetQueueConfigInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeShort(message.getPort().getValue().intValue()); + outBuffer.writeZero(PADDING_IN_GET_QUEUE_CONFIG_MESSAGE); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..8504447939 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactory.java new file mode 100644 index 0000000000..268f7f0621 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java new file mode 100644 index 0000000000..fa01f6d8fc --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactory.java @@ -0,0 +1,150 @@ +/* + * 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.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.openflowjava.util.ExperimenterSerializerKeyFactory; +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; +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.MultipartRequestFlowCase; +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.MultipartRequestQueueCase; +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.multipart.request.aggregate._case.MultipartRequestAggregate; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.experimenter._case.MultipartRequestExperimenter; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.flow._case.MultipartRequestFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.port.stats._case.MultipartRequestPortStats; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.request.multipart.request.body.multipart.request.queue._case.MultipartRequestQueue; + +/** + * Translates StatsRequest messages + * @author michal.polkorab + */ +public class OF10StatsRequestInputFactory implements OFSerializer, SerializerRegistryInjector { + + private static final byte MESSAGE_TYPE = 16; + private static final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY = 1; + private static final byte PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY = 1; + private static final byte PADDING_IN_MULTIPART_REQUEST_PORT_BODY = 6; + private static final byte PADING_IN_QUEUE_BODY = 2; + + private SerializerRegistry registry; + + @Override + public void serialize(final MultipartRequestInput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.OFHEADER_SIZE); + outBuffer.writeShort(message.getType().getIntValue()); + outBuffer.writeShort(createMultipartRequestFlagsBitmask(message.getFlags())); + if (message.getMultipartRequestBody() instanceof MultipartRequestDescCase) { + serializeDescBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestFlowCase) { + serializeFlowBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestAggregateCase) { + serializeAggregateBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestTableCase) { + serializeTableBody(); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestPortStatsCase) { + serializePortBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestQueueCase) { + serializeQueueBody(message.getMultipartRequestBody(), outBuffer); + } else if (message.getMultipartRequestBody() instanceof MultipartRequestExperimenterCase) { + serializeExperimenterBody(message.getMultipartRequestBody(), outBuffer); + } + ByteBufUtils.updateOFHeaderLength(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 + } + + private void serializeFlowBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestFlowCase flowCase = (MultipartRequestFlowCase) multipartRequestBody; + MultipartRequestFlow flow = flowCase.getMultipartRequestFlow(); + OFSerializer matchSerializer = registry.getSerializer(new MessageTypeKey<>( + EncodeConstants.OF10_VERSION_ID, MatchV10.class)); + matchSerializer.serialize(flow.getMatchV10(), output); + output.writeByte(flow.getTableId().shortValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY); + output.writeShort(flow.getOutPort().intValue()); + } + + private void serializeAggregateBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestAggregateCase aggregateCase = (MultipartRequestAggregateCase) multipartRequestBody; + MultipartRequestAggregate aggregate = aggregateCase.getMultipartRequestAggregate(); + OFSerializer matchSerializer = registry.getSerializer(new MessageTypeKey<>( + EncodeConstants.OF10_VERSION_ID, MatchV10.class)); + matchSerializer.serialize(aggregate.getMatchV10(), output); + output.writeByte(aggregate.getTableId().shortValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY); + output.writeShort(aggregate.getOutPort().intValue()); + } + + private static void serializePortBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestPortStatsCase portstatsCase = (MultipartRequestPortStatsCase) multipartRequestBody; + MultipartRequestPortStats portstats = portstatsCase.getMultipartRequestPortStats(); + output.writeShort(portstats.getPortNo().intValue()); + output.writeZero(PADDING_IN_MULTIPART_REQUEST_PORT_BODY); + } + + private static void serializeQueueBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestQueueCase queueCase = (MultipartRequestQueueCase) multipartRequestBody; + MultipartRequestQueue queue = queueCase.getMultipartRequestQueue(); + output.writeShort(queue.getPortNo().intValue()); + output.writeZero(PADING_IN_QUEUE_BODY); + output.writeInt(queue.getQueueId().intValue()); + } + + private void serializeExperimenterBody(final MultipartRequestBody multipartRequestBody, final ByteBuf output) { + MultipartRequestExperimenterCase expCase = (MultipartRequestExperimenterCase) multipartRequestBody; + MultipartRequestExperimenter experimenter = expCase.getMultipartRequestExperimenter(); + final long expId = experimenter.getExperimenter().getValue().longValue(); + + // write experimenterId + output.writeInt((int) expId); + + OFSerializer serializer = registry.getSerializer( + ExperimenterSerializerKeyFactory.createMultipartRequestSerializerKey( + EncodeConstants.OF10_VERSION_ID, expId, + -1 /* in order not to collide with OF >= 1.3 codecs*/)); + serializer.serialize(experimenter.getExperimenterDataOfChoice(), output); + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactory.java new file mode 100644 index 0000000000..713e8edaab --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactory.java new file mode 100644 index 0000000000..f229424d86 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactory.java @@ -0,0 +1,58 @@ +/* + * 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.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.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.PacketOutInput; + +/** + * Translates PacketOut messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class PacketOutInputMessageFactory implements OFSerializer, SerializerRegistryInjector { + + /** Code type of PacketOut message */ + private static final byte MESSAGE_TYPE = 13; + private static final byte PADDING_IN_PACKET_OUT_MESSAGE = 6; + private SerializerRegistry registry; + + @Override + public void serialize(PacketOutInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getBufferId().intValue()); + outBuffer.writeInt(message.getInPort().getValue().intValue()); + int actionsLengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + outBuffer.writeZero(PADDING_IN_PACKET_OUT_MESSAGE); + int actionsStartIndex = outBuffer.writerIndex(); + ListSerializer.serializeList(message.getAction(), TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, outBuffer); + outBuffer.setShort(actionsLengthIndex, outBuffer.writerIndex() - actionsStartIndex); + byte[] data = message.getData(); + if (data != null) { + outBuffer.writeBytes(data); + } + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java new file mode 100644 index 0000000000..03c39887f8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactory.java @@ -0,0 +1,84 @@ +/* + * 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.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.protocol.rev130731.PortMod; + +/** + * Translates PortMod messages. + * OF protocol versions: 1.3. + * @author timotej.kubas + * @author michal.polkorab + */ +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 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(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, index); + } + + /** + * @param config + * @return port config bitmask + */ + private static int createPortConfigBitmask(final PortConfig config) { + int configBitmask = 0; + Map portConfigMap = new HashMap<>(); + portConfigMap.put(0, config.isPortDown()); + portConfigMap.put(2, config.isNoRecv()); + portConfigMap.put(5, config.isNoFwd()); + portConfigMap.put(6, config.isNoPacketIn()); + + configBitmask = ByteBufUtils.fillBitMaskFromMap(portConfigMap); + return configBitmask; + } + + private static int createPortFeaturesBitmask(final PortFeatures feature) { + return ByteBufUtils.fillBitMask(0, feature.is_10mbHd(), + feature.is_10mbFd(), + feature.is_100mbHd(), + feature.is_100mbFd(), + feature.is_1gbHd(), + feature.is_1gbFd(), + feature.is_10gbFd(), + feature.is_40gbFd(), + feature.is_100gbFd(), + feature.is_1tbFd(), + feature.isOther(), + feature.isCopper(), + feature.isFiber(), + feature.isAutoneg(), + feature.isPause(), + feature.isPauseAsym()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactory.java new file mode 100644 index 0000000000..1a4e6fc810 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactory.java new file mode 100644 index 0000000000..3a15aaccde --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactory.java new file mode 100644 index 0000000000..0225665cd3 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactory.java new file mode 100644 index 0000000000..ce7d0cbf61 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactory.java @@ -0,0 +1,38 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; + +/** + * Translates RoleRequest messages + * @author michal.polkorab + * @author timotej.kubas + */ +public class RoleRequestInputMessageFactory implements OFSerializer { + + /** Code type of RoleRequest message */ + private static final byte MESSAGE_TYPE = 24; + private static final byte PADDING_IN_ROLE_REQUEST_MESSAGE = 4; + + @Override + public void serialize(RoleRequestInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeInt(message.getRole().getIntValue()); + outBuffer.writeZero(PADDING_IN_ROLE_REQUEST_MESSAGE); + outBuffer.writeLong(message.getGenerationId().longValue()); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactory.java new file mode 100644 index 0000000000..65cb07e33f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactory.java @@ -0,0 +1,110 @@ +/* + * 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.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.util.ByteBufUtils; +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.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; + +/** + * Translates SetAsync messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class SetAsyncInputMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 28; + + @Override + public void serialize(SetAsyncInput message, ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + serializePacketInMask(message.getPacketInMask(), outBuffer); + serializePortStatusMask(message.getPortStatusMask(), outBuffer); + serializerFlowRemovedMask(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 serializerFlowRemovedMask(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)); + } + } + } + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactory.java new file mode 100644 index 0000000000..84c69ab886 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactory.java @@ -0,0 +1,36 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; + +/** + * Translates SetConfig messages (both OpenFlow v1.0 and OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class SetConfigMessageFactory implements OFSerializer { + + /** Code type of SetConfig message */ + private static final byte MESSAGE_TYPE = 9; + + @Override + public void serialize(SetConfigInput 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactory.java new file mode 100644 index 0000000000..1f5e38a239 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactory.java @@ -0,0 +1,45 @@ +/* + * 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.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.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.TableConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput; + +/** + * Translates TableMod messages + * @author timotej.kubas + * @author michal.polkorab + */ +public class TableModInputMessageFactory implements OFSerializer { + private static final byte MESSAGE_TYPE = 17; + private static final byte PADDING_IN_TABLE_MOD_MESSAGE = 3; + + @Override + public void serialize(final TableModInput message, final ByteBuf outBuffer) { + ByteBufUtils.writeOFHeader(MESSAGE_TYPE, message, outBuffer, EncodeConstants.EMPTY_LENGTH); + outBuffer.writeByte(message.getTableId().getValue().byteValue()); + outBuffer.writeZero(PADDING_IN_TABLE_MOD_MESSAGE); + outBuffer.writeInt(createConfigBitmask(message.getConfig())); + ByteBufUtils.updateOFHeaderLength(outBuffer); + } + + /** + * @param tableConfig + * @return port config bitmask + */ + private static int createConfigBitmask(final TableConfig tableConfig) { + return ByteBufUtils.fillBitMask(3, tableConfig.isOFPTCDEPRECATEDMASK()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java new file mode 100644 index 0000000000..2cc7148e94 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactory.java @@ -0,0 +1,46 @@ +/* + * 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.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.ExperimenterOfMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; + +/** + * Translates Vendor messages (OF-1.0 limited version - skipping experimenter type) + * @author michal.polkorab + */ +public class VendorInputMessageFactory implements OFSerializer, + SerializerRegistryInjector { + + private SerializerRegistry registry; + + @Override + public void serialize(ExperimenterOfMessage message, ByteBuf outBuffer) { + long expId = message.getExperimenter().getValue(); + OFSerializer serializer = registry.getSerializer( + ExperimenterSerializerKeyFactory.createExperimenterMessageSerializerKey( + EncodeConstants.OF10_VERSION_ID, expId, message.getExpType().longValue())); + + // write experimenterId + outBuffer.writeInt(message.getExperimenter().getValue().intValue()); + + serializer.serialize(message.getExperimenterDataOfChoice(), outBuffer); + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractActionInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractActionInstructionSerializer.java new file mode 100644 index 0000000000..c1f3d7bbd0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractActionInstructionSerializer.java @@ -0,0 +1,53 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +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.InstructionConstants; +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.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractActionInstructionSerializer extends AbstractInstructionSerializer + implements SerializerRegistryInjector { + + private static final TypeKeyMaker ACTION_KEY_MAKER = + TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID); + + private SerializerRegistry registry; + + protected void writeActions(final List actions, final ByteBuf outBuffer, int startIndex) { + int lengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + outBuffer.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + ListSerializer.serializeList(actions, ACTION_KEY_MAKER, getRegistry(), outBuffer); + int instructionLength = outBuffer.writerIndex() - startIndex; + outBuffer.setShort(lengthIndex, instructionLength); + } + + protected SerializerRegistry getRegistry() { + return registry; + } + + @Override + public void injectSerializerRegistry(final SerializerRegistry serializerRegistry) { + registry = serializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractInstructionSerializer.java new file mode 100644 index 0000000000..c5d3331733 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/AbstractInstructionSerializer.java @@ -0,0 +1,36 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public abstract class AbstractInstructionSerializer implements OFSerializer, + HeaderSerializer { + + @Override + public void serializeHeader(Instruction input, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(InstructionConstants.INSTRUCTION_IDS_LENGTH); + } + + /** + * @return numeric representation of action type + */ + protected abstract int getType(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ApplyActionsInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ApplyActionsInstructionSerializer.java new file mode 100644 index 0000000000..4d6f1f53ec --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ApplyActionsInstructionSerializer.java @@ -0,0 +1,45 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.instruction.grouping.instruction.choice.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class ApplyActionsInstructionSerializer extends AbstractActionInstructionSerializer { + + @Override + public void serialize(final Instruction instruction, final ByteBuf outBuffer) { + int startIndex = outBuffer.writerIndex(); + outBuffer.writeShort(getType()); + ApplyActionsCase actionsCase = (ApplyActionsCase) instruction.getInstructionChoice(); + if (actionsCase != null) { + List actions = actionsCase.getApplyActions().getAction(); + writeActions(actions, outBuffer, startIndex); + } else { + outBuffer.writeShort(InstructionConstants.STANDARD_INSTRUCTION_LENGTH); + outBuffer.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + } + } + + @Override + protected int getType() { + return InstructionConstants.APPLY_ACTIONS_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ClearActionsInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ClearActionsInstructionSerializer.java new file mode 100644 index 0000000000..b8585b05f5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/ClearActionsInstructionSerializer.java @@ -0,0 +1,34 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class ClearActionsInstructionSerializer extends AbstractInstructionSerializer { + + @Override + public void serialize(final Instruction instruction, final ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(InstructionConstants.STANDARD_INSTRUCTION_LENGTH); + outBuffer.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + } + + @Override + protected int getType() { + return InstructionConstants.CLEAR_ACTIONS_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/GoToTableInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/GoToTableInstructionSerializer.java new file mode 100644 index 0000000000..4aca403bea --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/GoToTableInstructionSerializer.java @@ -0,0 +1,37 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class GoToTableInstructionSerializer extends AbstractInstructionSerializer { + + @Override + public void serialize(Instruction instruction, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(InstructionConstants.STANDARD_INSTRUCTION_LENGTH); + outBuffer.writeByte(((GotoTableCase) instruction.getInstructionChoice()) + .getGotoTable().getTableId()); + outBuffer.writeZero(InstructionConstants.PADDING_IN_GOTO_TABLE); + } + + @Override + protected int getType() { + return InstructionConstants.GOTO_TABLE_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/MeterInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/MeterInstructionSerializer.java new file mode 100644 index 0000000000..cd1099fef8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/MeterInstructionSerializer.java @@ -0,0 +1,36 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class MeterInstructionSerializer extends AbstractInstructionSerializer { + + @Override + public void serialize(Instruction instruction, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(InstructionConstants.STANDARD_INSTRUCTION_LENGTH); + outBuffer.writeInt(((MeterCase) instruction.getInstructionChoice()) + .getMeter().getMeterId().intValue()); + } + + @Override + protected int getType() { + return InstructionConstants.METER_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteActionsInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteActionsInstructionSerializer.java new file mode 100644 index 0000000000..28393a5e9c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteActionsInstructionSerializer.java @@ -0,0 +1,45 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +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.instruction.grouping.instruction.choice.WriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class WriteActionsInstructionSerializer extends AbstractActionInstructionSerializer { + + @Override + public void serialize(final Instruction instruction, final ByteBuf outBuffer) { + int startIndex = outBuffer.writerIndex(); + outBuffer.writeShort(getType()); + WriteActionsCase actionsCase = (WriteActionsCase) instruction.getInstructionChoice(); + if (actionsCase != null) { + List actions = actionsCase.getWriteActions().getAction(); + writeActions(actions, outBuffer, startIndex); + } else { + outBuffer.writeShort(InstructionConstants.STANDARD_INSTRUCTION_LENGTH); + outBuffer.writeZero(InstructionConstants.PADDING_IN_ACTIONS_INSTRUCTION); + } + } + + @Override + protected int getType() { + return InstructionConstants.WRITE_ACTIONS_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteMetadataInstructionSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteMetadataInstructionSerializer.java new file mode 100644 index 0000000000..a9b2a90754 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/instruction/WriteMetadataInstructionSerializer.java @@ -0,0 +1,40 @@ +/* + * 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.serialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.impl.util.InstructionConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.write.metadata._case.WriteMetadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class WriteMetadataInstructionSerializer extends AbstractInstructionSerializer { + + @Override + public void serialize(Instruction instruction, ByteBuf outBuffer) { + outBuffer.writeShort(getType()); + outBuffer.writeShort(InstructionConstants.WRITE_METADATA_LENGTH); + outBuffer.writeZero(InstructionConstants.PADDING_IN_WRITE_METADATA); + WriteMetadata metadata = ((WriteMetadataCase) instruction.getInstructionChoice()) + .getWriteMetadata(); + outBuffer.writeBytes(metadata.getMetadata()); + outBuffer.writeBytes(metadata.getMetadataMask()); + } + + @Override + protected int getType() { + return InstructionConstants.WRITE_METADATA_TYPE; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java new file mode 100644 index 0000000000..77e7651c82 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv4AddressSerializer.java @@ -0,0 +1,35 @@ +/* + * 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.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 + * @author michal.polkorab + */ +public abstract class AbstractOxmIpv4AddressSerializer extends AbstractOxmMatchEntrySerializer { + + /** + * @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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv6AddressSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv6AddressSerializer.java new file mode 100644 index 0000000000..c96465852a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmIpv6AddressSerializer.java @@ -0,0 +1,28 @@ +/* + * 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.serialization.match; + +import com.google.common.net.InetAddresses; +import io.netty.buffer.ByteBuf; + +/** + * Parent for Ipv6 address based match entry serializers + * @author michal.polkorab + */ +public abstract class AbstractOxmIpv6AddressSerializer extends AbstractOxmMatchEntrySerializer { + + protected void writeIpv6Address(final String textAddress, final ByteBuf outBuffer) { + if (InetAddresses.isInetAddress(textAddress)) { + byte[] binaryAddress = InetAddresses.forString(textAddress).getAddress(); + outBuffer.writeBytes(binaryAddress); + } else { + throw new IllegalArgumentException("Invalid ipv6 address received: " + textAddress); + } + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java new file mode 100644 index 0000000000..9dde0f0c53 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMacAddressSerializer.java @@ -0,0 +1,23 @@ +/* + * 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.serialization.match; + +import io.netty.buffer.ByteBuf; +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 + * @author michal.polkorab + */ +public abstract class AbstractOxmMacAddressSerializer extends AbstractOxmMatchEntrySerializer { + + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMatchEntrySerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMatchEntrySerializer.java new file mode 100644 index 0000000000..d2b96e2073 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/AbstractOxmMatchEntrySerializer.java @@ -0,0 +1,69 @@ +/* + * 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.serialization.match; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * Parent for all match entry serializers + * @author michal.polkorab + */ +public abstract class AbstractOxmMatchEntrySerializer + implements OFSerializer, HeaderSerializer{ + + @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 writeMask(byte[] mask, ByteBuf out, int length) { + if (mask != null && mask.length != length) { + throw new IllegalArgumentException("incorrect length of mask: "+ + mask.length + ", expected: " + length); + } + out.writeBytes(mask); + } + + 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; + } + out.writeByte(fieldAndMask); + out.writeByte(length); + } + + /** + * @return numeric representation of oxm_field + */ + protected abstract int getOxmFieldCode(); + + /** + * @return numeric representation of oxm_class + */ + protected abstract int getOxmClassCode(); + + /** + * @return match entry value length (without mask length) + */ + protected abstract int getValueLength(); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializer.java new file mode 100644 index 0000000000..c9ca79678a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpOpCase; + +/** + * @author michal.polkorab + * + */ +public class OxmArpOpSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ArpOpCase entryValue = (ArpOpCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getArpOp().getOpCode()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ARP_OP; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializer.java new file mode 100644 index 0000000000..13903be36f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpShaCase; + +/** + * @author michal.polkorab + * + */ +public class OxmArpShaSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ArpShaCase entryValue = (ArpShaCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getArpSha().getMacAddress(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getArpSha().getMask(), outBuffer, EncodeConstants.MAC_ADDRESS_LENGTH); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ARP_SHA; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java new file mode 100644 index 0000000000..99ed4c9cdf --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpSpaCase; + +/** + * @author michal.polkorab + * + */ +public class OxmArpSpaSerializer extends AbstractOxmIpv4AddressSerializer { + + @Override + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ArpSpaCase entryValue = (ArpSpaCase) entry.getMatchEntryValue(); + writeIpv4Address(entryValue.getArpSpa().getIpv4Address(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getArpSpa().getMask(), outBuffer, + EncodeConstants.GROUPS_IN_IPV4_ADDRESS); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ARP_SPA; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializer.java new file mode 100644 index 0000000000..8ed15f759b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpThaCase; + +/** + * @author michal.polkorab + * + */ +public class OxmArpThaSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ArpThaCase entryValue = (ArpThaCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getArpTha().getMacAddress(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getArpTha().getMask(), outBuffer, EncodeConstants.MAC_ADDRESS_LENGTH); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ARP_THA; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java new file mode 100644 index 0000000000..29e24cab33 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpTpaCase; + +/** + * @author michal.polkorab + * + */ +public class OxmArpTpaSerializer extends AbstractOxmIpv4AddressSerializer { + + @Override + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + ArpTpaCase entryValue = (ArpTpaCase) entry.getMatchEntryValue(); + writeIpv4Address(entryValue.getArpTpa().getIpv4Address(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getArpTpa().getMask(), outBuffer, + EncodeConstants.GROUPS_IN_IPV4_ADDRESS); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ARP_TPA; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializer.java new file mode 100644 index 0000000000..c34299f5a8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmEthDstSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + EthDstCase entryValue = (EthDstCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getEthDst().getMacAddress(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getEthDst().getMask(), outBuffer, EncodeConstants.MAC_ADDRESS_LENGTH); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ETH_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializer.java new file mode 100644 index 0000000000..5efe5b29be --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmEthSrcSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + EthSrcCase entryValue = (EthSrcCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getEthSrc().getMacAddress(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getEthSrc().getMask(), outBuffer, EncodeConstants.MAC_ADDRESS_LENGTH); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ETH_SRC; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializer.java new file mode 100644 index 0000000000..58ee45030f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCase; + +/** + * @author michal.polkorab + * + */ +public class OxmEthTypeSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + EthTypeCase entryValue = (EthTypeCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getEthType().getEthType().getValue().shortValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ETH_TYPE; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializer.java new file mode 100644 index 0000000000..ad80424c41 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4CodeCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4CodeSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Icmpv4CodeCase entryValue = (Icmpv4CodeCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIcmpv4Code().getIcmpv4Code()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ICMPV4_CODE; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializer.java new file mode 100644 index 0000000000..4619070933 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4TypeCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4TypeSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Icmpv4TypeCase entryValue = (Icmpv4TypeCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIcmpv4Type().getIcmpv4Type()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ICMPV4_TYPE; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializer.java new file mode 100644 index 0000000000..6b5daf81e9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6CodeCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6CodeSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Icmpv6CodeCase entryValue = (Icmpv6CodeCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIcmpv6Code().getIcmpv6Code()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ICMPV6_CODE; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializer.java new file mode 100644 index 0000000000..abf5227ad8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6TypeCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6TypeSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Icmpv6TypeCase entryValue = (Icmpv6TypeCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIcmpv6Type().getIcmpv6Type()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.ICMPV6_TYPE; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPhyPortSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPhyPortSerializer.java new file mode 100644 index 0000000000..cc22a34126 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPhyPortSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCase; + +/** + * @author michal.polkorab + * + */ +public class OxmInPhyPortSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + InPhyPortCase entryValue = (InPhyPortCase) entry.getMatchEntryValue(); + outBuffer.writeInt(entryValue.getInPhyPort().getPortNumber().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IN_PHY_PORT; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPortSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPortSerializer.java new file mode 100644 index 0000000000..4fbae264d8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmInPortSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCase; + +/** + * @author michal.polkorab + * + */ +public class OxmInPortSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + InPortCase entryValue = (InPortCase) entry.getMatchEntryValue(); + outBuffer.writeInt(entryValue.getInPort().getPortNumber().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IN_PORT; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializer.java new file mode 100644 index 0000000000..f06cd69046 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpDscpCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpDscpSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + IpDscpCase entryValue = (IpDscpCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIpDscp().getDscp().getValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IP_DSCP; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpEcnSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpEcnSerializer.java new file mode 100644 index 0000000000..2edd06ac2d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpEcnSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpEcnSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + IpEcnCase entryValue = (IpEcnCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIpEcn().getEcn()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IP_ECN; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializer.java new file mode 100644 index 0000000000..a9b4871b14 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpProtoCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpProtoSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + IpProtoCase entryValue = (IpProtoCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getIpProto().getProtocolNumber()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IP_PROTO; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java new file mode 100644 index 0000000000..9e1c00b0cc --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4DstSerializer extends AbstractOxmIpv4AddressSerializer { + + @Override + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv4DstCase entryValue = (Ipv4DstCase) entry.getMatchEntryValue(); + writeIpv4Address(entryValue.getIpv4Dst().getIpv4Address(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getIpv4Dst().getMask(), outBuffer, + EncodeConstants.GROUPS_IN_IPV4_ADDRESS); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV4_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java new file mode 100644 index 0000000000..42667ee063 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4SrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4SrcSerializer extends AbstractOxmIpv4AddressSerializer { + + @Override + public void serialize(final MatchEntry entry, final ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv4SrcCase entryValue = (Ipv4SrcCase) entry.getMatchEntryValue(); + writeIpv4Address(entryValue.getIpv4Src().getIpv4Address(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getIpv4Src().getMask(), outBuffer, + EncodeConstants.GROUPS_IN_IPV4_ADDRESS); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV4_SRC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6DstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6DstSerializer.java new file mode 100644 index 0000000000..0e749610eb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6DstSerializer.java @@ -0,0 +1,48 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6DstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6DstSerializer extends AbstractOxmIpv6AddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6DstCase entryValue = (Ipv6DstCase) entry.getMatchEntryValue(); + writeIpv6Address(entryValue.getIpv6Dst().getIpv6Address().getValue(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getIpv6Dst().getMask(), outBuffer, + EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializer.java new file mode 100644 index 0000000000..d60c392d15 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializer.java @@ -0,0 +1,60 @@ +/* + * 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.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.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; +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.entry.value.grouping.match.entry.value.Ipv6ExthdrCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6ExtHdrSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6ExthdrCase entryValue = (Ipv6ExthdrCase) entry.getMatchEntryValue(); + Ipv6ExthdrFlags pseudoField = entryValue.getIpv6Exthdr().getPseudoField(); + int bitmap = ByteBufUtils.fillBitMask(0, + pseudoField.isNonext(), + pseudoField.isEsp(), + pseudoField.isAuth(), + pseudoField.isDest(), + pseudoField.isFrag(), + pseudoField.isRouter(), + pseudoField.isHop(), + pseudoField.isUnrep(), + pseudoField.isUnseq()); + outBuffer.writeShort(bitmap); + if (entry.isHasMask()) { + outBuffer.writeBytes(entryValue.getIpv6Exthdr().getMask()); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_EXTHDR; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6FlabelSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6FlabelSerializer.java new file mode 100644 index 0000000000..4f86b25260 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6FlabelSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6FlabelCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6FlabelSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6FlabelCase entryValue = (Ipv6FlabelCase) entry.getMatchEntryValue(); + outBuffer.writeInt(entryValue.getIpv6Flabel().getIpv6Flabel().getValue().intValue()); + if (entry.isHasMask()) { + writeMask(entryValue.getIpv6Flabel().getMask(), outBuffer, EncodeConstants.SIZE_OF_INT_IN_BYTES); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_FLABEL; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializer.java new file mode 100644 index 0000000000..3144150375 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdSllCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdSllSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6NdSllCase entryValue = (Ipv6NdSllCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getIpv6NdSll().getMacAddress(), outBuffer); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_ND_SLL; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTargetSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTargetSerializer.java new file mode 100644 index 0000000000..cb5bd7cae0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTargetSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTargetCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdTargetSerializer extends AbstractOxmIpv6AddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6NdTargetCase entryValue = (Ipv6NdTargetCase) entry.getMatchEntryValue(); + writeIpv6Address(entryValue.getIpv6NdTarget().getIpv6Address().getValue(), outBuffer); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_ND_TARGET; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializer.java new file mode 100644 index 0000000000..3e5a17ad25 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTllCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdTllSerializer extends AbstractOxmMacAddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6NdTllCase entryValue = (Ipv6NdTllCase) entry.getMatchEntryValue(); + writeMacAddress(entryValue.getIpv6NdTll().getMacAddress(), outBuffer); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_ND_TLL; + } + + @Override + protected int getValueLength() { + return EncodeConstants.MAC_ADDRESS_LENGTH; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializer.java new file mode 100644 index 0000000000..4072b76767 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializer.java @@ -0,0 +1,48 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6SrcSerializer extends AbstractOxmIpv6AddressSerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + Ipv6SrcCase entryValue = (Ipv6SrcCase) entry.getMatchEntryValue(); + writeIpv6Address(entryValue.getIpv6Src().getIpv6Address().getValue(), outBuffer); + if (entry.isHasMask()) { + writeMask(entryValue.getIpv6Src().getMask(), outBuffer, + EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.IPV6_SRC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializer.java new file mode 100644 index 0000000000..1927e4c84b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializer.java @@ -0,0 +1,48 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MetadataCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMetadataSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + MetadataCase entryValue = (MetadataCase) entry.getMatchEntryValue(); + outBuffer.writeBytes(entryValue.getMetadata().getMetadata()); + if (entry.isHasMask()) { + writeMask(entryValue.getMetadata().getMask(), outBuffer, + EncodeConstants.SIZE_OF_LONG_IN_BYTES); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.METADATA; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_LONG_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializer.java new file mode 100644 index 0000000000..6e4e334802 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsBosCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsBosSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + MplsBosCase entryValue = (MplsBosCase) entry.getMatchEntryValue(); + outBuffer.writeBoolean(entryValue.getMplsBos().isBos().booleanValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.MPLS_BOS; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializer.java new file mode 100644 index 0000000000..a22e20893d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsLabelCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsLabelSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + MplsLabelCase entryValue = (MplsLabelCase) entry.getMatchEntryValue(); + outBuffer.writeInt(entryValue.getMplsLabel().getMplsLabel().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.MPLS_LABEL; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_INT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializer.java new file mode 100644 index 0000000000..5abc5b022b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsTcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsTcSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + MplsTcCase entryValue = (MplsTcCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getMplsTc().getTc()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.MPLS_TC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializer.java new file mode 100644 index 0000000000..dba3e87e8c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializer.java @@ -0,0 +1,47 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.PbbIsidCase; + +/** + * @author michal.polkorab + * + */ +public class OxmPbbIsidSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + PbbIsidCase entryValue = (PbbIsidCase) entry.getMatchEntryValue(); + outBuffer.writeMedium(entryValue.getPbbIsid().getIsid().intValue()); + if (entry.isHasMask()) { + writeMask(entryValue.getPbbIsid().getMask(), outBuffer, getValueLength()); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.PBB_ISID; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_3_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializer.java new file mode 100644 index 0000000000..fe66a7d872 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpDstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpDstSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + SctpDstCase entryValue = (SctpDstCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getSctpDst().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.SCTP_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializer.java new file mode 100644 index 0000000000..eea241171d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpSrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpSrcSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + SctpSrcCase entryValue = (SctpSrcCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getSctpSrc().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.SCTP_SRC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializer.java new file mode 100644 index 0000000000..2e91d37890 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpDstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpDstSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + TcpDstCase entryValue = (TcpDstCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getTcpDst().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.TCP_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializer.java new file mode 100644 index 0000000000..6d761a1c0e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpSrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpSrcSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + TcpSrcCase entryValue = (TcpSrcCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getTcpSrc().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.TCP_SRC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializer.java new file mode 100644 index 0000000000..aea8545a6b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializer.java @@ -0,0 +1,48 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TunnelIdCase; + +/** + * @author michal.polkorab + * + */ +public class OxmTunnelIdSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + TunnelIdCase entryValue = (TunnelIdCase) entry.getMatchEntryValue(); + outBuffer.writeBytes(entryValue.getTunnelId().getTunnelId()); + if (entry.isHasMask()) { + writeMask(entryValue.getTunnelId().getMask(), outBuffer, + EncodeConstants.SIZE_OF_LONG_IN_BYTES); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.TUNNEL_ID; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_LONG_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializer.java new file mode 100644 index 0000000000..110dede992 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializer.java @@ -0,0 +1,44 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpDstCase; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpDstSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + UdpDstCase entryValue = (UdpDstCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getUdpDst().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.UDP_DST; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializer.java new file mode 100644 index 0000000000..a1db321d6d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializer.java @@ -0,0 +1,45 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCase; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpSrcSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + UdpSrcCase entryValue = (UdpSrcCase) entry.getMatchEntryValue(); + outBuffer.writeShort(entryValue.getUdpSrc().getPort().getValue().intValue()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.UDP_SRC; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializer.java new file mode 100644 index 0000000000..a344e99738 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializer.java @@ -0,0 +1,45 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanPcpCase; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanPcpSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + VlanPcpCase entryValue = (VlanPcpCase) entry.getMatchEntryValue(); + outBuffer.writeByte(entryValue.getVlanPcp().getVlanPcp()); + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.VLAN_PCP; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_BYTE_IN_BYTES; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializer.java new file mode 100644 index 0000000000..0a76f89584 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializer.java @@ -0,0 +1,54 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVid; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanVidSerializer extends AbstractOxmMatchEntrySerializer { + + @Override + public void serialize(MatchEntry entry, ByteBuf outBuffer) { + super.serialize(entry, outBuffer); + VlanVid vlanVid = ((VlanVidCase) entry.getMatchEntryValue()).getVlanVid(); + int vlanVidValue = vlanVid.getVlanVid(); + if (vlanVid.isCfiBit()) { + short cfi = 1 << 12; // 13-th bit + vlanVidValue = vlanVidValue | cfi; + } + outBuffer.writeShort(vlanVidValue); + if (entry.isHasMask()) { + writeMask(vlanVid.getMask(), outBuffer, getValueLength()); + } + } + + @Override + protected int getOxmClassCode() { + return OxmMatchConstants.OPENFLOW_BASIC_CLASS; + } + + @Override + protected int getOxmFieldCode() { + return OxmMatchConstants.VLAN_VID; + } + + @Override + protected int getValueLength() { + return EncodeConstants.SIZE_OF_SHORT_IN_BYTES; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java new file mode 100644 index 0000000000..4d82ad8541 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/AbstractOxmExperimenterMatchEntrySerializer.java @@ -0,0 +1,58 @@ +/* + * 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/ext/OnfOxmTcpFlagsSerializer.java new file mode 100644 index 0000000000..f244cc42ff --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractCodeKeyMaker.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractCodeKeyMaker.java new file mode 100644 index 0000000000..7aff0aa7be --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractCodeKeyMaker.java @@ -0,0 +1,32 @@ +/* + * 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.util; + +/** + * @author michal.polkorab + */ +public abstract class AbstractCodeKeyMaker implements CodeKeyMaker { + + private short version; + + /** + * @param version openflow wire version + */ + public AbstractCodeKeyMaker(short version) { + this.version = version; + + } + + /** + * @return the version + */ + public short getVersion() { + return version; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractTypeKeyMaker.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractTypeKeyMaker.java new file mode 100644 index 0000000000..70c7a1551b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/AbstractTypeKeyMaker.java @@ -0,0 +1,35 @@ +/* + * 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.util; + + +/** + * @author michal.polkorab + * @param type the key maker is based on + */ +public abstract class AbstractTypeKeyMaker implements TypeKeyMaker { + + private short version; + + /** + * @param version openflow wire version + */ + public AbstractTypeKeyMaker(short version) { + this.version = version; + + } + + /** + * @return the version + */ + public short getVersion() { + return version; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionConstants.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionConstants.java new file mode 100644 index 0000000000..4179178081 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionConstants.java @@ -0,0 +1,107 @@ +/* + * 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.util; + +/** + * @author michal.polkorab + * + */ +public final class ActionConstants { + + /** Openflow v1.0 and v1.3 OFPAT_OUTPUT code */ + public static final byte OUTPUT_CODE = 0; + /** Openflow v1.0 OFPAT_SET_VLAN_VID code */ + public static final byte SET_VLAN_VID_CODE = 1; + /** Openflow v1.0 OFPAT_SET_VLAN_PCP code */ + public static final byte SET_VLAN_PCP_CODE = 2; + /** Openflow v1.0 OFPAT_STRIP_VLAN code */ + public static final byte STRIP_VLAN_CODE = 3; + /** Openflow v1.0 OFPAT_SET_DL_SRC code */ + public static final byte SET_DL_SRC_CODE = 4; + /** Openflow v1.0 OFPAT_SET_DL_DST code */ + public static final byte SET_DL_DST_CODE = 5; + /** Openflow v1.0 OFPAT_SET_NW_SRC code */ + public static final byte SET_NW_SRC_CODE = 6; + /** Openflow v1.0 OFPAT_SET_NW_DST code */ + public static final byte SET_NW_DST_CODE = 7; + /** Openflow v1.0 OFPAT_SET_NW_TOS code */ + public static final byte SET_NW_TOS_CODE = 8; + /** Openflow v1.0 OFPAT_SET_TP_SRC code */ + public static final byte SET_TP_SRC_CODE = 9; + /** Openflow v1.0 OFPAT_SET_TP_DST code */ + public static final byte SET_TP_DST_CODE = 10; + /** Openflow v1.0 OFPAT_ENQUEUE code */ + public static final byte ENQUEUE_CODE = 11; + /** Openflow v1.3 OFPAT_COPY_TTL_OUT code */ + public static final byte COPY_TTL_OUT_CODE = 11; + /** Openflow v1.3 OFPAT_COPY_TTL_IN code */ + public static final byte COPY_TTL_IN_CODE = 12; + /** Openflow v1.3 OFPAT_SET_MPLS_TTL code */ + public static final byte SET_MPLS_TTL_CODE = 15; + /** Openflow v1.3 OFPAT_DEC_MPLS_TTL code */ + public static final byte DEC_MPLS_TTL_CODE = 16; + /** Openflow v1.3 OFPAT_PUSH_VLAN code */ + public static final byte PUSH_VLAN_CODE = 17; + /** Openflow v1.3 OFPAT_POP_VLAN code */ + public static final byte POP_VLAN_CODE = 18; + /** Openflow v1.3 OFPAT_PUSH_MPLS code */ + public static final byte PUSH_MPLS_CODE = 19; + /** Openflow v1.3 OFPAT_POP_MPLS code */ + public static final byte POP_MPLS_CODE = 20; + /** Openflow v1.3 OFPAT_SET_QUEUE code */ + public static final byte SET_QUEUE_CODE = 21; + /** Openflow v1.3 OFPAT_GROUP code */ + public static final byte GROUP_CODE = 22; + /** Openflow v1.3 OFPAT_SET_NW_TTL code */ + public static final byte SET_NW_TTL_CODE = 23; + /** Openflow v1.3 OFPAT_DEC_NW_TTL code */ + public static final byte DEC_NW_TTL_CODE = 24; + /** Openflow v1.3 OFPAT_SET_FIELD code */ + public static final int SET_FIELD_CODE = 25; + /** Openflow v1.3 OFPAT_PUSH_PBB code */ + public static final byte PUSH_PBB_CODE = 26; + /** Openflow v1.3 OFPAT_POP_PBB code */ + public static final byte POP_PBB_CODE = 27; + + /** Padding in OFPAT_OUTPUT (OF v1.3) */ + public static final byte OUTPUT_PADDING = 6; + /** Padding in OFPAT_SET_VLAN_VID (OF v1.3) */ + public static final byte PADDING_IN_SET_VLAN_VID_ACTION = 2; + /** Padding in OFPAT_SET_VLAN_PCP (OF v1.3) */ + public static final byte PADDING_IN_SET_VLAN_PCP_ACTION = 3; + /** Padding in OFPAT_SET_NW_TOS (OF v1.3) */ + public static final byte PADDING_IN_SET_NW_TOS_ACTION = 3; + /** Padding in OFPAT_ENQUEUE (OF v1.3) */ + public static final int PADDING_IN_ENQUEUE_ACTION = 6; + /** Padding in OFPAT_SET_MPLS_TTL (OF v1.3) */ + public static final byte SET_MPLS_TTL_PADDING = 3; + /** Padding in OFPAT_SET_NW_TTL (OF v1.3) */ + public static final byte SET_NW_TTL_PADDING = 3; + /** Padding in OFPAT_SET_DL_SRC and OFPAT_SET_DL_DST (OF v1.3) */ + public static final byte PADDING_IN_DL_ADDRESS_ACTION = 6; + /** Padding in OFPAT_SET_TP_SRC and OFPAT_SET_TP_DST (OF v1.3) */ + public static final byte PADDING_IN_TP_PORT_ACTION = 2; + /** Padding in action header (OF v1.3) */ + public static final byte PADDING_IN_ACTION_HEADER = 4; + /** Padding in OFPAT_PUSH_VLAN, OFPAT_PUSH_MPLS, OFPAT_POP_MPLS + * and OFPAT_PUSH_PBB (OF v1.3) */ + public static final byte ETHERTYPE_ACTION_PADDING = 2; + + /** Most common action length */ + public static final byte GENERAL_ACTION_LENGTH = 8; + /** Action larger than GENERAL_ACTION_LENGTH - currently + * only 16 bytes long actions for both OF v1.0 and v1.3*/ + public static final byte LARGER_ACTION_LENGTH = 16; + /** Action header size */ + public static final byte ACTION_IDS_LENGTH = 4; + + private ActionConstants() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionDeserializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionDeserializerRegistryHelper.java new file mode 100644 index 0000000000..49c1b6fc14 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionDeserializerRegistryHelper.java @@ -0,0 +1,40 @@ +/* + * 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.impl.util; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; +import org.opendaylight.openflowjava.protocol.api.keys.ActionDeserializerKey; + +/** + * @author michal.polkorab + * + */ +public class ActionDeserializerRegistryHelper { + + private short version; + private DeserializerRegistry registry; + + /** + * @param version wire protocol version + * @param deserializerRegistry registry to be filled with message deserializers + */ + public ActionDeserializerRegistryHelper(short version, DeserializerRegistry deserializerRegistry) { + this.version = version; + this.registry = deserializerRegistry; + } + + /** + * @param code code / value to distinguish between deserializers + * @param deserializer deserializer instance + */ + public void registerDeserializer(int code, OFGeneralDeserializer deserializer) { + registry.registerDeserializer(new ActionDeserializerKey(version, code, + null), deserializer); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionSerializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionSerializerRegistryHelper.java new file mode 100644 index 0000000000..b622dd17ed --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ActionSerializerRegistryHelper.java @@ -0,0 +1,42 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.ActionChoice; + +/** + * @author michal.polkorab + */ +public class ActionSerializerRegistryHelper { + + private short version; + private SerializerRegistry serializerRegistry; + + /** + * @param version Openflow wire version + * @param serializerRegistry + */ + public ActionSerializerRegistryHelper(short version, SerializerRegistry serializerRegistry) { + this.version = version; + this.serializerRegistry = serializerRegistry; + } + + /** + * Registers given serializer + * @param actionType + * @param serializer + */ + public void registerSerializer(Class actionType, + OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(new ActionSerializerKey<>(version, + actionType, null), serializer); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMaker.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMaker.java new file mode 100644 index 0000000000..865db78035 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMaker.java @@ -0,0 +1,26 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; + +import io.netty.buffer.ByteBuf; + +/** + * @author michal.polkorab + */ +public interface CodeKeyMaker { + + /** + * @param input buffer that will be the needed data gathered from + * @return key for deserializer lookup + */ + abstract MessageCodeKey make(ByteBuf input); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactory.java new file mode 100644 index 0000000000..ba692c8f81 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactory.java @@ -0,0 +1,93 @@ +/* + * 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.util; + +import io.netty.buffer.ByteBuf; + +import org.opendaylight.openflowjava.protocol.api.keys.ActionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterInstructionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public abstract class CodeKeyMakerFactory { + + private CodeKeyMakerFactory() { + //not called + } + /** + * @param version + * @return + */ + public static CodeKeyMaker createMatchEntriesKeyMaker(short version) { + return new AbstractCodeKeyMaker(version) { + @Override + public MessageCodeKey make(ByteBuf input) { + int oxmClass = input.getUnsignedShort(input.readerIndex()); + int oxmField = input.getUnsignedByte(input.readerIndex() + + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1; + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(getVersion(), + oxmClass, oxmField); + if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) { + long expId = input.getUnsignedInt(input.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES + + 2 * EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + key.setExperimenterId(expId); + return key; + } + key.setExperimenterId(null); + return key; + } + }; + } + + /** + * @param version + * @return + */ + public static CodeKeyMaker createActionsKeyMaker(short version) { + return new AbstractCodeKeyMaker(version) { + @Override + public MessageCodeKey make(ByteBuf input) { + int type = input.getUnsignedShort(input.readerIndex()); + if (type == EncodeConstants.EXPERIMENTER_VALUE) { + Long expId = input.getUnsignedInt(input.readerIndex() + + 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + return new ExperimenterActionDeserializerKey(getVersion(), expId); + } + ActionDeserializerKey actionDeserializerKey = new ActionDeserializerKey(getVersion(), type, null); + return actionDeserializerKey; + } + }; + } + + /** + * @param version + * @return + */ + public static CodeKeyMaker createInstructionsKeyMaker(short version) { + return new AbstractCodeKeyMaker(version) { + @Override + public MessageCodeKey make(ByteBuf input) { + int type = input.getUnsignedShort(input.readerIndex()); + if (type == EncodeConstants.EXPERIMENTER_VALUE) { + Long expId = input.getUnsignedInt(input.readerIndex() + + 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + return new ExperimenterInstructionDeserializerKey(getVersion(), expId); + } + return new InstructionDeserializerKey(getVersion(), type, null); + } + }; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java new file mode 100644 index 0000000000..15bc5971f8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/CommonMessageRegistryHelper.java @@ -0,0 +1,42 @@ +/* + * 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.util; + +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 { + + private short version; + private SerializerRegistry serializerRegistry; + + /** + * @param version wire protocol version + * @param serializerRegistry registry to be filled with message serializers + */ + public CommonMessageRegistryHelper(short version, SerializerRegistry serializerRegistry) { + this.version = version; + this.serializerRegistry = serializerRegistry; + } + + /** + * 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionConstants.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionConstants.java new file mode 100644 index 0000000000..7d9479a121 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionConstants.java @@ -0,0 +1,48 @@ +/* + * 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.util; + +/** + * @author michal.polkorab + * + */ +public final class InstructionConstants { + + /** Openflow v1.3 OFPIT_GOTO_TABLE code */ + public static final byte GOTO_TABLE_TYPE = 1; + /** Openflow v1.3 OFPIT_WRITE_METADATA code */ + public static final byte WRITE_METADATA_TYPE = 2; + /** Openflow v1.3 OFPIT_WRITE_ACTIONS code */ + public static final byte WRITE_ACTIONS_TYPE = 3; + /** Openflow v1.3 OFPIT_APPLY_ACTIONS code */ + public static final byte APPLY_ACTIONS_TYPE = 4; + /** Openflow v1.3 OFPIT_CLEAR_ACTIONS code */ + public static final byte CLEAR_ACTIONS_TYPE = 5; + /** Openflow v1.3 OFPIT_METER code */ + public static final byte METER_TYPE = 6; + + /** PADDING in OFPIT_GOTO_TABLE */ + public static final byte PADDING_IN_GOTO_TABLE = 3; + /** PADDING in OFPIT_WRITE_METADATA */ + public static final byte PADDING_IN_WRITE_METADATA = 4; + /** PADDING in OFPIT_WRITE_ACTIONS, OFPIT_APPLY_ACTIONS + * and OFPIT_CLEAR_ACTIONS */ + public static final byte PADDING_IN_ACTIONS_INSTRUCTION = 4; + + /** Openflow v1.3 header length (padded) */ + public static final byte STANDARD_INSTRUCTION_LENGTH = 8; + /** Openflow v1.3 OFPIT_WRITE_METADATA length */ + public static final byte WRITE_METADATA_LENGTH = 24; + /** Openflow v1.3 header length (only type and length fields) */ + public static final byte INSTRUCTION_IDS_LENGTH = 4; + + private InstructionConstants() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionDeserializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionDeserializerRegistryHelper.java new file mode 100644 index 0000000000..19149e109c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionDeserializerRegistryHelper.java @@ -0,0 +1,40 @@ +/* + * 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.impl.util; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionDeserializerKey; + +/** + * @author michal.polkorab + * + */ +public class InstructionDeserializerRegistryHelper { + + private short version; + private DeserializerRegistry registry; + + /** + * @param version wire protocol version + * @param deserializerRegistry registry to be filled with message deserializers + */ + public InstructionDeserializerRegistryHelper(short version, DeserializerRegistry deserializerRegistry) { + this.version = version; + this.registry = deserializerRegistry; + } + + /** + * @param code code / value to distinguish between deserializers + * @param deserializer deserializer instance + */ + public void registerDeserializer(int code, OFGeneralDeserializer deserializer) { + registry.registerDeserializer(new InstructionDeserializerKey(version, code, + null), deserializer); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionSerializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionSerializerRegistryHelper.java new file mode 100644 index 0000000000..78a361803b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionSerializerRegistryHelper.java @@ -0,0 +1,42 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionSerializerKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.InstructionChoice; + +/** + * @author michal.polkorab + */ +public class InstructionSerializerRegistryHelper { + + private short version; + private SerializerRegistry serializerRegistry; + + /** + * @param version Openflow wire version + * @param serializerRegistry + */ + public InstructionSerializerRegistryHelper(short version, SerializerRegistry serializerRegistry) { + this.version = version; + this.serializerRegistry = serializerRegistry; + } + + /** + * Registers given serializer + * @param instructionType + * @param serializer + */ + public void registerSerializer(Class instructionType, + OFGeneralSerializer serializer) { + serializerRegistry.registerSerializer(new InstructionSerializerKey<>(version, + instructionType, null), serializer); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java new file mode 100644 index 0000000000..44534720c7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializer.java @@ -0,0 +1,106 @@ +/* + * 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.util; + +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.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"); + } + + /** + * Deserializes items into list + * @param version openflow wire version + * @param length length of list in ByteBuf (bytes) + * @param input input buffer + * @param keyMaker creates keys for deserializer lookup + * @param registry stores deserializers + * @return list of items + */ + public static List deserializeList(short version, int length, + ByteBuf input, CodeKeyMaker keyMaker, DeserializerRegistry registry) { + List items = null; + if (input.readableBytes() > 0) { + items = new ArrayList<>(); + int startIndex = input.readerIndex(); + while ((input.readerIndex() - startIndex) < length){ + OFDeserializer deserializer = registry.getDeserializer(keyMaker.make(input)); + E item = deserializer.deserialize(input); + items.add(item); + } + } + return items; + } + + /** + * 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 + * @param keyMaker creates keys for deserializer lookup + * @param registry stores deserializers + * @return list of items + */ + public static List deserializeHeaders(short version, int length, + ByteBuf input, CodeKeyMaker keyMaker, DeserializerRegistry registry) { + List items = null; + if (input.readableBytes() > 0) { + items = new ArrayList<>(); + int startIndex = input.readerIndex(); + boolean exceptionLogged = false; + while ((input.readerIndex() - startIndex) < length){ + HeaderDeserializer deserializer; + MessageCodeKey key = keyMaker.make(input); + try { + deserializer = registry.getDeserializer(key); + } catch (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); + } + } + return items; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializer.java new file mode 100644 index 0000000000..7392be7612 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializer.java @@ -0,0 +1,64 @@ +/* + * 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.util; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +import org.opendaylight.openflowjava.protocol.api.extensibility.HeaderSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Serializes list items and their headers + * @author michal.polkorab + */ +public abstract class ListSerializer { + + private ListSerializer() { + //not called + } + + /** + * Serializes item list + * @param list list of items to be serialized + * @param keyMaker creates key for registry lookup + * @param registry stores serializers + * @param outBuffer output buffer + */ + public static void serializeList(List list, + TypeKeyMaker keyMaker, SerializerRegistry registry, ByteBuf outBuffer) { + if (list != null) { + for (E item : list) { + OFSerializer serializer = registry.getSerializer(keyMaker.make(item)); + serializer.serialize(item, outBuffer); + } + } + } + + /** + * Serializes headers of items in list + * @param list list of items to be serialized + * @param keyMaker creates key for registry lookup + * @param registry stores serializers + * @param outBuffer output buffer + */ + public static void serializeHeaderList(List list, + TypeKeyMaker keyMaker, SerializerRegistry registry, ByteBuf outBuffer) { + if (list != null) { + for (E item : list) { + HeaderSerializer serializer = registry.getSerializer(keyMaker.make(item)); + serializer.serializeHeader(item, outBuffer); + } + } + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java new file mode 100644 index 0000000000..0a6852defe --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializer.java @@ -0,0 +1,69 @@ +/* + * 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.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.DeserializerRegistryInjector; +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.StandardMatchType; +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.grouping.Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder; + +/** + * Deserializes ofp_match (OpenFlow v1.3) and its oxm_fields structures + * @author timotej.kubas + * @author michal.polkorab + */ +public class MatchDeserializer implements OFDeserializer, + DeserializerRegistryInjector { + + private DeserializerRegistry registry; + + @Override + public Match deserialize(ByteBuf input) { + if (input.readableBytes() > 0) { + MatchBuilder builder = new MatchBuilder(); + int type = input.readUnsignedShort(); + int length = input.readUnsignedShort(); + switch (type) { + case 0: + builder.setType(StandardMatchType.class); + break; + case 1: + builder.setType(OxmMatchType.class); + break; + default: + break; + } + CodeKeyMaker keyMaker = CodeKeyMakerFactory + .createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + List entries = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + length - 2 * EncodeConstants.SIZE_OF_SHORT_IN_BYTES, input, keyMaker, registry); + builder.setMatchEntry(entries); + int paddingRemainder = length % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + input.skipBytes(EncodeConstants.PADDING - paddingRemainder); + } + return builder.build(); + } + return null; + } + + @Override + public void injectDeserializerRegistry(DeserializerRegistry deserializerRegistry) { + this.registry = deserializerRegistry; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java new file mode 100644 index 0000000000..96d01c3dc8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntryDeserializerRegistryHelper.java @@ -0,0 +1,55 @@ +/* + * 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.util; + +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 + * + */ +public class MatchEntryDeserializerRegistryHelper { + + private short version; + private DeserializerRegistry registry; + private int oxmClass; + + /** + * @param version wire protocol version + * @param oxmClass oxm_class that will be used for match entry deserializer + * registration + * @param deserializerRegistry registry to be filled with message deserializers + */ + public MatchEntryDeserializerRegistryHelper(short version, int oxmClass, + DeserializerRegistry deserializerRegistry) { + this.version = version; + this.oxmClass = oxmClass; + this.registry = deserializerRegistry; + } + + /** + * Registers match entry deserializer under provided oxmfield () + * @param oxmField oxm_field value/code + * @param deserializer deserializer instance + */ + public void register(int oxmField, OFGeneralDeserializer deserializer) { + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(version, oxmClass, oxmField); + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java new file mode 100644 index 0000000000..d9c76295e7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/MatchEntrySerializerRegistryHelper.java @@ -0,0 +1,63 @@ +/* + * 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.util; + +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; + +/** + * @author michal.polkorab + * @param OXM class + */ +public class MatchEntrySerializerRegistryHelper { + + private short version; + private Class generalClass; + private SerializerRegistry serializerRegistry; + + /** + * @param version Openflow wire version + * @param generalClass + * @param serializerRegistry + */ + public MatchEntrySerializerRegistryHelper(short version, Class generalClass, + SerializerRegistry serializerRegistry) { + this.version = version; + this.generalClass = generalClass; + this.serializerRegistry = serializerRegistry; + } + + /** + * Registers given serializer + * @param specificClass + * @param serializer + */ + public void registerSerializer( + Class specificClass, OFGeneralSerializer serializer) { + MatchEntrySerializerKey key = new MatchEntrySerializerKey<>(version, generalClass, specificClass); + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java new file mode 100644 index 0000000000..7ff074ae7f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializer.java @@ -0,0 +1,95 @@ +/* + * 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.util; + +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.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; + +/** + * Deserializes ofp_match (OpenFlow v1.0) structure + * @author michal.polkorab + */ +public class OF10MatchDeserializer implements OFDeserializer { + + private static final byte PADDING_IN_MATCH = 1; + private static final byte PADDING_IN_MATCH_2 = 2; + private static final byte NW_SRC_BITS = 6; + private static final byte NW_SRC_SHIFT = 8; + private static final int NW_SRC_MASK = ((1 << NW_SRC_BITS) - 1) << NW_SRC_SHIFT; + private static final byte NW_DST_BITS = 6; + private static final byte NW_DST_SHIFT = 14; + private static final int NW_DST_MASK = ((1 << NW_DST_BITS) - 1) << NW_DST_SHIFT; + + @Override + public MatchV10 deserialize(final ByteBuf input) { + MatchV10Builder builder = new MatchV10Builder(); + long wildcards = input.readUnsignedInt(); + builder.setWildcards(createWildcards(wildcards)); + builder.setNwSrcMask(decodeNwSrcMask(wildcards)); + builder.setNwDstMask(decodeNwDstMask(wildcards)); + builder.setInPort(input.readUnsignedShort()); + builder.setDlSrc(ByteBufUtils.readIetfMacAddress(input)); + builder.setDlDst(ByteBufUtils.readIetfMacAddress(input)); + + builder.setDlVlan(input.readUnsignedShort()); + builder.setDlVlanPcp(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_MATCH); + builder.setDlType(input.readUnsignedShort()); + builder.setNwTos(input.readUnsignedByte()); + builder.setNwProto(input.readUnsignedByte()); + input.skipBytes(PADDING_IN_MATCH_2); + builder.setNwSrc(ByteBufUtils.readIetfIpv4Address(input)); + builder.setNwDst(ByteBufUtils.readIetfIpv4Address(input)); + builder.setTpSrc(input.readUnsignedShort()); + builder.setTpDst(input.readUnsignedShort()); + return builder.build(); + } + + /** + * Decodes FlowWildcards + * @param input input ByteBuf + * @return decoded FlowWildcardsV10 + */ + public static FlowWildcardsV10 createWildcards(final long input) { + boolean inPort = (input & (1 << 0)) != 0; + boolean dlVLAN = (input & (1 << 1)) != 0; + boolean dlSrc = (input & (1 << 2)) != 0; + boolean dlDst = (input & (1 << 3)) != 0; + boolean dLType = (input & (1 << 4)) != 0; + boolean nwProto = (input & (1 << 5)) != 0; + boolean tpSrc = (input & (1 << 6)) != 0; + boolean tpDst = (input & (1 << 7)) != 0; + boolean dlVLANpcp = (input & (1 << 20)) != 0; + boolean nwTos = (input & (1 << 21)) != 0; + return new FlowWildcardsV10(dlDst, dlSrc, dLType, dlVLAN, + dlVLANpcp, inPort, nwProto, nwTos, tpDst, tpSrc); + } + + /** + * Decodes NwSrcMask from FlowWildcards (represented as uint32) + * @param input binary FlowWildcards + * @return decoded NwSrcMask + */ + public static short decodeNwSrcMask(final long input) { + return (short) Math.max(32 - ((input & NW_SRC_MASK) >> NW_SRC_SHIFT), 0); + } + + /** + * Decodes NwDstMask from FlowWildcards (represented as uint32) + * @param input binary FlowWildcards + * @return decoded NwDstMask + */ + public static short decodeNwDstMask(final long input) { + return (short) Math.max(32 - ((input & NW_DST_MASK) >> NW_DST_SHIFT), 0); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java new file mode 100644 index 0000000000..a9db0af9d3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializer.java @@ -0,0 +1,72 @@ +/* + * 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.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; + +/** + * Serializes ofp_match (OpenFlow v1.0) structure + * @author michal.polkorab + */ +public class OF10MatchSerializer implements OFSerializer { + + private static final byte PADDING_IN_MATCH = 1; + private static final byte PADDING_IN_MATCH_2 = 2; + private static final byte NW_SRC_SHIFT = 8; + private static final byte NW_DST_SHIFT = 14; + + /** + * Serializes ofp_match (OpenFlow v1.0) + * @param outBuffer output ByteBuf + * @param match match to be serialized + */ + @Override + public void serialize(final MatchV10 match, final ByteBuf outBuffer) { + outBuffer.writeInt(encodeWildcards(match.getWildcards(), match.getNwSrcMask(), match.getNwDstMask())); + outBuffer.writeShort(match.getInPort()); + 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); + outBuffer.writeShort(match.getDlType()); + outBuffer.writeByte(match.getNwTos()); + outBuffer.writeByte(match.getNwProto()); + outBuffer.writeZero(PADDING_IN_MATCH_2); + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(match.getNwSrc())); + outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(match.getNwDst())); + outBuffer.writeShort(match.getTpSrc()); + outBuffer.writeShort(match.getTpDst()); + } + + private static int encodeWildcards(final FlowWildcardsV10 wildcards, final short srcMask, final short dstMask) { + int bitmask = ByteBufUtils.fillBitMask(0, + wildcards.isINPORT(), + wildcards.isDLVLAN(), + wildcards.isDLSRC(), + wildcards.isDLDST(), + wildcards.isDLTYPE(), + wildcards.isNWPROTO(), + wildcards.isTPSRC(), + wildcards.isTPDST()); + bitmask |= ByteBufUtils.fillBitMask(20, + wildcards.isDLVLANPCP(), + wildcards.isNWTOS()); + bitmask |= ((32 - srcMask) << NW_SRC_SHIFT); + bitmask |= ((32 - dstMask) << NW_DST_SHIFT); + return bitmask; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java new file mode 100644 index 0000000000..7022c98d55 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer.java @@ -0,0 +1,98 @@ +/* + * 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.util; + +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.keys.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.common.types.rev130731.StandardMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +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.grouping.Match; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Serializes ofp_match (OpenFlow v1.3) + * @author michal.polkorab + * @author timotej.kubas + */ +public class OF13MatchSerializer implements OFSerializer, SerializerRegistryInjector { + 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; + + @Override + public void serialize(Match match, ByteBuf outBuffer) { + if (match == null) { + LOG.debug("Match is null"); + return; + } + int matchStartIndex = outBuffer.writerIndex(); + serializeType(match, outBuffer); + int matchLengthIndex = outBuffer.writerIndex(); + outBuffer.writeShort(EncodeConstants.EMPTY_LENGTH); + serializeMatchEntries(match.getMatchEntry(), outBuffer); + // Length of ofp_match (excluding padding) + int matchLength = outBuffer.writerIndex() - matchStartIndex; + outBuffer.setShort(matchLengthIndex, matchLength); + int paddingRemainder = matchLength % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + outBuffer.writeZero(EncodeConstants.PADDING - paddingRemainder); + } + } + + private static void serializeType(Match match, ByteBuf out) { + if (match.getType().isAssignableFrom(StandardMatchType.class)) { + out.writeShort(STANDARD_MATCH_TYPE_CODE); + } else if (match.getType().isAssignableFrom(OxmMatchType.class)) { + out.writeShort(OXM_MATCH_TYPE_CODE); + } + } + + /** + * Serializes MatchEntries + * @param matchEntries list of match entries (oxm_fields) + * @param out output ByteBuf + */ + public void serializeMatchEntries(List matchEntries, ByteBuf out) { + if (matchEntries == null) { + LOG.debug("Match entries are null"); + return; + } + for (MatchEntry entry : matchEntries) { + + MatchEntrySerializerKey key = new MatchEntrySerializerKey<>( + EncodeConstants.OF13_VERSION_ID, entry.getOxmClass(), entry.getOxmMatchField()); + if (entry.getOxmClass().equals(ExperimenterClass.class)) { + ExperimenterIdCase entryValue = (ExperimenterIdCase) entry.getMatchEntryValue(); + key.setExperimenterId(entryValue.getExperimenter().getExperimenter().getValue()); + } else { + key.setExperimenterId(null); + } + OFSerializer entrySerializer = registry.getSerializer(key); + entrySerializer.serialize(entry, out); + } + } + + @Override + public void injectSerializerRegistry(SerializerRegistry serializerRegistry) { + this.registry = serializerRegistry; + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtils.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtils.java new file mode 100644 index 0000000000..23f2f3c2fd --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtils.java @@ -0,0 +1,80 @@ +/* + * 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.impl.util; + +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; + +/** + * Used for common structures translation / conversion + * + * @author michal.polkorab + */ +public abstract class OpenflowUtils { + + private OpenflowUtils() { + //not called + } + + /** + * Creates PortState (OF v1.0) from input + * @param input value read from buffer + * @return port state + */ + public static PortStateV10 createPortState(long input){ + final Boolean psLinkDown = ((input) & (1<<0)) != 0; + final Boolean psBlocked = ((input) & (1<<1)) != 0; + final Boolean psLive = ((input) & (1<<2)) != 0; + final Boolean psStpListen = ((input) & (1<<8)) == 0; + final Boolean psStpLearn = ((input) & (1<<8)) != 0; + final Boolean psStpForward = ((input) & (1<<9)) != 0; // equals 2 << 8 + final Boolean psStpBlock = (((input) & (1<<9)) != 0) && (((input) & (1<<8)) != 0); // equals 3 << 8 + final Boolean psStpMask = ((input) & (1<<10)) != 0; // equals 4 << 8 + return new PortStateV10(psBlocked, psLinkDown, psLive, psStpBlock, psStpForward, psStpLearn, psStpListen, psStpMask); + } + + /** + * Creates PortConfig (OF v1.0) from input + * @param input value read from buffer + * @return port state + */ + public static PortConfigV10 createPortConfig(long input){ + final Boolean pcPortDown = ((input) & (1<<0)) != 0; + final Boolean pcNoStp = ((input) & (1<<1)) != 0; + final Boolean pcNoRecv = ((input) & (1<<2)) != 0; + final Boolean pcNoRecvStp = ((input) & (1<<3)) != 0; + final Boolean pcNoFlood = ((input) & (1<<4)) != 0; + final Boolean pcNoFwd = ((input) & (1<<5)) != 0; + final Boolean pcNoPacketIn = ((input) & (1<<6)) != 0; + return new PortConfigV10(pcNoFlood, pcNoFwd, pcNoPacketIn, pcNoRecv, pcNoRecvStp, pcNoStp, pcPortDown); + } + + /** + * Creates PortFeatures (OF v1.0) from input + * @param input value read from buffer + * @return port state + */ + public static PortFeaturesV10 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 pfCopper = ((input) & (1<<7)) != 0; + final Boolean pfFiber = ((input) & (1<<8)) != 0; + final Boolean pfAutoneg = ((input) & (1<<9)) != 0; + final Boolean pfPause = ((input) & (1<<10)) != 0; + final Boolean pfPauseAsym = ((input) & (1<<11)) != 0; + return new PortFeaturesV10(pf100mbFd, pf100mbHd, pf10gbFd, pf10mbFd, pf10mbHd, + pf1gbFd, pf1gbHd, pfAutoneg, pfCopper, pfFiber, pfPause, pfPauseAsym); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java new file mode 100644 index 0000000000..6d527c4a04 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/SimpleDeserializerRegistryHelper.java @@ -0,0 +1,47 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; + +/** + * Helper class for deserializer registration. + * @author michal.polkorab + */ +public class SimpleDeserializerRegistryHelper { + + private short version; + private DeserializerRegistry registry; + + /** + * @param version wire protocol version + * @param deserializerRegistry registry to be filled with message deserializers + */ + 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 deserializedObjectClass class of object that will be deserialized by given deserializer + * @param deserializer deserializer instance + */ + 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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMaker.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMaker.java new file mode 100644 index 0000000000..3ace85ab7c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMaker.java @@ -0,0 +1,26 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; + +/** + * @author michal.polkorab + * @param + */ +public interface TypeKeyMaker { + + /** + * @param entry + * @return key that will be used for serializer lookup in + * the serializer registry + */ + abstract MessageTypeKey make(T entry); + +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactory.java new file mode 100644 index 0000000000..2312685c64 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactory.java @@ -0,0 +1,95 @@ +/* + * 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.util; + +import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +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.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase; +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.actions.grouping.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.InstructionChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry; + +/** + * Creates KeyMakers + * @author michal.polkorab + */ +public abstract class TypeKeyMakerFactory { + + private TypeKeyMakerFactory() { + //not called + } + + /** + * @param version openflow wire version that shall be used + * in lookup key + * @return lookup key + */ + public static TypeKeyMaker createMatchEntriesKeyMaker(short version) { + return new AbstractTypeKeyMaker(version) { + @Override + public MatchEntrySerializerKey make(MatchEntry entry) { + MatchEntrySerializerKey key; + key = new MatchEntrySerializerKey<>(getVersion(), entry.getOxmClass(), + entry.getOxmMatchField()); + if (entry.getOxmClass().equals(ExperimenterClass.class)) { + ExperimenterIdCase entryValue = (ExperimenterIdCase) entry.getMatchEntryValue(); + key.setExperimenterId(entryValue.getExperimenter().getExperimenter().getValue()); + return key; + } + key.setExperimenterId(null); + return key; + } + }; + } + + /** + * @param version openflow wire version that shall be used + * in lookup key + * @return lookup key + */ + public static TypeKeyMaker createActionKeyMaker(short version) { + return new AbstractTypeKeyMaker(version) { + @Override + public MessageTypeKey make(Action entry) { + if (entry.getExperimenterId() != null) { + return new ActionSerializerKey<>(getVersion(), + (Class) entry.getActionChoice().getImplementedInterface(), + entry.getExperimenterId().getValue()); + } + return new ActionSerializerKey<>(getVersion(), + (Class) entry.getActionChoice().getImplementedInterface(), null); + } + }; + } + + /** + * @param version openflow wire version that shall be used + * in lookup key + * @return lookup key + */ + public static TypeKeyMaker createInstructionKeyMaker(short version) { + return new AbstractTypeKeyMaker(version) { + @Override + public MessageTypeKey make(Instruction entry) { + if (entry.getExperimenterId() != null) { + return new InstructionSerializerKey<>(getVersion(), + (Class) entry.getInstructionChoice().getImplementedInterface(), + entry.getExperimenterId().getValue()); + } + return new InstructionSerializerKey<>(getVersion(), + (Class) entry.getInstructionChoice().getImplementedInterface(), null); + } + }; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java new file mode 100644 index 0000000000..b360f89fd4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/TypeToClassInitHelper.java @@ -0,0 +1,41 @@ +/* + * 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.util; + +import java.util.Map; +import org.opendaylight.openflowjava.protocol.api.keys.TypeToClassKey; + +/** + * @author michal.polkorab + * + */ +public class TypeToClassInitHelper { + + private short version; + private Map> messageClassMap; + + /** + * Constructor + * @param version protocol wire version + * @param messageClassMap map which stores type to class mapping + */ + public TypeToClassInitHelper(short version, Map> messageClassMap) { + this.version = version; + this.messageClassMap = messageClassMap; + } + + /** + * Registers Class int the type to class mapping + * @param type code value for message type / class + * @param clazz class corresponding to the code + */ + public void registerTypeToClass(short type, Class clazz) { + messageClassMap.put(new TypeToClassKey(version, type), clazz); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/util/VersionAssignableFactory.java new file mode 100644 index 0000000000..d10f8fa6c2 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/Counter.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/Counter.java new file mode 100644 index 0000000000..33bd50aa88 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/Counter.java @@ -0,0 +1,84 @@ +/* + * 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.statistics; + +import java.util.concurrent.atomic.AtomicLong; +/** + * Counts statistics + * + * @author madamjak + */ +public class Counter { + + private AtomicLong counterValue; + private AtomicLong counterLastReadValue; + + /** + * Default constructor + */ + public Counter() { + counterValue = new AtomicLong(0L); + counterLastReadValue = new AtomicLong(0L); + } + + /** + * Increment current counter value + */ + public void incrementCounter(){ + counterValue.incrementAndGet(); + } + + /** + * return the last read value of counter. This value can be set during the reading of current counter value, + * for detail see method getCounterValue(boolean modifyLastReadValue). + * @return the counterLastReadValue + */ + public long getCounterLastReadValue() { + return counterLastReadValue.get(); + } + + /** + * get current value of counter and rewrite CounterLastReadValue by current value + * @return the current value of counter + */ + public long getCounterValue() { + return getCounterValue(true); + } + + /** + * get current counter value + * @param modifyLastReadValue + * true - CounterLastReadValue will be rewritten by current CounterValue + * false - no change CounterLastReadValue + * @return the current value of counter + */ + public long getCounterValue(boolean modifyLastReadValue) { + if(modifyLastReadValue){ + counterLastReadValue.set(counterValue.get()); + } + return counterValue.get(); + } + + /** + * set current counter value and CounterLastReadValue to 0 (zero) + */ + public void reset(){ + counterValue.set(0l); + counterLastReadValue.set(0l); + } + + /** + * @return last and current count for specified statistic + */ + public String getStat() { + long cntPrevVal = getCounterLastReadValue(); + long cntCurValue = getCounterValue(); + return String.format("+%d | %d",cntCurValue-cntPrevVal,cntCurValue); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/CounterEventTypes.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/CounterEventTypes.java new file mode 100644 index 0000000000..60b1c6da35 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/CounterEventTypes.java @@ -0,0 +1,57 @@ +/* + * 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.statistics; + +/** + * Enumeration of events to be counted with StatisticsCounters + * @author madamjak + * + */ +public enum CounterEventTypes { + /** + * enter message to OFJ and pass to downstream + */ + DS_ENTERED_OFJAVA, + /** + * flow-mod is entered + */ + DS_FLOW_MODS_ENTERED, + /** + * encode message successfully + */ + DS_ENCODE_SUCCESS, + /** + * fail encode message + */ + DS_ENCODE_FAIL, + /** + * flow-mod encoded and sent to downstream + */ + DS_FLOW_MODS_SENT, + /** + * packetIn message got dropped -filtering is active + */ + US_DROPPED_PACKET_IN, + /** + * receive message and pass to upstream + */ + US_RECEIVED_IN_OFJAVA, + /** + * decode message successfully + */ + US_DECODE_SUCCESS, + /** + * fail decode message + */ + US_DECODE_FAIL, + /** + * pass message to consumer (end of upstream) + */ + US_MESSAGE_PASS; +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java new file mode 100644 index 0000000000..d0c071e50f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/statistics/StatisticsCounters.java @@ -0,0 +1,248 @@ +/* + * 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.statistics; + +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ConcurrentHashMap; +import org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Singleton class to hold and process counters + * @author madamjak + * + */ +public final class StatisticsCounters implements StatisticsHandler { + + /** + * Default delay between two writings into log (milliseconds) + */ + public static final int DEFAULT_LOG_REPORT_PERIOD = 10000; + /** + * Minimal delay between two writings into log (milliseconds) + */ + public static final int MINIMAL_LOG_REPORT_PERIOD = 500; + private static StatisticsCounters instanceHolder; + private static final Logger LOG = LoggerFactory.getLogger(StatisticsCounters.class); + + private Timer logReporter; + private int logReportPeriod; + private boolean runLogReport; + private Map countersMap; + private boolean runCounting; + // array to hold enabled counter types + private CounterEventTypes[] enabledCounters = { + CounterEventTypes.DS_ENCODE_FAIL, + CounterEventTypes.DS_ENCODE_SUCCESS, + CounterEventTypes.DS_ENTERED_OFJAVA, + CounterEventTypes.DS_FLOW_MODS_ENTERED, + CounterEventTypes.DS_FLOW_MODS_SENT, + CounterEventTypes.US_DROPPED_PACKET_IN, + CounterEventTypes.US_DECODE_FAIL, + CounterEventTypes.US_DECODE_SUCCESS, + CounterEventTypes.US_MESSAGE_PASS, + CounterEventTypes.US_RECEIVED_IN_OFJAVA}; + + /** + * Get instance of statistics counters, first created object does not start counting and log reporting + * @return an instance + */ + public static synchronized StatisticsCounters getInstance() { + if (instanceHolder == null) { + instanceHolder = new StatisticsCounters(); + } + return instanceHolder; + } + + private StatisticsCounters() { + countersMap = new ConcurrentHashMap<>(); + for(CounterEventTypes cet : enabledCounters){ + countersMap.put(cet, new Counter()); + } + runCounting = false; + this.logReportPeriod = 0; + this.runLogReport = false; + LOG.debug("StaticsCounters has been created"); + } + + /** + * Start counting (counters are set to 0 before counting starts) + * @param reportToLogs - true = statistic counters will periodically log + * @param logReportDelay - delay between two logs (in milliseconds) + */ + public void startCounting(boolean reportToLogs, int logReportDelay){ + if (runCounting) { + return; + } + resetCounters(); + LOG.debug("Counting started..."); + if(reportToLogs){ + startLogReport(logReportDelay); + } + runCounting = true; + } + + /** + * Stop counting, values in counters are untouched, log reporter is stopped + */ + public void stopCounting(){ + runCounting = false; + LOG.debug("Stop counting..."); + stopLogReport(); + } + + /** + * Give an information if counting is running + * @return true, if counting is running, otherwise false + */ + public boolean isRunCounting(){ + return runCounting; + } + + /** + * Prints statistics with given delay between logs + * @param logReportDelay - delay between two logs (in milliseconds) + * @exception IllegalArgumentException if logReportDelay is less than 0 + */ + public void startLogReport(int logReportDelay){ + if(runLogReport){ + return; + } + if(logReportDelay <= 0){ + throw new IllegalArgumentException("logReportDelay has to be greater than 0"); + } + if(logReportDelay < MINIMAL_LOG_REPORT_PERIOD){ + this.logReportPeriod = MINIMAL_LOG_REPORT_PERIOD; + } else { + this.logReportPeriod = logReportDelay; + } + logReporter = new Timer("SC_Timer"); + logReporter.schedule(new LogReporterTask(this), this.logReportPeriod, this.logReportPeriod); + runLogReport = true; + LOG.debug("Statistics log reporter has been scheduled with period {} ms", this.logReportPeriod); + } + + /** + * Stops logging, counting continues + */ + public void stopLogReport(){ + if(runLogReport){ + if(logReporter != null){ + logReporter.cancel(); + LOG.debug("Statistics log reporter has been canceled"); + } + runLogReport = false; + } + } + + /** + * Give an information if log reporter is running (statistics are write into logs). + * @return true if log reporter writes statistics into log, otherwise false + */ + public boolean isRunLogReport(){ + return runLogReport; + } + + /** + * @return the current delay between two writings into logs + */ + public int getLogReportPeriod() { + return logReportPeriod; + } + + /** + * @return the enabled counters + */ + protected CounterEventTypes[] getEnabledCounters() { + return enabledCounters; + } + /** + * @return the countersMap + */ + protected Map getCountersMap() { + return countersMap; + } + + /** + * Give an information if is given counter is enabled + * @param counterEventKey + * @return true if counter has been Enabled, otherwise false + */ + public boolean isCounterEnabled(CounterEventTypes counterEventKey){ + if (counterEventKey == null) { + return false; + } + return countersMap.containsKey(counterEventKey); + } + + /** + * Get counter by CounterEventType + * @param counterEventKey key to identify counter (can not be null) + * @return Counter object or null if counter has not been enabled + * @throws IllegalArgumentException if counterEventKey is null + */ + public Counter getCounter(CounterEventTypes counterEventKey) { + if (counterEventKey == null) { + throw new IllegalArgumentException("counterEventKey can not be null"); + } + return countersMap.get(counterEventKey); + } + + /** + * Increment value of given counter + * @param counterEventKey key to identify counter + */ + public void incrementCounter(CounterEventTypes counterEventKey) { + if(runCounting){ + if (isCounterEnabled(counterEventKey)){ + countersMap.get(counterEventKey).incrementCounter(); + } + } + } + + @Override + public void resetCounters() { + for(CounterEventTypes cet : enabledCounters){ + countersMap.get(cet).reset(); + } + LOG.debug("StaticsCounters has been reset"); + } + + @Override + public String printStatistics() { + StringBuilder strBuilder = new StringBuilder(); + for(CounterEventTypes cet : getEnabledCounters()){ + strBuilder.append(cet.name() + ": " + getCountersMap().get(cet).getStat() + "\n"); + } + return strBuilder.toString(); + } + + /** + * internal class to process logReporter + * @author madamjak + * + */ + private static class LogReporterTask extends TimerTask { + private static final Logger LOG = LoggerFactory.getLogger(LogReporterTask.class); + + private StatisticsCounters sc; + public LogReporterTask(StatisticsCounters sc) { + this.sc = sc; + } + + @Override + public void run() { + for(CounterEventTypes cet : sc.getEnabledCounters()){ + LOG.debug("{}: {}", cet.name(), sc.getCountersMap().get(cet).getStat()); + } + } + } +} diff --git a/openflowjava/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/openflowjava/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 new file mode 100644 index 0000000000..e30b4d6bd5 --- /dev/null +++ b/openflowjava/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 @@ -0,0 +1,118 @@ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; + +import org.opendaylight.openflowjava.protocol.api.connection.StatisticsConfiguration; +import org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler; +import org.opendaylight.openflowjava.statistics.StatisticsCounters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** +* This is the definition of statistics collection module identity. +*/ +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 LOG = LoggerFactory.getLogger(StatisticsCollectionModule.class); + + public StatisticsCollectionModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public StatisticsCollectionModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.StatisticsCollectionModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + final Statistics statistics = getStatistics(); + final StatisticsCounters statsCounter = StatisticsCounters.getInstance(); + StatisticsConfiguration statsConfig = null; + if (statistics != null) { + statsConfig = new StatisticsConfiguration() { + + @Override + public boolean getStatisticsCollect() { + if (statistics.getStatisticsCollect() != null) { + return statistics.getStatisticsCollect().booleanValue(); + } + return false; + } + + @Override + public int getLogReportDelay() { + if (statistics.getLogReportDelay() != null) { + return statistics.getLogReportDelay().intValue(); + } + return 0; + } + }; + } + if (statsConfig != null) { + statsCounter.startCounting(statsConfig.getStatisticsCollect(), statsConfig.getLogReportDelay()); + } else { + LOG.debug("Unable to start StatisticCounter - wrong configuration"); + } + + /* Internal MXBean implementation */ + final StatisticsCollectionRuntimeMXBean collectionBean = new StatisticsCollectionRuntimeMXBean() { + + @Override + public String printOfjavaStatistics() { + if (statsCounter != null) { + return statsCounter.printStatistics(); + } + return "Statistics collection is not avaliable."; + } + @Override + public String getMsgStatistics() { + return printOfjavaStatistics(); + } + @Override + public String resetOfjavaStatistics() { + statsCounter.resetCounters(); + return "Statistics have been reset"; + } + }; + + /* MXBean registration */ + final StatisticsCollectionRuntimeRegistration runtimeReg = + getRootRuntimeBeanRegistratorWrapper().register(collectionBean); + + /* Internal StatisticsCollectionService implementation */ + final class AutoClosableStatisticsCollection implements StatisticsHandler, AutoCloseable { + + @Override + public void close() { + if (runtimeReg != null) { + try { + runtimeReg.close(); + } + catch (Exception e) { + String errMsg = "Error by stoping StatisticsCollectionService."; + LOG.error(errMsg, e); + throw new IllegalStateException(errMsg, e); + } + } + LOG.info("StatisticsCollection Service consumer (instance {} turn down.)", this); + } + + @Override + public void resetCounters() { + statsCounter.resetCounters(); + } + + @Override + public String printStatistics() { + return statsCounter.printStatistics(); + } + } + + AutoCloseable ret = new AutoClosableStatisticsCollection(); + LOG.info("StatisticsCollection service (instance {}) initialized.", ret); + return ret; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModuleFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModuleFactory.java new file mode 100644 index 0000000000..04db2fa886 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/_switch/connection/provider/impl/rev140328/StatisticsCollectionModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: openflow-switch-connection-provider-impl yang module local name: statistics-collection-service-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Thu Nov 13 12:52:26 CET 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; +public class StatisticsCollectionModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328.AbstractStatisticsCollectionModuleFactory { + +} diff --git a/openflowjava/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/openflowjava/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 new file mode 100644 index 0000000000..a9756bdd32 --- /dev/null +++ b/openflowjava/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 @@ -0,0 +1,76 @@ +/** +* Generated file + +* Generated from: yang module name: openflow-switch-connection-provider-impl yang module local name: openflow-switch-connection-provider-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Mar 28 17:50:58 PDT 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; + +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; + +/** + * @deprecated Replaced by blueprint wiring + */ +@Deprecated +public final class SwitchConnectionProviderModule extends AbstractSwitchConnectionProviderModule { + private BundleContext bundleContext; + + /** + * @param identifier + * @param dependencyResolver + */ + public SwitchConnectionProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + /** + * @param identifier + * @param dependencyResolver + * @param oldModule + * @param oldInstance + */ + public SwitchConnectionProviderModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, + final SwitchConnectionProviderModule oldModule, final java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + 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); + + // 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 + 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); + } + } + }); + } + + public void setBundleContext(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + @Override + public boolean canReuseInstance(AbstractSwitchConnectionProviderModule oldModule) { + return true; + } +} diff --git a/openflowjava/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/openflowjava/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 new file mode 100644 index 0000000000..ca41fc3923 --- /dev/null +++ b/openflowjava/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 @@ -0,0 +1,36 @@ +/** +* Generated file + +* Generated from: yang module name: openflow-switch-connection-provider-impl yang module local name: openflow-switch-connection-provider-impl +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Mar 28 17:50:58 PDT 2014 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.provider.impl.rev140328; + +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/openflowjava/openflow-protocol-impl/src/main/resources/exemplary-cacert.pem b/openflowjava/openflow-protocol-impl/src/main/resources/exemplary-cacert.pem new file mode 100644 index 0000000000..f726b9280c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/resources/exemplary-cacert.pem @@ -0,0 +1,70 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 3 (0x3) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=CA, O=Open vSwitch, OU=controllerca, CN=OVS controllerca CA Certificate (2012 Nov 30 22:32:42) + Validity + Not Before: May 27 07:25:06 2014 GMT + Not After : May 24 07:25:06 2024 GMT + Subject: C=US, ST=CA, O=Open vSwitch, OU=controllerca, CN=OVS controllerca CA Certificate (2012 Nov 30 22:32:42) + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:cd:ee:e0:69:c0:bb:06:76:35:dd:7d:cd:d2:1e: + 7a:eb:e3:39:c9:fb:e4:b1:63:2c:4b:29:83:88:b3: + a4:b3:96:de:cd:43:1e:1c:6c:82:88:23:6a:e6:fc: + 1b:69:68:a0:89:00:2f:76:2d:66:60:cf:6a:aa:15: + 22:3d:26:f1:36:c2:a4:af:70:ec:22:eb:ba:fe:43: + 24:42:b1:45:08:ce:51:12:14:03:55:27:74:ed:1b: + 2a:b9:21:ae:3c:a7:4d:63:92:7d:ed:d6:e2:e2:91: + c7:55:30:0b:6f:26:d2:78:67:c2:01:fc:89:f8:20: + 0f:e8:8b:3b:c0:41:bf:de:9f:a6:d2:3c:f2:25:71: + e1:89:81:a8:93:41:78:41:b8:20:df:77:39:39:a6: + 4a:5b:72:b8:ce:89:ad:2b:37:94:48:e0:94:bc:d0: + 7b:08:6a:6f:bb:16:33:03:11:4a:bb:17:19:fa:41: + 19:53:74:62:72:59:ac:b9:1b:81:7c:30:15:4e:e5: + 34:fd:fa:12:da:52:dc:f0:b9:4a:23:3c:69:7b:9d: + f3:62:76:7b:36:0a:3d:7e:77:d2:61:7e:84:20:6f: + 57:ad:9b:5a:1b:53:7b:43:fa:8f:68:d9:cb:a3:c2: + 7f:d8:ea:70:40:25:e0:de:2f:9c:dd:df:bd:d1:73: + be:8d + Exponent: 65537 (0x10001) + Signature Algorithm: md5WithRSAEncryption + 89:cd:f5:bc:e1:c8:ff:d8:9e:12:6d:59:2f:20:90:a4:bc:cb: + cd:13:2c:c0:de:24:81:6b:6a:54:32:6b:bd:2b:c1:1e:3b:b5: + d5:25:49:14:73:54:5b:93:0b:31:30:aa:10:2d:aa:be:41:4e: + ad:b9:1d:19:7d:1a:4b:a6:8b:d7:0b:47:6f:c5:b5:ca:e2:33: + 32:d0:c4:25:b3:b8:ee:f8:e6:34:0b:2b:fc:db:52:62:8b:42: + 00:d3:ba:10:9c:5b:41:c7:59:22:74:58:37:b7:08:7d:fc:ee: + 8a:86:2e:2c:95:d6:b1:26:08:72:a2:db:07:a0:ea:e9:af:db: + 78:64:c0:03:4e:70:b1:c7:42:b8:6b:80:af:0c:82:2a:f8:b4: + 67:34:d2:66:d8:20:66:8d:34:e6:1b:6a:de:94:58:2a:a5:dd: + dd:1e:66:e9:e7:8b:b5:d4:73:03:97:05:9e:f7:ce:f7:f8:fe: + cd:d0:b7:f4:57:0b:08:3b:98:99:6d:8d:00:46:fa:c5:9c:a4: + 42:ad:9c:d1:86:43:70:ae:2f:b2:91:4c:87:96:7e:ff:03:45: + 15:3f:99:1a:44:33:3c:ea:bd:6f:76:8c:09:2a:3b:13:38:a7: + 95:2b:ef:88:ed:f0:98:dc:17:0c:6f:4a:1e:11:03:17:9e:ae: + af:b4:d0:11 +-----BEGIN CERTIFICATE----- +MIIDiDCCAnACAQMwDQYJKoZIhvcNAQEEBQAwgYkxCzAJBgNVBAYTAlVTMQswCQYD +VQQIEwJDQTEVMBMGA1UEChMMT3BlbiB2U3dpdGNoMRUwEwYDVQQLEwxjb250cm9s +bGVyY2ExPzA9BgNVBAMTNk9WUyBjb250cm9sbGVyY2EgQ0EgQ2VydGlmaWNhdGUg +KDIwMTIgTm92IDMwIDIyOjMyOjQyKTAeFw0xNDA1MjcwNzI1MDZaFw0yNDA1MjQw +NzI1MDZaMIGJMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFTATBgNVBAoTDE9w +ZW4gdlN3aXRjaDEVMBMGA1UECxMMY29udHJvbGxlcmNhMT8wPQYDVQQDEzZPVlMg +Y29udHJvbGxlcmNhIENBIENlcnRpZmljYXRlICgyMDEyIE5vdiAzMCAyMjozMjo0 +MikwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDN7uBpwLsGdjXdfc3S +Hnrr4znJ++SxYyxLKYOIs6Szlt7NQx4cbIKII2rm/BtpaKCJAC92LWZgz2qqFSI9 +JvE2wqSvcOwi67r+QyRCsUUIzlESFANVJ3TtGyq5Ia48p01jkn3t1uLikcdVMAtv +JtJ4Z8IB/In4IA/oizvAQb/en6bSPPIlceGJgaiTQXhBuCDfdzk5pkpbcrjOia0r +N5RI4JS80HsIam+7FjMDEUq7Fxn6QRlTdGJyWay5G4F8MBVO5TT9+hLaUtzwuUoj +PGl7nfNidns2Cj1+d9JhfoQgb1etm1obU3tD+o9o2cujwn/Y6nBAJeDeL5zd373R +c76NAgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAInN9bzhyP/YnhJtWS8gkKS8y80T +LMDeJIFralQya70rwR47tdUlSRRzVFuTCzEwqhAtqr5BTq25HRl9Gkumi9cLR2/F +tcriMzLQxCWzuO745jQLK/zbUmKLQgDTuhCcW0HHWSJ0WDe3CH387oqGLiyV1rEm +CHKi2weg6umv23hkwANOcLHHQrhrgK8Mgir4tGc00mbYIGaNNOYbat6UWCql3d0e +Zunni7XUcwOXBZ73zvf4/s3Qt/RXCwg7mJltjQBG+sWcpEKtnNGGQ3CuL7KRTIeW +fv8DRRU/mRpEMzzqvW92jAkqOxM4p5Ur74jt8JjcFwxvSh4RAxeerq+00BE= +-----END CERTIFICATE----- diff --git a/openflowjava/openflow-protocol-impl/src/main/resources/exemplary-ctlKeystore b/openflowjava/openflow-protocol-impl/src/main/resources/exemplary-ctlKeystore new file mode 100644 index 0000000000000000000000000000000000000000..c7310975775cf0418464970fb3f0922901437077 GIT binary patch literal 2254 zcma)-cTkh*7RK`>0VGn5G!YDoQUsPS2?RqEh%{-kfD!2liPX@GG$C{mR1iTa0s)m? zlq>F~cMvIxARR=SEJ#~0AaHSaobk{5$C-JbbKaTvcb<9YoP(8v6$k_ZJqqBT0MJJ# zo$$x6Dj*OR0HnkBK`vH=3@ZQ!&O>VK$b z_R`hrv$J6bYr^W2H~F3Y=}YdOR5m zZ#5$6IgrDJOHUn?j{)}eHos1n&1wc;7L%8JHmt4!(>z zUYol{!>N~xilt?Dyh^`ft3yJ^0>!?LBogZm^KP?w; z$ITKRIPDpt*@OJ&pES4gJo4r|On;RK;ZsicQ`32H?cBi5} z7<&=J(dF;YnKKP&k%bE=}Y(u+~j21X01t*yC+6fmGoYDnP1{GBBli3JUr9$wC*zrI4N*0`29D)S8sP`5~Od+ZSh z6#ByC;(tjkC{&tR;Q{x+?G zyDo-#Y4G9xo>Vf9mZ=pzJSJ|BvS4JqtBca{h(b#hCNHC`1-o$*u`NfmvkPU2{+8Cl|0loH++YKk(1 zyU0dn2WV^tWj}UnY8lK~#Mo5d2h}KbjM|8p@2&2V8%y!HjI_hKMGMVORK9J3qCoU; zdj+|xNApqXhW;25;C3m#we@5m)Z=isQX_qf-MszI8big7;<&DepfpNx%Ou&W{Z0<( zG(iv5wf6N8rkY+>!Y8Mbdd-bp1j54rA*bvEk<8-n4|A^HiY`@=Tq>qw=&IB8d$HCF zW4^(osVhSR%C-I%Dv>v6oPA50JzppYqD!VT-}kIhLF8tnm1~|CS7K$gd9;|9c%YH> zGOj&ou$T9Jkg%f!HN(`ri9vpoM=;*;K+8)`->Do}YuBCas45vvGztK1aPuE_ zqF$P3!$!Cb3?R%T^PsP5^+jK){H2^l^}#6=nfvMM5pieu`sAC_xj=2O@t|5J(Oa zPYMm?Zx-O}OLqF1K91xdd(eEnJ>1+V-ed>#MNsX>Z5R?~a@7p=YY9crL=h<7zRpx< zvV$)LC4~Xe7?iPxKMD(?Fc@VlMp*$P4T=hIq7^_Kh)08p7&LhONGkp!!HBq@c>h1^ z8BpX0)Nv&LuPva+|I$#rj~>MQOD#k8bwfEjDm&sRBn%d>Acs-F;^h=DRJ#%d+2>(N1P8 z2&t|%IW z&0Zp^0Et(%G0aZ0Rw|{Ry?w~wxwLu(>oKdZmvUolGPQQo@`cfheQkcl&PzH;(lGS7 zbOE`}Gfm?Xx#7Kzjovh0J#?UOglEMOe(H; zgx|77)%RYcwLM>I)SQr0Nm{uboFTsXRbA7M*dd5+DdG%)8JpOZtzb^~!*54mjVlI? zy8rl+@7*dAJ3BLS=FI_^#dlNO_CPCWvqFhTNlc_^c305TQY`6hdycA4%TDqepdcN{ z)%?s?%|$vJ>yBplo$rqICv_6GPcnBrnWMVY!D5ozyLVn4;r3YEVuNFAtFs!l7TqP) z17}OT{4f+#OQJP1czCqMm{Sy-9Tl8Yi%K%nGLsWaQWZ3e3=EAF z{PN2bj13fwjI4}}tW1nF4dldm4NVM8jm!d9G}_)hK(_wz4rORao*HT4}m9Z1HCYw)QWfA(> zv2v!$r%2mH;vt74Q!kYt+qYuf-5-+=9;*yH&QvXXFst&_V?ZRk3!e|(#1Zb8?*bBk^;`g~ZBzdAYU zp~Smur<0B*Xk5Q(7Tx@7{`{Rq>RXkx{io}NPB?yewT6Di!if=Xj~?mSPql5?dQ`(p z`Pi1gkEiqgn_Zk*z3<|dbPnk|hocM3Kic_Q9Qkj?zs7S7XL;YM zMNh@`zNY5Lrv5j1m*IHDT4J|#u8q*mw@l2842;Mj1Wa7O5MpGA-KBVcr}pxFm+e#f z-zBa0Q8*y`t9{Dkzxi`lIft~~b=$K#@6zl*(_7Bx!=7>9o-Vn|?aEHnte z^oMJ;MClK2D-Fmp5Sxshd!8eD}UvHL#Tj$y^k~=jLs|K4yApHWoLT;^rM|tv(lgxjt)_R3^a-hx7S~qXeak0g z)|>s{-JT2g|L@rvC2vx8mT88(Z2RhMt0cmfzfC^9y{7YY&Q7tkO?GcSq_3@wxj8>) zMb1RFur<>{Se!F8rEWJdZ`dO6qvlc5Bu~p74}WVsX}+@2Ipb5s-HtWk`}MqTY + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openflowjava/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml b/openflowjava/openflow-protocol-impl/src/main/resources/org/opendaylight/blueprint/openflow-protocol-impl.xml new file mode 100644 index 0000000000..c4ce514b7f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang b/openflowjava/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang new file mode 100644 index 0000000000..81e5b3e378 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/yang/openflow-switch-connection-provider-impl.yang @@ -0,0 +1,192 @@ +module openflow-switch-connection-provider-impl { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl"; + prefix "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 2013-07-15; } + import openflow-configuration {prefix of-config; revision-date 2014-06-30; } + import rpc-context { prefix rpcx; revision-date 2013-06-17; } + + description + "openflow-switch-connection-provider"; + + revision "2014-03-28" { + description + "Initial revision"; + } + + identity 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 { + description + "This is the definition of statistics collection module identity."; + base config:module-type; + config:provided-service openflow-switch-connection-provider:statistics-collection-service; + config:java-name-prefix StatisticsCollection; + } + + augment "/config:modules/config:module/config:configuration" { + 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; + mandatory true; + } + leaf address { + description "address of local listening interface"; + type ietf-inet:ip-address; + } + leaf transport-protocol { + description "Transport protocol used for communication."; + type of-config:transport-protocol; + mandatory true; + } + leaf switch-idle-timeout { + description "idle timeout in [ms]"; + type uint32; + mandatory true; + } + 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; + } + } + } + + case statistics-collection-service-impl { + when "/config:modules/config:module/config:type = 'statistics-collection-service-impl'"; + + container statistics { + leaf statistics-collect { + description "Toggle statistics collecting"; + type boolean; + } + leaf log-report-delay { + description "Delay between statistics logs"; + type uint16; + } + } + list openflow-switch-connection-provider { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity openflow-switch-connection-provider:openflow-switch-connection-provider; + } + } + } + } + } + + augment "/config:modules/config:module/config:state" { + case statistics-collection-service-impl { + when "/config:modules/config:module/config:type = 'statistics-collection-service-impl'"; + + description + "MXBean designed for Message Statistic providing to JConsole."; + + leaf msgStatistics { + type string; + } + + rpcx:rpc-context-instance "print-ofjava-statistics-rpc"; + rpcx:rpc-context-instance "reset-ofjava-statistics-rpc"; + } + } + + identity print-ofjava-statistics-rpc; + identity reset-ofjava-statistics-rpc; + + rpc print-ofjava-statistics { + description + "Shortcut JMX call to printOfjavaStatistics."; + input { + uses rpcx:rpc-context-ref { + refine context-instance { + rpcx:rpc-context-instance print-ofjava-statistics-rpc; + } + } + } + output { + leaf result { + type string; + } + } + } + + rpc reset-ofjava-statistics { + description + "Shortcut JMX call to resetOfjavaStatistics."; + input { + uses rpcx:rpc-context-ref { + refine context-instance { + rpcx:rpc-context-instance reset-ofjava-statistics-rpc; + } + } + } + output { + leaf result { + type string; + } + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandlerTest.java new file mode 100644 index 0000000000..27aac9ce0a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DelegatingInboundHandlerTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014 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 static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import io.netty.channel.ChannelHandlerContext; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author jameshall + */ +public class DelegatingInboundHandlerTest { + + @Mock ChannelHandlerContext mockChHndlrCtx ; + @Mock MessageConsumer mockMsgConsumer ; + @Mock DataObject mockDataObject ; + + DelegatingInboundHandler dih ; + + /** + * Sets up test environment + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + dih = new DelegatingInboundHandler(mockMsgConsumer) ; + } + + /** + * + */ + @Test + public void testChannelReadSuccess() { + dih.channelRead(mockChHndlrCtx, mockDataObject) ; + + // Verify that the message buf was released... + verify( mockMsgConsumer, times(1)).consume(mockDataObject); + } + /** + * + */ + @Test + public void testChannelInactive() { + dih.channelInactive(mockChHndlrCtx); + + verify( mockMsgConsumer, times(1)).consume(any(DataObject.class)); + } + + /** + * ChannelUnregistered + */ + @Test + public void testChannelUnregistered() { + dih.channelUnregistered(mockChHndlrCtx); + + verify( mockMsgConsumer, times(1)).consume(any(DataObject.class)); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java new file mode 100644 index 0000000000..55ebf43d1f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/DummyDecoder.java @@ -0,0 +1,36 @@ +/* + * 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.core; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class DummyDecoder extends ByteToMessageDecoder { + + private static final Logger LOG = LoggerFactory + .getLogger(DummyDecoder.class); + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf in, + List out) throws Exception { + LOG.debug("decoding"); + ctx.fireChannelReadComplete(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandlerTest.java new file mode 100644 index 0000000000..b3462e98ea --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/IdleHandlerTest.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2014 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 static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import io.netty.channel.ChannelHandlerContext; + +import java.util.concurrent.TimeUnit; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; + +/** + * + * @author jameshall + */ +public class IdleHandlerTest { + + @Mock ChannelHandlerContext mockChHndlrCtx ; + + IdleHandler idleHandler ; + + /** + * Sets up test environment + * + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + idleHandler = new IdleHandler(60L, TimeUnit.MINUTES ) ; + } + + /** + * Test message passing on channel read + */ + @Test + public void testChannelRead() { + try { + idleHandler.channelRead(mockChHndlrCtx, new Object() ); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that a read was fired for the next handler ... + verify(mockChHndlrCtx, times(1)).fireChannelRead(any(SwitchIdleEvent.class)) ; + } + + /** + * Test channel read timeout + */ + @Test + public void testReadTimedOut() { + try { + idleHandler.readTimedOut( mockChHndlrCtx ); + } catch (Exception e) { + Assert.fail(); + } + + // Verify a read was fired for the next handler to process ... + verify(mockChHndlrCtx, times(1)).fireChannelRead(any(SwitchIdleEvent.class)) ; + } + + /** + * Test only one timeout notification + */ + @Test + public void testReadTimedOutNoOpNotFirst() { + try { + idleHandler.readTimedOut(mockChHndlrCtx); + idleHandler.readTimedOut(mockChHndlrCtx); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that only one notification was sent to the next handler ... + verify(mockChHndlrCtx, times(1)).fireChannelRead(any(Object.class)) ; + } + + /** + * Test two timeout notifications + */ + @Test + public void testReadTimedOutTwice() { + try { + idleHandler.readTimedOut(mockChHndlrCtx); + verify(mockChHndlrCtx, times(1)).fireChannelRead(any(Object.class)) ; + + idleHandler.channelRead(mockChHndlrCtx, new String() ); + verify(mockChHndlrCtx, times(2)).fireChannelRead(any(Object.class)) ; + + idleHandler.readTimedOut(mockChHndlrCtx); + verify(mockChHndlrCtx, times(3)).fireChannelRead(any(Object.class)) ; + } catch (Exception e) { + Assert.fail(); + } + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoderTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoderTest.java new file mode 100644 index 0000000000..683a89abf8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketDecoderTest.java @@ -0,0 +1,53 @@ +/* + * 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.impl.core; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +import java.net.InetSocketAddress; + +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.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; + +/** + * @author madamjak + * + */ +public class OFDatagramPacketDecoderTest { + @Mock DeserializationFactory deserializationFactory; + @Mock ChannelHandlerContext ctx; + @Mock ByteBuf messageBufferMock; + + private VersionMessageUdpWrapper msgWrapper; + + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + } + + @Test + public void test() { + OFDatagramPacketDecoder decoder = new OFDatagramPacketDecoder(); + decoder.setDeserializationFactory(deserializationFactory); + msgWrapper = new VersionMessageUdpWrapper(EncodeConstants.OF13_VERSION_ID, messageBufferMock, new InetSocketAddress("10.0.0.1", 6653)); + try { + decoder.channelRead0(ctx, msgWrapper); + } catch (Exception e) { + Assert.fail("Exception occured"); + } + verify(messageBufferMock, times(1)).release(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoderTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoderTest.java new file mode 100644 index 0000000000..7ab8bfcc75 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketEncoderTest.java @@ -0,0 +1,88 @@ +/* + * 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.impl.core; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.core.connection.UdpMessageListenerWrapper; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class OFDatagramPacketEncoderTest { + + @Mock ChannelHandlerContext ctx; + @Mock GenericFutureListener> listener; + @Mock SerializationFactory factory; + + private UdpMessageListenerWrapper wrapper; + private InetSocketAddress address = new InetSocketAddress("10.0.0.1", 6653); + private List out; + + /** + * Initializes mocks and other objects + * @param version openflow protocol wire version + */ + public void startUp(Short version) { + MockitoAnnotations.initMocks(this); + out = new ArrayList<>(); + HelloInputBuilder builder = new HelloInputBuilder(); + builder.setVersion(version); + HelloInput hello = builder.build(); + wrapper = new UdpMessageListenerWrapper(hello, listener, address); + } + + /** + * Tests encoding + */ + @Test + public void testCorrectEncode() { + startUp((short) EncodeConstants.OF13_VERSION_ID); + OFDatagramPacketEncoder encoder = new OFDatagramPacketEncoder(); + encoder.setSerializationFactory(factory); + try { + encoder.encode(ctx, wrapper, out); + } catch (Exception e) { + Assert.fail(); + } + } + + /** + * Tests encoding + */ + @Test + public void testIncorrectEncode() { + startUp(null); + OFDatagramPacketEncoder encoder = new OFDatagramPacketEncoder(); + encoder.setSerializationFactory(factory); + try { + encoder.encode(ctx, wrapper, out); + } catch (Exception e) { + verify(wrapper, times(1)).getListener(); + Assert.assertEquals("List should be empty", 0, out.size()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandlerTest.java new file mode 100644 index 0000000000..a3f5befc84 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDatagramPacketHandlerTest.java @@ -0,0 +1,70 @@ +/* + * 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.impl.core; + +import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; + +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; + +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.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageConsumer; +import org.opendaylight.openflowjava.util.ByteBufUtils; + +/** + * @author madamjak + * + */ +public class OFDatagramPacketHandlerTest { + @Mock ChannelHandlerContext ctxMock; + @Mock SwitchConnectionHandler switchConnHandler; + @Mock MessageConsumer consumerMock; + @Mock Channel channelMock; + + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + when(ctxMock.channel()).thenReturn(channelMock); + } + + /** + * Test {@link OFDatagramPacketHandler} + */ + @Test + public void test(){ + OFDatagramPacketHandler handler = new OFDatagramPacketHandler(switchConnHandler); + byte version = EncodeConstants.OF13_VERSION_ID; + ByteBuf messageBuffer = ByteBufUtils.hexStringToByteBuf("04 02 00 08 01 02 03 04"); + InetSocketAddress recipientISA = InetSocketAddress.createUnresolved("localhost", 9876); + InetSocketAddress senderISA = InetSocketAddress.createUnresolved("192.168.15.24", 21021); + DatagramPacket datagramPacket = new DatagramPacket(messageBuffer, recipientISA, senderISA); + UdpConnectionMap.addConnection(datagramPacket.sender(), consumerMock); + List outList = new ArrayList<>(); + try { + handler.decode(ctxMock, datagramPacket, outList); + } catch (Exception e) { + Assert.fail("Wrong - Unexcepted exception occurred"); + } + VersionMessageUdpWrapper versionUdpWrapper = (VersionMessageUdpWrapper) outList.get(0); + Assert.assertEquals("Wrong - incorrect version has been decoded",version, versionUdpWrapper.getVersion()); + Assert.assertEquals("Wrong - sender addresses are different", senderISA, versionUdpWrapper.getAddress()); + messageBuffer.readerIndex(1); + Assert.assertEquals("Wrong - undecoded part of input ByteBuff is differnt to output",0, messageBuffer.compareTo(versionUdpWrapper.getMessageBuffer())); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderStatisticsTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderStatisticsTest.java new file mode 100644 index 0000000000..409e475d46 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderStatisticsTest.java @@ -0,0 +1,141 @@ +/* + * 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.impl.core; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyShort; +import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +import java.util.ArrayList; +import java.util.List; + +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.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.statistics.CounterEventTypes; +import org.opendaylight.openflowjava.statistics.StatisticsCounters; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Test to count decoder events (counters US_DECODE_SUCCESS, US_DECODE_FAIL and + * US_RECEIVED_IN_OFJAVA have to be enabled) + * + * @author madamjak + * + */ +public class OFDecoderStatisticsTest { + + @Mock ChannelHandlerContext mockChHndlrCtx; + @Mock DeserializationFactory mockDeserializationFactory; + @Mock DataObject mockDataObject; + + private OFDecoder ofDecoder; + private ByteBuf writeObj; + private VersionMessageWrapper inMsg; + private List outList; + private StatisticsCounters statCounters; + + /** + * Sets up test environment Start counting and reset counters before each + * test + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + ofDecoder = new OFDecoder(); + ofDecoder.setDeserializationFactory(mockDeserializationFactory); + outList = new ArrayList<>(); + statCounters = StatisticsCounters.getInstance(); + statCounters.startCounting(false, 0); + } + + /** + * Stop counting after each test + */ + @After + public void tierDown() { + statCounters.stopCounting(); + } + + /** + * Test decode success counter + */ + @Test + public void testDecodeSuccesfullCounter() { + if (!statCounters.isCounterEnabled(CounterEventTypes.US_DECODE_SUCCESS)) { + Assert.fail("Counter " + CounterEventTypes.US_DECODE_SUCCESS + " is not enable"); + } + if (!statCounters.isCounterEnabled(CounterEventTypes.US_DECODE_FAIL)) { + Assert.fail("Counter " + CounterEventTypes.US_DECODE_FAIL + " is not enable"); + } + if (!statCounters + .isCounterEnabled(CounterEventTypes.US_RECEIVED_IN_OFJAVA)) { + Assert.fail("Counter " + CounterEventTypes.US_RECEIVED_IN_OFJAVA + " is not enable"); + } + int count = 4; + when(mockDeserializationFactory.deserialize(any(ByteBuf.class),anyShort())).thenReturn(mockDataObject); + try { + for (int i = 0; i < count; i++) { + writeObj = ByteBufUtils.hexStringToByteBuf("16 03 01 00"); + inMsg = new VersionMessageWrapper((short) 8, writeObj); + ofDecoder.decode(mockChHndlrCtx, inMsg, outList); + } + } catch (Exception e) { + Assert.fail(); + } + Assert.assertEquals("Wrong - bad counter value for OFEncoder encode succesfully ", + count,statCounters.getCounter(CounterEventTypes.US_DECODE_SUCCESS).getCounterValue()); + Assert.assertEquals( + "Wrong - different between RECEIVED_IN_OFJAVA and (US_DECODE_SUCCESS + US_DECODE_FAIL)", + statCounters.getCounter(CounterEventTypes.US_RECEIVED_IN_OFJAVA).getCounterValue(), + statCounters.getCounter(CounterEventTypes.US_DECODE_SUCCESS).getCounterValue() + + statCounters.getCounter(CounterEventTypes.US_DECODE_FAIL).getCounterValue()); + } + + /** + * Test fail decode counter + */ + @Test + public void testDecodeFailCounter() { + if (!statCounters.isCounterEnabled(CounterEventTypes.US_DECODE_SUCCESS)) { + Assert.fail("Counter " + CounterEventTypes.US_DECODE_SUCCESS + " is not enable"); + } + if (!statCounters.isCounterEnabled(CounterEventTypes.US_DECODE_FAIL)) { + Assert.fail("Counter " + CounterEventTypes.US_DECODE_FAIL + " is not enable"); + } + if (!statCounters.isCounterEnabled(CounterEventTypes.US_RECEIVED_IN_OFJAVA)) { + Assert.fail("Counter " + CounterEventTypes.US_RECEIVED_IN_OFJAVA + " is not enable"); + } + int count = 2; + when( mockDeserializationFactory.deserialize(any(ByteBuf.class),anyShort())).thenThrow(new IllegalArgumentException()); + try { + for (int i = 0; i < count; i++) { + writeObj = ByteBufUtils.hexStringToByteBuf("16 03 01 00"); + inMsg = new VersionMessageWrapper((short) 8, writeObj); + ofDecoder.decode(mockChHndlrCtx, inMsg, outList); + } + } catch (Exception e) { + Assert.fail(); + } + Assert.assertEquals( + "Wrong - bad counter value for OFEncoder encode succesfully ", + count, statCounters.getCounter(CounterEventTypes.US_DECODE_FAIL).getCounterValue()); + Assert.assertEquals( + "Wrong - different between RECEIVED_IN_OFJAVA and (US_DECODE_SUCCESS + US_DECODE_FAIL)", + statCounters.getCounter(CounterEventTypes.US_RECEIVED_IN_OFJAVA).getCounterValue(), + statCounters.getCounter(CounterEventTypes.US_DECODE_SUCCESS).getCounterValue() + + statCounters.getCounter(CounterEventTypes.US_DECODE_FAIL).getCounterValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderTest.java new file mode 100644 index 0000000000..917f9b920f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFDecoderTest.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyShort; +import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +import java.util.ArrayList; +import java.util.List; + +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.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * + * @author jameshall + */ +public class OFDecoderTest { + + @Mock ChannelHandlerContext mockChHndlrCtx ; + @Mock DeserializationFactory mockDeserializationFactory ; + @Mock DataObject mockDataObject ; + + OFDecoder ofDecoder ; + private ByteBuf writeObj; + private VersionMessageWrapper inMsg; + private List outList; + + /** + * Sets up test environment + * + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + ofDecoder = new OFDecoder() ; + ofDecoder.setDeserializationFactory( mockDeserializationFactory ) ; + writeObj = ByteBufUtils.hexStringToByteBuf("16 03 01 00"); + inMsg = new VersionMessageWrapper( (short)8, writeObj ); + outList = new ArrayList<>(); + } + + /** + * + */ + @Test + public void testDecode() { + when(mockDeserializationFactory.deserialize( any(ByteBuf.class), anyShort() )).thenReturn(mockDataObject); + try { + ofDecoder.decode(mockChHndlrCtx, inMsg, outList); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the message buf was released... + assertEquals( mockDataObject, outList.get(0) ) ; + assertEquals( 0, writeObj.refCnt() ) ; + } + + /** + * + */ + @Test + public void testDecodeDeserializeException() { + when(mockDeserializationFactory.deserialize( any(ByteBuf.class), anyShort() )) + .thenThrow(new IllegalArgumentException()) ; + + try { + ofDecoder.decode(mockChHndlrCtx, inMsg, outList); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the message buf was released... + assertEquals( 0, outList.size() ) ; + assertEquals( 0, writeObj.refCnt() ) ; + } + + /** + * + */ + @Test + public void testDecodeDeserializeNull() { + when(mockDeserializationFactory.deserialize( any(ByteBuf.class), anyShort() )) + .thenReturn(null) ; + + try { + ofDecoder.decode(mockChHndlrCtx, inMsg, outList); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the message buf was released... + assertEquals( 0, outList.size() ) ; + assertEquals( 0, writeObj.refCnt() ) ; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderStatisticsTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderStatisticsTest.java new file mode 100644 index 0000000000..cfafe99450 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderStatisticsTest.java @@ -0,0 +1,142 @@ +/* + * 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.impl.core; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyShort; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +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.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +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.yangtools.yang.binding.DataObject; + +/** + * Test counters for encoding (at least DS_ENCODE_SUCCESS, DS_ENCODE_FAIL and DS_FLOW_MODS_SENT counters have to be enabled) + * @author madamjak + * + */ +public class OFEncoderStatisticsTest { + + @Mock ChannelHandlerContext mockChHndlrCtx ; + @Mock SerializationFactory mockSerializationFactory ; + @Mock MessageListenerWrapper wrapper; + @Mock OfHeader mockMsg ; + @Mock ByteBuf mockOut ; + @Mock Future future; + @Mock GenericFutureListener> listener; + @Mock FlowModInput mockFlowModInput; + + private StatisticsCounters statCounters; + private OFEncoder ofEncoder; + + /** + * Initialize tests, start and reset counters before each test + */ + @Before + public void initTlest(){ + MockitoAnnotations.initMocks(this); + ofEncoder = new OFEncoder() ; + ofEncoder.setSerializationFactory(mockSerializationFactory) ; + statCounters = StatisticsCounters.getInstance(); + statCounters.startCounting(false, 0); + } + + /** + * Stop counting after each test + */ + @After + public void tierDown(){ + statCounters.stopCounting(); + } + + /** + * Test counting of success encode (counter DS_ENCODE_SUCCESS has to be enabled) + */ + @Test + public void testEncodeSuccessCounter() { + CounterEventTypes cet = CounterEventTypes.DS_ENCODE_SUCCESS; + if(! statCounters.isCounterEnabled(cet)){ + Assert.fail("Counter " + cet + " is not enabled."); + } + int count = 4; + when(mockOut.readableBytes()).thenReturn(1); + when(wrapper.getMsg()).thenReturn(mockMsg); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + try { + for(int i = 0; i< count; i++){ + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } + } catch (Exception e) { + Assert.fail(); + } + Assert.assertEquals("Wrong - bad counter value for OFEncoder encode succesfully ", count, statCounters.getCounter(cet).getCounterValue()); + } + + /** + * Test counting of flow-mod sent (counter DS_FLOW_MODS_SENT has to be enabled) + */ + @Test + public void testFlowModSentCounter() { + CounterEventTypes cet = CounterEventTypes.DS_FLOW_MODS_SENT; + if(! statCounters.isCounterEnabled(cet)){ + Assert.fail("Counter " + cet + " is not enabled."); + } + int count = 4; + when(mockOut.readableBytes()).thenReturn(1); + when(wrapper.getMsg()).thenReturn(mockFlowModInput); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + try { + for(int i = 0; i< count; i++){ + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } + } catch (Exception e) { + Assert.fail(); + } + Assert.assertEquals("Wrong - bad counter value for OFEncoder flow-mod sent", count, statCounters.getCounter(cet).getCounterValue()); + } + /** + * Test counting of encode fail (counter DS_ENCODE_FAIL has to be enabled) + */ + + @Test + public void testEncodeEncodeFailCounter() { + CounterEventTypes cet = CounterEventTypes.DS_ENCODE_FAIL; + if(! statCounters.isCounterEnabled(cet)){ + Assert.fail("Counter " + cet + " is not enabled."); + } + int count = 2; + when(wrapper.getMsg()).thenReturn(mockMsg); + when(wrapper.getListener()).thenReturn(listener); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + doThrow(new IllegalArgumentException()).when(mockSerializationFactory).messageToBuffer(anyShort(),any(ByteBuf.class), any(DataObject.class)); + try { + for(int i = 0; i< count; i++){ + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } + } catch (Exception e) { + Assert.fail(); + } + Assert.assertEquals("Wrong - bad counter value for OFEncoder fail encode", count, statCounters.getCounter(cet).getCounterValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderTest.java new file mode 100644 index 0000000000..e05fbd9876 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFEncoderTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 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 static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyShort; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +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.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * + * @author jameshall + */ +public class OFEncoderTest { + + @Mock ChannelHandlerContext mockChHndlrCtx ; + @Mock SerializationFactory mockSerializationFactory ; + @Mock MessageListenerWrapper wrapper; + @Mock OfHeader mockMsg ; + @Mock ByteBuf mockOut ; + @Mock Future future; + @Mock GenericFutureListener> listener; + + OFEncoder ofEncoder = new OFEncoder() ; + + /** + * Sets up test environment + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + ofEncoder = new OFEncoder() ; + ofEncoder.setSerializationFactory( mockSerializationFactory ) ; + } + + /** + * Test successful write (no clear) + */ + @Test + public void testEncodeSuccess() { + when(mockOut.readableBytes()).thenReturn(1); + when(wrapper.getMsg()).thenReturn(mockMsg); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + try { + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the channel was flushed after the ByteBuf was retained. + verify(mockOut, times(0)).clear(); + } + + /** + * Test Bytebuf clearing after serialization failure + */ + @Test + public void testEncodeSerializationException() { + when(wrapper.getMsg()).thenReturn(mockMsg); + when(wrapper.getListener()).thenReturn(listener); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + doThrow(new IllegalArgumentException()).when(mockSerializationFactory).messageToBuffer(anyShort(),any(ByteBuf.class), any(DataObject.class)); + try { + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the output message buf was cleared... + verify(mockOut, times(1)).clear(); + } + + /** + * Test no action on empty bytebuf + */ + @Test + public void testEncodeSerializesNoBytes() { + when(mockOut.readableBytes()).thenReturn(0); + when(wrapper.getMsg()).thenReturn(mockMsg); + when(wrapper.getMsg().getVersion()).thenReturn((short) EncodeConstants.OF13_VERSION_ID); + try { + ofEncoder.encode(mockChHndlrCtx, wrapper, mockOut); + } catch (Exception e) { + Assert.fail(); + } + + // Verify that the output message buf was cleared... + verify(mockOut, times(0)).clear(); + verify(mockChHndlrCtx, times(0)).writeAndFlush(mockOut); + verify(mockOut, times(0)).retain(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoderTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoderTest.java new file mode 100644 index 0000000000..41d692c820 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFFrameDecoderTest.java @@ -0,0 +1,167 @@ +/* + * 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.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 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.impl.core.connection.ConnectionFacade; +import org.opendaylight.openflowjava.util.ByteBufUtils; + +/** + * Testing class of {@link OFFrameDecoder} + * + * @author michal.polkorab + */ +@RunWith(MockitoJUnitRunner.class) +public class OFFrameDecoderTest { + + @Mock + ChannelHandlerContext channelHandlerContext; + + @Mock + ConnectionFacade connectionFacade; + private OFFrameDecoder decoder; + private List list = new ArrayList<>(); + + /** + * Sets up tests + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + decoder = new OFFrameDecoder(connectionFacade, false); + list.clear(); + + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecode8BMessage() { + try { + decoder.decode(channelHandlerContext, + ByteBufUtils.hexStringToByteBuf("04 00 00 08 00 00 00 01"), + list); + } catch (Exception e) { + Assert.fail(); + } + + assertEquals(8, ((ByteBuf) list.get(0)).readableBytes()); + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecode16BMessage() { + ByteBuf byteBuffer = ByteBufUtils + .hexStringToByteBuf("04 00 00 10 00 00 00 00 00 00 00 00 00 00 00 42"); + try { + decoder.decode(channelHandlerContext, byteBuffer, list); + } catch (Exception e) { + Assert.fail(); + } + + assertEquals(16, ((ByteBuf) list.get(0)).readableBytes()); + assertEquals(0, byteBuffer.readableBytes()); + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecode5BIncompleteMessage() { + ByteBuf byteBuffer = ByteBufUtils.hexStringToByteBuf("04 00 00 08 00"); + try { + decoder.decode(channelHandlerContext, byteBuffer, list); + } catch (Exception e) { + Assert.fail(); + } + + Assert.assertEquals("List is not empty", 0, list.size()); + assertEquals(5, byteBuffer.readableBytes()); + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecode16BIncompleteMessage() { + ByteBuf byteBuffer = ByteBufUtils + .hexStringToByteBuf("04 00 00 11 00 00 00 00 00 00 00 00 00 00 00 42"); + try { + decoder.decode(channelHandlerContext, byteBuffer, list); + } catch (Exception e) { + Assert.fail(); + } + + Assert.assertEquals("List is not empty", 0, list.size()); + assertEquals(16, byteBuffer.readableBytes()); + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecodeCompleteAndPartialMessage() { + ByteBuf byteBuffer = ByteBufUtils + .hexStringToByteBuf("04 00 00 08 00 00 00 01 04 00 00 08 00"); + try { + decoder.decode(channelHandlerContext, byteBuffer, list); + } catch (Exception e) { + Assert.fail(); + } + + Assert.assertEquals(8, ((ByteBuf) list.get(0)).readableBytes()); + Assert.assertEquals(1, list.size()); + assertEquals(5, byteBuffer.readableBytes()); + + } + + @Test + public void testExceptionCaught() throws Exception { + decoder.exceptionCaught(channelHandlerContext, new Throwable()); + } + + /** + * Test of decoding + * {@link OFFrameDecoder#decode(io.netty.channel.ChannelHandlerContext, io.netty.buffer.ByteBuf, java.util.List)} + */ + @Test + public void testDecode8BMessageWithTls() { + decoder = new OFFrameDecoder(connectionFacade, true); + try { + decoder.decode(channelHandlerContext, + ByteBufUtils.hexStringToByteBuf("04 00 00 08 00 00 00 01"), + list); + } catch (Exception e) { + Assert.fail(); + } + + assertEquals(8, ((ByteBuf) list.get(0)).readableBytes()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java new file mode 100644 index 0000000000..7b3d814a59 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/OFVersionDetectorTest.java @@ -0,0 +1,73 @@ +/* + * 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.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 org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.util.ByteBufUtils; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.core.OFVersionDetector}. + */ +@RunWith(MockitoJUnitRunner.class) +public class OFVersionDetectorTest { + + @Mock + ChannelHandlerContext channelHandlerContext; + + private OFVersionDetector detector; + private List list = new ArrayList<>(); + + @Before + public void setUp() { + list.clear(); + detector = new OFVersionDetector(); + } + + @Test + 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 + 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 + 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()); + } + + @Test + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java new file mode 100644 index 0000000000..486972401b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerFactoryTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertNotNull; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +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 + */ +public class PublishingChannelInitializerFactoryTest { + + TlsConfiguration tlsConfiguration ; + ChannelInitializerFactory factory; + private final long switchIdleTimeOut = 60; + @Mock SwitchConnectionHandler switchConnectionHandler ; + @Mock SerializationFactory serializationFactory; + @Mock DeserializationFactory deserializationFactory ; + + /** + * Sets up test environment + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + factory = new ChannelInitializerFactory(); + tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore", + 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); + factory.setSwitchIdleTimeout(switchIdleTimeOut); + factory.setTlsConfig(tlsConfiguration); + } + + /** + * Test {@link TcpChannelInitializer} creation + */ + @Test + public void testCreatePublishingChannelInitializer() { + TcpChannelInitializer initializer = factory.createPublishingChannelInitializer() ; + assertNotNull( initializer ); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java new file mode 100644 index 0000000000..b855cc917e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/PublishingChannelInitializerTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelPipeline; +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; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterFactory; +import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionFacade; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; +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 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 + */ +public class PublishingChannelInitializerTest { + + @Mock SocketChannel mockSocketCh ; + @Mock ChannelPipeline mockChPipeline ; + @Mock SwitchConnectionHandler mockSwConnHandler ; + @Mock ConnectionAdapterFactory mockConnAdaptorFactory; + @Mock DefaultChannelGroup mockChGrp ; + @Mock ConnectionFacade mockConnFacade ; + @Mock Tls mockTls ; + SSLEngine sslEngine ; + + @Mock SerializationFactory mockSerializationFactory ; + @Mock DeserializationFactory mockDeserializationFactory ; + + TlsConfiguration tlsConfiguration ; + InetSocketAddress inetSockAddr; + TcpChannelInitializer pubChInitializer ; + + /** + * Sets up test environment + * @throws Exception + */ + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + pubChInitializer= new TcpChannelInitializer(mockChGrp, mockConnAdaptorFactory) ; + pubChInitializer.setSerializationFactory(mockSerializationFactory); + 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, true)) + .thenReturn(mockConnFacade); + when(mockSocketCh.remoteAddress()).thenReturn(inetSockAddr) ; + when(mockSocketCh.localAddress()).thenReturn(inetSockAddr) ; + when(mockSocketCh.remoteAddress()).thenReturn(inetSockAddr) ; + when(mockSwConnHandler.accept(eq(InetAddress.getLocalHost()))).thenReturn(true) ; + when(mockSocketCh.pipeline()).thenReturn(mockChPipeline) ; + + tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/selfSignedSwitch", PathType.CLASSPATH, + KeystoreType.JKS, "/selfSignedController", PathType.CLASSPATH, + Lists.newArrayList("TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA256")); + } + + + /** + * Test channel initialization with encryption config set + */ + @Test + public void testinitChannelEncryptionSet() { + pubChInitializer.setTlsConfiguration(tlsConfiguration); + pubChInitializer.initChannel(mockSocketCh) ; + + verifyCommonHandlers(); + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.SSL_HANDLER.name()),any(SslHandler.class)) ; + } + + /** + * Test channel initialization with null encryption config + */ + @Test + public void testinitChannelEncryptionSetNullTls() { + pubChInitializer.setTlsConfiguration(null); + pubChInitializer.initChannel(mockSocketCh) ; + + verifyCommonHandlers(); + verify(mockChPipeline, times(0)).addLast(eq(PipelineHandlers.SSL_HANDLER.name()),any(SslHandler.class)) ; + } + + /** + * Test channel initialization without setting the encryption + */ + @Test + public void testinitChannelEncryptionNotSet() { + // Without encryption, only the common + pubChInitializer.initChannel(mockSocketCh) ; + + verifyCommonHandlers(); + } + + /** + * Test disconnect on new connection rejected + * @throws UnknownHostException + */ + @Test + public void testinitChannelNoEncryptionAcceptFails() throws UnknownHostException { + when(mockSwConnHandler.accept(eq(InetAddress.getLocalHost()))).thenReturn(false) ; + pubChInitializer.initChannel(mockSocketCh) ; + + verify(mockSocketCh, times(1)).disconnect(); + verify(mockChPipeline, times(0)) + .addLast( any(String.class), any(ChannelHandler.class) ) ; + } + + /** + * Test channel close on exception during initialization + */ + @Test + public void testExceptionThrown() { + doThrow(new IllegalArgumentException()).when(mockSocketCh).pipeline() ; + pubChInitializer.initChannel(mockSocketCh); + + verify( mockSocketCh, times(1)).close() ; + } + + /** + * All paths should install these six handlers: + */ + private void verifyCommonHandlers() { + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.IDLE_HANDLER.name()),any(IdleHandler.class)) ; + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.OF_DECODER.name()),any(OFDecoder.class)) ; + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.OF_ENCODER.name()),any(OFEncoder.class)) ; + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.OF_FRAME_DECODER.name()),any(OFFrameDecoder.class)) ; + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.OF_VERSION_DETECTOR.name()),any(OFVersionDetector.class)) ; + verify(mockChPipeline, times(1)).addLast(eq(PipelineHandlers.DELEGATING_INBOUND_HANDLER.name()),any(DelegatingInboundHandler.class)); + assertEquals(1, pubChInitializer.size()) ; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java new file mode 100644 index 0000000000..862e0ca56e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslContextFactoryTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertNotNull; + +import javax.net.ssl.SSLContext; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +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 + */ +public class SslContextFactoryTest { + + SslContextFactory sslContextFactory; + TlsConfiguration tlsConfiguration ; + + /** + * Sets up test environment + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + tlsConfiguration = new TlsConfigurationImpl(KeystoreType.JKS, "/exemplary-ctlTrustStore", + 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); + } + + /** + * @throws Exception + */ + @Test + public void testGetServerContext() throws Exception { + SSLContext context = sslContextFactory.getServerContext() ; + + assertNotNull( context ); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStoreTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStoreTest.java new file mode 100644 index 0000000000..c2a13df8a1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/SslKeyStoreTest.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertNotNull; + +import java.io.InputStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; + +/** + * + * @author jameshall + */ +public class SslKeyStoreTest { + + /** + * Sets up test environment + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + /** + * Test keystore file access - via classpath + * @throws Exception + */ + @Test + public void testAsInputStream() throws Exception { + InputStream inputStream = SslKeyStore.asInputStream("/key.bin", PathType.CLASSPATH); + assertNotNull( inputStream ); + inputStream.close(); + } + + /** + * Test keystore file access - via relative path + * @throws Exception + */ + @Test + public void testAsInputStream2() throws Exception { + InputStream inputStream = SslKeyStore.asInputStream("src/test/resources/key.bin", PathType.PATH); + assertNotNull( inputStream ); + inputStream.close(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java new file mode 100644 index 0000000000..6faad908f0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2014 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 static org.junit.Assert.assertEquals; +import io.netty.channel.ChannelHandlerContext; + +import java.io.IOException; +import java.net.BindException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +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; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * + * @author jameshall + */ +public class TcpHandlerTest { + + private InetAddress serverAddress = InetAddress.getLoopbackAddress() ; + @Mock ChannelHandlerContext mockChHndlrCtx ; + @Mock TcpChannelInitializer mockChannelInitializer; + @Mock SwitchConnectionHandler mockSwitchConnHndler ; + @Mock SerializationFactory mockSerializationFactory ; + @Mock DeserializationFactory mockDeserializationFactory ; + + TcpHandler tcpHandler ; + + /** + * Initialize mocks + */ + public TcpHandlerTest() { + MockitoAnnotations.initMocks(this); + } + + /** + * Test run with null address set + * @throws IOException + * @throws InterruptedException + * @throws ExecutionException + */ + @Test + public void testRunWithNullAddress() throws IOException, InterruptedException, ExecutionException { + + tcpHandler = new TcpHandler(null, 0); + tcpHandler.setChannelInitializer(mockChannelInitializer); + + 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(); + } + + /** + * Test run with address set + * @throws IOException + * @throws InterruptedException + * @throws ExecutionException + */ + @Test + public void testRunWithAddress() throws IOException, InterruptedException, ExecutionException { + + tcpHandler = new TcpHandler(serverAddress, 0); + tcpHandler.setChannelInitializer(mockChannelInitializer); + + 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 + * @throws IOException + * @throws ExecutionException + */ + @Test + 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(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())); + + 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(); + } + + /** + * Test run on already used port + * @throws IOException + */ + @Test + public void testSocketAlreadyInUse() 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); + tcpHandler.initiateEventLoopGroups(null, false); + tcpHandler.run(); + } catch (Exception e) { + if (e instanceof BindException) { + exceptionThrown = true; + } + } + firstBinder.close(); + 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 + */ + private void shutdownServer() throws InterruptedException, ExecutionException { + ListenableFuture shutdownRet = tcpHandler.shutdown() ; + while ( shutdownRet.isDone() != true ) + Thread.sleep(100) ; + assertEquals("shutdown failed", true, shutdownRet.get()); + } + + /** + * @throws InterruptedException + * @throws IOException + * @throws ExecutionException + */ + private Boolean startupServer(boolean isEpollEnabled) throws InterruptedException, IOException, ExecutionException { + ListenableFuture online = tcpHandler.getIsOnlineFuture(); + /** + * 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) { + Thread.sleep(100); + } + return online.isDone() ; + } + /** + * @throws IOException + */ + private static Boolean clientConnection(int port) throws IOException { + // Connect, and disconnect + Socket socket = new Socket(InetAddress.getLoopbackAddress(), port ); + Boolean result = socket.isConnected(); + socket.close() ; + return result ; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMapTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMapTest.java new file mode 100644 index 0000000000..624aef0882 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/UdpConnectionMapTest.java @@ -0,0 +1,75 @@ +/* + * 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.impl.core; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.socket.DatagramPacket; + +import java.net.InetSocketAddress; + +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.MessageConsumer; + +/** + * @author madamjak + * + */ +public class UdpConnectionMapTest { + + @Mock MessageConsumer consumerMock; + @Mock ByteBuf messageBuffer; + + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + } + + /** + * Test {@link UdpConnectionMap} - sender address is not null + */ + @Test + public void testWithSenderAddress(){ + InetSocketAddress recipientISA = InetSocketAddress.createUnresolved("localhost", 9876); + InetSocketAddress senderISA = InetSocketAddress.createUnresolved("192.168.15.2", 21021); + DatagramPacket datagramPacket = new DatagramPacket(messageBuffer, recipientISA, senderISA); + UdpConnectionMap.addConnection(datagramPacket.sender(), consumerMock); + Assert.assertEquals("Wrong - different object has been returned", + consumerMock, UdpConnectionMap.getMessageConsumer(datagramPacket.sender())); + UdpConnectionMap.removeConnection(datagramPacket.sender()); + Assert.assertNull("Wrong - object has been returned after remove key-value pair", + UdpConnectionMap.getMessageConsumer(datagramPacket.sender())); + } + + /** + * Test {@link UdpConnectionMap} - sender address is null to add connection + */ + @Test(expected = IllegalArgumentException.class) + public void testWithoutSenderAddressOnAdd(){ + UdpConnectionMap.addConnection(null, consumerMock); + } + + /** + * Test {@link UdpConnectionMap} - sender address is not null to get message consumer + */ + @Test(expected = IllegalArgumentException.class) + public void testWithoutSenderAddressOnGet(){ + UdpConnectionMap.getMessageConsumer(null); + } + + /** + * Test {@link UdpConnectionMap} - sender address is not null to remove connection + */ + @Test(expected = IllegalArgumentException.class) + public void testWithoutSenderAddressOnRemove(){ + UdpConnectionMap.removeConnection(null); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapperTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapperTest.java new file mode 100644 index 0000000000..be61603037 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/VersionMessageUdpWrapperTest.java @@ -0,0 +1,45 @@ +/* + * 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.impl.core; + +import io.netty.buffer.ByteBuf; +import java.net.InetSocketAddress; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * + * @author madamjak + * + */ + +public class VersionMessageUdpWrapperTest { + + @Mock ByteBuf byteBuff; + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + } + + @Test + public void test(){ + short version = 35; + int port = 9876; + String host ="localhost"; + InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); + VersionMessageUdpWrapper wrapper = new VersionMessageUdpWrapper(version,byteBuff,inetSockAddr); + + Assert.assertEquals("Wrong getAddress", inetSockAddr, wrapper.getAddress()); + Assert.assertEquals("Wrong getVersion", version, wrapper.getVersion()); + Assert.assertEquals("Wrong getVersion", byteBuff, wrapper.getMessageBuffer()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java new file mode 100644 index 0000000000..5f080dc571 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueue02Test.java @@ -0,0 +1,160 @@ +/* + * 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.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.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; + +/** + * @author madamjak + * + */ +public class ChannelOutboundQueue02Test { + private static int counter; + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock EchoInput echoInput; + @Mock BarrierInput barrierInput; + @Mock EchoReplyInput echoReplyInput; + @Mock ExperimenterInput experimenterInput; + private ConnectionAdapterImpl adapter; + private Cache> cache; + /** + * Initialize mocks + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + /** + * Disconnect adapter after each test + */ + @After + public void tierDown(){ + if (adapter != null && adapter.isAlive()) { + adapter.disconnect(); + } + } + + /** + * Test write to closed / opened channel + * @throws Exception + */ + @Test + public void test01() throws Exception { + 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); + final ChannelOutboundQueue cq = (ChannelOutboundQueue) ec.pipeline().last(); + counter=0; + adapter.barrier(barrierInput); + adapter.echo(echoInput); + cq.channelInactive(ec.pipeline().lastContext()); + ec.runPendingTasks(); + Assert.assertEquals("Wrong - ChannelOutboundHandlerAdapter.write was invoked on closed channel",0, counter); + cq.channelActive(ec.pipeline().lastContext()); + counter=0; + adapter.barrier(barrierInput); + adapter.experimenter(experimenterInput); + ec.runPendingTasks(); + Assert.assertEquals("Wrong - ChannelOutboundHandlerAdapter.write has not been invoked on opened channel",2, counter); + } + + /** + * Test write to read only / writable channel + */ + @Test + public void test02(){ + 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); + ec.setReadOnly(); + counter=0; + adapter.barrier(barrierInput); + adapter.echo(echoInput); + ec.runPendingTasks(); + Assert.assertEquals("Wrong - write to readonly channel",0, counter); + ec.setWritable(); + adapter.echoReply(echoReplyInput); + adapter.echo(echoInput); + ec.runPendingTasks(); + Assert.assertEquals("Wrong - write to writtable channel",4, counter); + } + + /** + * Channel Handler for testing + * @author madamjak + * + */ + private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { + @Override + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { + if(msg instanceof MessageListenerWrapper){ + counter++; + } + } + } + + /** + * Class for testing - channel can change state to read only or writable + * @author madamjak + * + */ + private class ChangeWritableEmbededChannel extends EmbeddedChannel { + private boolean isWrittable; + public ChangeWritableEmbededChannel(final ChannelHandler channelHandler){ + super(channelHandler); + setReadOnly(); + } + + @Override + public boolean isWritable() { + return isWrittable; + } + + public void setWritable(){ + isWrittable = true; + } + + public void setReadOnly(){ + isWrittable = false; + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueueTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueueTest.java new file mode 100644 index 0000000000..0b001d9b3c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ChannelOutboundQueueTest.java @@ -0,0 +1,55 @@ +/* + * 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.impl.core.connection; + +import io.netty.channel.Channel; + +import org.junit.Assert; +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.SimpleRpcListener; + +/** + * @author michal.polkorab + * + */ +public class ChannelOutboundQueueTest { + + @Mock Channel channel; + + /** + * Initialize mocks + */ + public ChannelOutboundQueueTest() { + MockitoAnnotations.initMocks(this); + } + + /** + * Test incorrect queue creation handling + */ + @Test(expected=IllegalArgumentException.class) + public void testIncorrectQueueCreation() { + new ChannelOutboundQueue(channel, 0, null); + } + + /** + * Test correct enqueue handling + */ + @Test + public void testEnqueue() { + ChannelOutboundQueue queue = new ChannelOutboundQueue(channel, 1, null); + boolean enqueued; + enqueued = queue.enqueue(new SimpleRpcListener("INPUT", "Failed to send INPUT")); + Assert.assertTrue("Enqueue problem", enqueued); + enqueued = queue.enqueue(new SimpleRpcListener("INPUT", "Failed to send INPUT")); + Assert.assertFalse("Enqueue problem", enqueued); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java new file mode 100644 index 0000000000..e3317e32a7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterFactoryImplTest.java @@ -0,0 +1,43 @@ +/* + * 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.impl.core.connection; + +import static org.mockito.Mockito.when; +import io.netty.channel.Channel; +import io.netty.channel.ChannelPipeline; +import java.net.InetSocketAddress; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +/** + * + * @author madamjak + * + */ +public class ConnectionAdapterFactoryImplTest { + + @Mock ChannelPipeline channnelPipe; + @Mock Channel channel; + @Mock InetSocketAddress address; + + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + when(channel.pipeline()).thenReturn(channnelPipe); + } + + @Test + public void test(){ + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java new file mode 100644 index 0000000000..0909547cb5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImp02lTest.java @@ -0,0 +1,206 @@ +/* + * 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.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.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 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.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.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; + +/** + * @author madamjak + * @author michal.polkorab + */ +public class ConnectionAdapterImp02lTest { + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock EchoInput echoInput; + @Mock BarrierInput barrierInput; + @Mock EchoReplyInput echoReplyInput; + @Mock ExperimenterInput experimenterInput; + @Mock FlowModInput flowModInput; + @Mock GetConfigInput getConfigInput; + @Mock GetFeaturesInput getFeaturesInput; + @Mock GetQueueConfigInput getQueueConfigInput; + @Mock GroupModInput groupModInput; + @Mock HelloInput helloInput; + @Mock MeterModInput meterModInput; + @Mock PacketOutInput packetOutInput; + @Mock MultipartRequestInput multipartRequestInput; + @Mock PortModInput portModInput; + @Mock RoleRequestInput roleRequestInput; + @Mock SetConfigInput setConfigInput; + @Mock TableModInput tableModInput; + @Mock GetAsyncInput getAsyncInput; + @Mock SetAsyncInput setAsyncInput; + private ConnectionAdapterImpl adapter; + private Cache> cache; + private OfHeader responseOfCall; + /** + * Initialize mocks + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + /** + * Disconnect adapter + */ + @After + public void tierDown(){ + if (adapter != null && adapter.isAlive()) { + adapter.disconnect(); + } + } + /** + * Test Rpc Calls + */ + @Test + public void testRcp() { + 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); + // -- barrier + adapter.barrier(barrierInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - barrier", barrierInput, responseOfCall); + // -- echo + adapter.echo(echoInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - echo", echoInput, responseOfCall); + // -- echoReply + adapter.echoReply(echoReplyInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - echoReply",echoReplyInput, responseOfCall); + // -- experimenter + adapter.experimenter(experimenterInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - experimenter",experimenterInput, responseOfCall); + // -- flowMod + adapter.flowMod(flowModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - flowMod", flowModInput, responseOfCall); + // -- getConfig + adapter.getConfig(getConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getConfig", getConfigInput, responseOfCall); + // -- getFeatures + adapter.getFeatures(getFeaturesInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getFeatures",getFeaturesInput, responseOfCall); + // -- getQueueConfig + adapter.getQueueConfig(getQueueConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getQueueConfig",getQueueConfigInput, responseOfCall); + // -- groupMod + adapter.groupMod(groupModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - groupMod", groupModInput, responseOfCall); + // -- hello + adapter.hello(helloInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - helloInput",helloInput, responseOfCall); + // -- meterMod + adapter.meterMod(meterModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - meterMod",meterModInput, responseOfCall); + // -- packetOut + adapter.packetOut(packetOutInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - packetOut",packetOutInput, responseOfCall); + // -- multipartRequest + adapter.multipartRequest(multipartRequestInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - multipartRequest", multipartRequestInput, responseOfCall); + // -- portMod + adapter.portMod(portModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - portMod", portModInput, responseOfCall); + // -- roleRequest + adapter.roleRequest(roleRequestInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - roleRequest", roleRequestInput, responseOfCall); + // -- setConfig + adapter.setConfig(setConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - setConfig",setConfigInput, responseOfCall); + // -- tableMod + adapter.tableMod(tableModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - tableMod", tableModInput, responseOfCall); + // -- getAsync + adapter.getAsync(getAsyncInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getAsync", getAsyncInput, responseOfCall); + // -- setAsync + adapter.setAsync(setAsyncInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - setAsync", setAsyncInput, responseOfCall); + adapter.disconnect(); + } + + /** + * Channel Handler for testing + * @author madamjak + * + */ + private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { + @Override + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { + responseOfCall = null; + if(msg instanceof MessageListenerWrapper){ + final MessageListenerWrapper listener = (MessageListenerWrapper) msg; + final OfHeader ofHeader = listener.getMsg(); + responseOfCall = ofHeader; + } + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java new file mode 100644 index 0000000000..0786009553 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImpl02Test.java @@ -0,0 +1,206 @@ +/* + * 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.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.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 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.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.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; + +/** + * @author madamjak + * @author michal.polkorab + */ +public class ConnectionAdapterImpl02Test { + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock EchoInput echoInput; + @Mock BarrierInput barrierInput; + @Mock EchoReplyInput echoReplyInput; + @Mock ExperimenterInput experimenterInput; + @Mock FlowModInput flowModInput; + @Mock GetConfigInput getConfigInput; + @Mock GetFeaturesInput getFeaturesInput; + @Mock GetQueueConfigInput getQueueConfigInput; + @Mock GroupModInput groupModInput; + @Mock HelloInput helloInput; + @Mock MeterModInput meterModInput; + @Mock PacketOutInput packetOutInput; + @Mock MultipartRequestInput multipartRequestInput; + @Mock PortModInput portModInput; + @Mock RoleRequestInput roleRequestInput; + @Mock SetConfigInput setConfigInput; + @Mock TableModInput tableModInput; + @Mock GetAsyncInput getAsyncInput; + @Mock SetAsyncInput setAsyncInput; + private ConnectionAdapterImpl adapter; + private Cache> cache; + private OfHeader responseOfCall; + /** + * Initialize mocks + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + /** + * Disconnect adapter + */ + @After + public void tierDown(){ + if (adapter != null && adapter.isAlive()) { + adapter.disconnect(); + } + } + /** + * Test Rpc Calls + */ + @Test + public void testRcp() { + 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); + // -- barrier + adapter.barrier(barrierInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - barrier", barrierInput, responseOfCall); + // -- echo + adapter.echo(echoInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - echo", echoInput, responseOfCall); + // -- echoReply + adapter.echoReply(echoReplyInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - echoReply",echoReplyInput, responseOfCall); + // -- experimenter + adapter.experimenter(experimenterInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - experimenter",experimenterInput, responseOfCall); + // -- flowMod + adapter.flowMod(flowModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - flowMod", flowModInput, responseOfCall); + // -- getConfig + adapter.getConfig(getConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getConfig", getConfigInput, responseOfCall); + // -- getFeatures + adapter.getFeatures(getFeaturesInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getFeatures",getFeaturesInput, responseOfCall); + // -- getQueueConfig + adapter.getQueueConfig(getQueueConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getQueueConfig",getQueueConfigInput, responseOfCall); + // -- groupMod + adapter.groupMod(groupModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - groupMod", groupModInput, responseOfCall); + // -- hello + adapter.hello(helloInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - helloInput",helloInput, responseOfCall); + // -- meterMod + adapter.meterMod(meterModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - meterMod",meterModInput, responseOfCall); + // -- packetOut + adapter.packetOut(packetOutInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - packetOut",packetOutInput, responseOfCall); + // -- multipartRequest + adapter.multipartRequest(multipartRequestInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - multipartRequest", multipartRequestInput, responseOfCall); + // -- portMod + adapter.portMod(portModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - portMod", portModInput, responseOfCall); + // -- roleRequest + adapter.roleRequest(roleRequestInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - roleRequest", roleRequestInput, responseOfCall); + // -- setConfig + adapter.setConfig(setConfigInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - setConfig",setConfigInput, responseOfCall); + // -- tableMod + adapter.tableMod(tableModInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - tableMod", tableModInput, responseOfCall); + // -- getAsync + adapter.getAsync(getAsyncInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - getAsync", getAsyncInput, responseOfCall); + // -- setAsync + adapter.setAsync(setAsyncInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - setAsync", setAsyncInput, responseOfCall); + adapter.disconnect(); + } + + /** + * Channel Handler for testing + * @author madamjak + * + */ + private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { + @Override + public void write(final ChannelHandlerContext ctx, final Object msg, + final ChannelPromise promise) throws Exception { + responseOfCall = null; + if(msg instanceof MessageListenerWrapper){ + final MessageListenerWrapper listener = (MessageListenerWrapper) msg; + final OfHeader ofHeader = listener.getMsg(); + responseOfCall = ofHeader; + } + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java new file mode 100644 index 0000000000..706c624e7c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplStatisticsTest.java @@ -0,0 +1,239 @@ +/* + * 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.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; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; +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.EchoInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; +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.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder; +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.PortStatusMessageBuilder; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * Test counters in ConnectionAdapter (at least DS_ENTERED_OFJAVA, DS_FLOW_MODS_ENTERED and US_MESSAGE_PASS counters have to be enabled) + * @author madamjak + * + */ +public class ConnectionAdapterImplStatisticsTest { + + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock SystemNotificationsListener systemListener; + @Mock ConnectionReadyListener readyListener; + @Mock ChannelFuture channelFuture; + @Mock OpenflowProtocolListener messageListener; + @Mock SocketChannel channel; + @Mock ChannelPipeline pipeline; + @Mock EchoInput echoInput; + @Mock BarrierInput barrierInput; + @Mock EchoReplyInput echoReplyInput; + @Mock ExperimenterInput experimenterInput; + @Mock FlowModInput flowModInput; + @Mock GetConfigInput getConfigInput; + @Mock GetFeaturesInput getFeaturesInput; + @Mock GetQueueConfigInput getQueueConfigInput; + @Mock GroupModInput groupModInput; + @Mock HelloInput helloInput; + @Mock MeterModInput meterModInput; + @Mock PacketOutInput packetOutInput; + @Mock MultipartRequestInput multipartRequestInput; + @Mock PortModInput portModInput; + @Mock RoleRequestInput roleRequestInput; + @Mock SetConfigInput setConfigInput; + @Mock TableModInput tableModInput; + @Mock GetAsyncInput getAsyncInput; + @Mock SetAsyncInput setAsyncInput; + + private ConnectionAdapterImpl adapter; + private Cache> cache; + private StatisticsCounters statCounters; + + /** + * Initialize mocks + * Start counting and reset counters before each test + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + statCounters = StatisticsCounters.getInstance(); + statCounters.startCounting(false, 0); + } + + /** + * Disconnect adapter + * Stop counting after each test + */ + @After + public void tierDown(){ + if (adapter != null && adapter.isAlive()) { + adapter.disconnect(); + } + statCounters.stopCounting(); + } + + /** + * Test statistic counter for all rpc calls (counters DS_ENTERED_OFJAVA and DS_FLOW_MODS_ENTERED have to be enabled) + */ + @Test + public void testEnterOFJavaCounter() { + if(!statCounters.isCounterEnabled(CounterEventTypes.DS_ENTERED_OFJAVA)){ + Assert.fail("Counter " + CounterEventTypes.DS_ENTERED_OFJAVA + " is not enabled"); + } + if(!statCounters.isCounterEnabled(CounterEventTypes.DS_FLOW_MODS_ENTERED)){ + Assert.fail("Counter " + CounterEventTypes.DS_FLOW_MODS_ENTERED + " is not enabled"); + } + 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); + adapter.barrier(barrierInput); + embChannel.runPendingTasks(); + adapter.echo(echoInput); + embChannel.runPendingTasks(); + adapter.echoReply(echoReplyInput); + embChannel.runPendingTasks(); + adapter.experimenter(experimenterInput); + embChannel.runPendingTasks(); + adapter.flowMod(flowModInput); + embChannel.runPendingTasks(); + adapter.getConfig(getConfigInput); + embChannel.runPendingTasks(); + adapter.getFeatures(getFeaturesInput); + embChannel.runPendingTasks(); + adapter.getQueueConfig(getQueueConfigInput); + embChannel.runPendingTasks(); + adapter.groupMod(groupModInput); + embChannel.runPendingTasks(); + adapter.hello(helloInput); + embChannel.runPendingTasks(); + adapter.meterMod(meterModInput); + embChannel.runPendingTasks(); + adapter.packetOut(packetOutInput); + embChannel.runPendingTasks(); + adapter.multipartRequest(multipartRequestInput); + embChannel.runPendingTasks(); + adapter.portMod(portModInput); + embChannel.runPendingTasks(); + adapter.roleRequest(roleRequestInput); + embChannel.runPendingTasks(); + adapter.setConfig(setConfigInput); + embChannel.runPendingTasks(); + adapter.tableMod(tableModInput); + embChannel.runPendingTasks(); + adapter.getAsync(getAsyncInput); + embChannel.runPendingTasks(); + adapter.setAsync(setAsyncInput); + embChannel.runPendingTasks(); + Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl rpc methods", 19, statCounters.getCounter(CounterEventTypes.DS_ENTERED_OFJAVA).getCounterValue()); + Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl flow-mod entered", 1, statCounters.getCounter(CounterEventTypes.DS_FLOW_MODS_ENTERED).getCounterValue()); + adapter.disconnect(); + } + + /** + * Test counter for pass messages to consumer (counter US_MESSAGE_PASS has to be enabled) + */ + @Test + public void testMessagePassCounter() { + if(!statCounters.isCounterEnabled(CounterEventTypes.US_MESSAGE_PASS)){ + 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), true); + adapter.setMessageListener(messageListener); + adapter.setSystemListener(systemListener); + adapter.setConnectionReadyListener(readyListener); + cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) + .removalListener(REMOVAL_LISTENER).build(); + adapter.setResponseCache(cache); + when(channel.disconnect()).thenReturn(channelFuture); + DataObject message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + message = new ErrorMessageBuilder().build(); + adapter.consume(message); + message = new ExperimenterMessageBuilder().build(); + adapter.consume(message); + message = new FlowRemovedMessageBuilder().build(); + adapter.consume(message); + message = new HelloMessageBuilder().build(); + adapter.consume(message); + message = new MultipartReplyMessageBuilder().build(); + adapter.consume(message); + message = new PacketInMessageBuilder().build(); + adapter.consume(message); + message = new PortStatusMessageBuilder().build(); + adapter.consume(message); + message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl consume method", 9, statCounters.getCounter(CounterEventTypes.US_MESSAGE_PASS).getCounterValue()); + adapter.disconnect(); + } + + /** + * Empty channel Handler for testing + * @author madamjak + * + */ + private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter { + // no operation need to test + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java new file mode 100644 index 0000000000..0859a34f31 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionAdapterImplTest.java @@ -0,0 +1,207 @@ +/* + * 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.impl.core.connection; + +import static org.mockito.Matchers.any; +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; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder; +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.protocol.rev130731.ErrorMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder; +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.FlowRemovedMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder; +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.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.PacketInMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author michal.polkorab + * @author madamjak + * + */ +public class ConnectionAdapterImplTest { + + private static final int RPC_RESPONSE_EXPIRATION = 1; + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + + @Mock SocketChannel channel; + @Mock ChannelPipeline pipeline; + @Mock OpenflowProtocolListener messageListener; + @Mock SystemNotificationsListener systemListener; + @Mock ConnectionReadyListener readyListener; + @Mock Cache> mockCache; + @Mock ChannelFuture channelFuture; + + private ConnectionAdapterImpl adapter; + private Cache> cache; + + /** + * Initializes ConnectionAdapter + */ + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(channel.pipeline()).thenReturn(pipeline); + adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653), true); + adapter.setMessageListener(messageListener); + adapter.setSystemListener(systemListener); + adapter.setConnectionReadyListener(readyListener); + cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) + .removalListener(REMOVAL_LISTENER).build(); + adapter.setResponseCache(cache); + when(channel.disconnect()).thenReturn(channelFuture); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications + */ + @Test + public void testConsume() { + DataObject message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message); + message = new ErrorMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onErrorMessage((ErrorMessage) message); + message = new ExperimenterMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onExperimenterMessage((ExperimenterMessage) message); + message = new FlowRemovedMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onFlowRemovedMessage((FlowRemovedMessage) message); + message = new HelloMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onHelloMessage((HelloMessage) message); + message = new MultipartReplyMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onMultipartReplyMessage((MultipartReplyMessage) message); + message = new PacketInMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onPacketInMessage((PacketInMessage) message); + message = new PortStatusMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onPortStatusMessage((PortStatusMessage) message); + message = new SwitchIdleEventBuilder().build(); + adapter.consume(message); + verify(systemListener, times(1)).onSwitchIdleEvent((SwitchIdleEvent) message); + message = new DisconnectEventBuilder().build(); + adapter.consume(message); + verify(systemListener, times(1)).onDisconnectEvent((DisconnectEvent) message); + message = new EchoRequestMessageBuilder().build(); + adapter.consume(message); + verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc + */ + @Test + public void testConsume2() { + adapter.setResponseCache(mockCache); + final BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + barrierBuilder.setXid(42L); + final BarrierOutput barrier = barrierBuilder.build(); + adapter.consume(barrier); + verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class)); + } + + /** + * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc + */ + @Test + public void testConsume3() { + final BarrierInputBuilder inputBuilder = new BarrierInputBuilder(); + inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + inputBuilder.setXid(42L); + 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); + final BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder(); + barrierBuilder.setXid(42L); + final BarrierOutput barrierOutput = barrierBuilder.build(); + adapter.consume(barrierOutput); + final ResponseExpectedRpcListener ifPresent = cache.getIfPresent(key); + Assert.assertNull("Listener was not discarded", ifPresent); + } + /** + * Test IsAlive method + */ + @Test + public void testIsAlive(){ + 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(); + Assert.assertFalse("Wrong - ConnectionAdapterImpl can not be alive after disconnet.", connAddapter.isAlive()); + } + + /** + * Test throw exception if no listeners are present + */ + @Test(expected = java.lang.IllegalStateException.class) + public void testMissingListeners(){ + 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); + connAddapter.checkListeners(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java new file mode 100644 index 0000000000..b4097dda60 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ConnectionConfigurationImpl.java @@ -0,0 +1,104 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; + +/** + * @author michal.polkorab + * + */ +public class ConnectionConfigurationImpl implements ConnectionConfiguration { + + private final InetAddress address; + private final int port; + private Object transferProtocol; + 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(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 + public InetAddress getAddress() { + return address; + } + + @Override + public int getPort() { + return port; + } + + @Override + public Object getTransferProtocol() { + return transferProtocol; + } + + /** + * Used for testing - sets transport protocol + * @param protocol + */ + public void setTransferProtocol(final TransportProtocol protocol) { + this.transferProtocol = protocol; + } + + @Override + public long getSwitchIdleTimeout() { + return switchIdleTimeout; + } + + @Override + public Object getSslContext() { + // TODO Auto-generated method stub + return null; + } + + @Override + public TlsConfiguration getTlsConfiguration() { + return tlsConfig; + } + + @Override + public ThreadConfiguration getThreadConfiguration() { + return threadConfig; + } + + /** + * @param threadConfig thread model configuration (configures threads used) + */ + public void setThreadConfiguration(final ThreadConfiguration threadConfig) { + this.threadConfig = threadConfig; + } + + @Override + public boolean useBarrier() { + return useBarrier; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapperTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapperTest.java new file mode 100644 index 0000000000..3be4ba4f38 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/MessageListenerWrapperTest.java @@ -0,0 +1,36 @@ +/* + * 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.impl.core.connection; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.core.connection.MessageListenerWrapper; +import org.opendaylight.openflowjava.protocol.impl.core.connection.SimpleRpcListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class MessageListenerWrapperTest { + + /** + * Test MessageListenerWrapper creation + */ + @Test + public void test() { + HelloInputBuilder builder = new HelloInputBuilder(); + HelloInput hello = builder.build(); + SimpleRpcListener listener = new SimpleRpcListener(hello, "Error"); + MessageListenerWrapper wrapper = new MessageListenerWrapper(hello, listener); + Assert.assertEquals("Wrong message", hello, wrapper.getMsg()); + Assert.assertEquals("Wrong listener", listener, wrapper.getListener()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/OutboundQueueEntryTest.java new file mode 100644 index 0000000000..08c98c415d --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListenerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListenerTest.java new file mode 100644 index 0000000000..e6d1fff2e4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/ResponseExpectedRpcListenerTest.java @@ -0,0 +1,124 @@ +/* + * 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.impl.core.connection; + +import static org.junit.Assert.fail; +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 com.google.common.util.concurrent.SettableFuture; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +/** + * @author michal.polkorab + * + */ +public class ResponseExpectedRpcListenerTest { + + private static final RemovalListener> REMOVAL_LISTENER = + new RemovalListener>() { + @Override + public void onRemoval( + final RemovalNotification> notification) { + notification.getValue().discard(); + } + }; + private static final int RPC_RESPONSE_EXPIRATION = 1; + private final Cache> responseCache = CacheBuilder.newBuilder() + .concurrencyLevel(1) + .expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES) + .removalListener(REMOVAL_LISTENER).build(); + + /** + * Test object creation + */ + @Test(expected=NullPointerException.class) + public void testCreation() { + RpcResponseKey key = new RpcResponseKey(12345L, BarrierOutput.class.getName()); + new ResponseExpectedRpcListener<>("MESSAGE", "Failed to send message", null, key); + } + + /** + * Test object creation + */ + @Test(expected=NullPointerException.class) + public void testCreation2() { + new ResponseExpectedRpcListener<>("MESSAGE", "Failed to send message", responseCache, null); + } + + /** + * Test object creation + */ + @Test + public void testDiscard() { + RpcResponseKey key = new RpcResponseKey(12345L, BarrierOutput.class.getName()); + ResponseExpectedRpcListener listener = + new ResponseExpectedRpcListener<>("MESSAGE", "Failed to send message", responseCache, key); + listener.discard(); + RpcError rpcError = AbstractRpcListener.buildRpcError("Failed to send message", + "check switch connection", new TimeoutException("Request timed out")); + SettableFuture> result = SettableFuture.create(); + result.set(RpcResultBuilder.failed().withRpcError(rpcError).build()); + try { + Assert.assertEquals("Wrong result", result.get().getErrors().iterator().next().getMessage(), + listener.getResult().get().getErrors().iterator().next().getMessage()); + Assert.assertEquals("Wrong result", result.get().getResult(), listener.getResult().get().getResult()); + Assert.assertEquals("Wrong result", result.get().isSuccessful(), listener.getResult().get().isSuccessful()); + } catch (InterruptedException | ExecutionException e) { + fail("Problem accessing result"); + } + } + + /** + * Test object creation + */ + @Test + public void testCompleted() { + RpcResponseKey key = new RpcResponseKey(12345L, BarrierOutput.class.getName()); + ResponseExpectedRpcListener listener = + new ResponseExpectedRpcListener<>("MESSAGE", "Failed to send message", responseCache, key); + BarrierInputBuilder barrierBuilder = new BarrierInputBuilder(); + BarrierInput barrierInput = barrierBuilder.build(); + listener.completed(barrierInput); + SettableFuture> result = SettableFuture.create(); + result.set(RpcResultBuilder.success(barrierInput).build()); + try { + Assert.assertEquals("Wrong result", result.get().getErrors(), listener.getResult().get().getErrors()); + Assert.assertEquals("Wrong result", result.get().getResult(), listener.getResult().get().getResult()); + Assert.assertEquals("Wrong result", result.get().isSuccessful(), listener.getResult().get().isSuccessful()); + } catch (InterruptedException | ExecutionException e) { + fail("Problem accessing result"); + } + } + + /** + * Test object creation + */ + @Test + public void testOperationSuccessful() { + RpcResponseKey key = new RpcResponseKey(12345L, BarrierOutput.class.getName()); + ResponseExpectedRpcListener listener = + new ResponseExpectedRpcListener<>("MESSAGE", "Failed to send message", responseCache, key); + listener.operationSuccessful(); + ResponseExpectedRpcListener present = responseCache.getIfPresent(key); + Assert.assertEquals(present, listener); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java new file mode 100644 index 0000000000..2ef9cb8261 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/RpcResponseKeyTest.java @@ -0,0 +1,61 @@ +/* + * 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.impl.core.connection; + +import org.junit.Test; +import org.junit.Assert; +import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey; + +/** + * + * @author madamjak + * + */ +public class RpcResponseKeyTest { + + /** + * Test equals (xid is not tested) + */ + @Test + public void testEquals(){ + + long xid1 = 12L; + long xid2 = 66L; + String outputClazz1 = "Clazz01"; + String outputClazz2 = "Clazz02"; + RpcResponseKey key1 = new RpcResponseKey(xid1, null); + RpcResponseKey key2 = new RpcResponseKey(xid2, outputClazz2); + + Assert.assertTrue("Wrong equal to same obejct.", key1.equals(key1)); + Assert.assertFalse("Wrong equal to null.", key1.equals(null)); + Assert.assertFalse("Wrong equal to different type.", key1.equals(new Object())); + Assert.assertFalse("Wrong equal by outputClazz.", key1.equals(key2)); + + 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)); + } + + /** + * Test getters + */ + @Test + public void testGetters(){ + + long xid1 = 12L; + String outputClazz1 = "Clazz01"; + RpcResponseKey key1 = new RpcResponseKey(xid1, outputClazz1); + + Assert.assertTrue("Wrong getXid",key1.getXid() == xid1); + Assert.assertTrue("Wrong getOutputClazz",key1.getOutputClazz() == outputClazz1); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListenerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListenerTest.java new file mode 100644 index 0000000000..7726000532 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SimpleRpcListenerTest.java @@ -0,0 +1,102 @@ +/* + * 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.impl.core.connection; + +import static org.junit.Assert.fail; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import com.google.common.util.concurrent.SettableFuture; +import io.netty.util.concurrent.Future; +import java.util.concurrent.ExecutionException; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; + +/** + * @author michal.polkorab + * + */ +public class SimpleRpcListenerTest { + + @Mock Future future; + + /** + * Initializes mocks + */ + @Before + public void startUp() { + MockitoAnnotations.initMocks(this); + } + + /** + * Test SimpleRpcListener creation + */ + @Test + public void test() { + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + Assert.assertEquals("Wrong message", "MESSAGE", listener.takeMessage()); + Assert.assertEquals("Wrong message", listener, listener.takeListener()); + } + + /** + * Test rpc success + */ + @Test + public void testSuccessfulRpc() { + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + listener.operationSuccessful(); + SettableFuture> result = SettableFuture.create(); + result.set(RpcResultBuilder.success((Void)null).build()); + try { + Assert.assertEquals("Wrong result", result.get().getErrors(), listener.getResult().get().getErrors()); + Assert.assertEquals("Wrong result", result.get().getResult(), listener.getResult().get().getResult()); + Assert.assertEquals("Wrong result", result.get().isSuccessful(), listener.getResult().get().isSuccessful()); + } catch (InterruptedException | ExecutionException e) { + fail("Problem accessing result"); + } + } + + /** + * Test rpc success + */ + @Test + public void testOperationComplete() { + when(future.isSuccess()).thenReturn(false); + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + listener.operationComplete(future); + verify(future, times(1)).cause(); + try { + Assert.assertEquals("Wrong result", 1, listener.getResult().get().getErrors().size()); + } catch (InterruptedException | ExecutionException e) { + Assert.fail(); + } + } + + /** + * Test rpc success + */ + @Test + public void testOperationComplete2() { + when(future.isSuccess()).thenReturn(true); + SimpleRpcListener listener = new SimpleRpcListener("MESSAGE", "Failed to send message"); + listener.operationComplete(future); + verify(future, times(0)).cause(); + try { + Assert.assertEquals("Wrong result", 0, listener.getResult().get().getErrors().size()); + Assert.assertEquals("Wrong result", true, listener.getResult().get().isSuccessful()); + } catch (InterruptedException | ExecutionException e) { + Assert.fail(); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java new file mode 100755 index 0000000000..03cc3f990d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java @@ -0,0 +1,257 @@ +/* + * 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.impl.core.connection; + +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; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +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; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.ExperimenterActionSubType; +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 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * @author madamjak + * @author michal.polkorab + */ +public class SwitchConnectionProviderImpl02Test { + @Mock SwitchConnectionHandler handler; + @Mock OFGeneralSerializer serializer; + @Mock OFGeneralDeserializer deserializer; + @Mock OFDeserializer deserializerError; + @Mock OFDeserializer deserializerExpMsg; + @Mock OFDeserializer deserializerMultipartRplMsg; + @Mock OFDeserializer deserializerQueueProperty; + @Mock OFDeserializer deserializerMeterBandExpCase; + @Mock OFSerializer serializerExperimenterInput; + @Mock OFSerializer serializerMultipartRequestExpCase; + @Mock OFSerializer serializerMeterBandExpCase; + private static final int SWITCH_IDLE_TIMEOUT = 2000; + private InetAddress startupAddress; + private TlsConfiguration tlsConfiguration; + private SwitchConnectionProviderImpl provider; + private ConnectionConfigurationImpl config; + + /** + * Creates new {@link SwitchConnectionProvider} instance for each test + * @param protocol communication protocol + */ + public void startUp(final TransportProtocol protocol) { + MockitoAnnotations.initMocks(this); + config = null; + if (protocol != null) { + createConfig(protocol); + } + provider = new SwitchConnectionProviderImpl(); + } + + private void createConfig(final TransportProtocol protocol) { + try { + startupAddress = InetAddress.getLocalHost(); + } 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, + 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, true); + config.setTransferProtocol(protocol); + } + + + /** + * Test getServerFacade + */ + @Test + public void testServerFacade(){ + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + final ListenableFuture future = provider.startup(); + final ServerFacade serverFacade = provider.getServerFacade(); + Assert.assertNotNull("Wrong -- getServerFacade return null",serverFacade); + } + + /** + * Test shutdown on unconfigured provider + */ + @Test(expected = IllegalStateException.class) + public void testShutdownUnconfigured(){ + startUp(TransportProtocol.TCP); + provider.shutdown(); + } + /** + * Test unregister by wrong key + */ + @Test + public void testUnregisterWrongKeys(){ + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + final ExperimenterInstructionSerializerKey testSerKey + = new ExperimenterInstructionSerializerKey(EncodeConstants.OF10_VERSION_ID,42L); + Assert.assertFalse("Wrong -- unregisterSerializer",provider.unregisterSerializer(testSerKey)); + final ExperimenterInstructionDeserializerKey tesDeserKey + = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF10_VERSION_ID,24L); + Assert.assertFalse("Wrong -- unregisterDeserializer",provider.unregisterDeserializer(tesDeserKey)); + } + + /** + * Test register and unregister method + */ + @Test + public void testUnregisterExistingKeys(){ + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + // -- registerActionSerializer + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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 + 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, 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, 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 + 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 + 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 + 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 { + // empty class - only used in test for comparation + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java new file mode 100644 index 0000000000..175595157e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java @@ -0,0 +1,182 @@ +/* + * 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.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; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; +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 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; + +/** + * @author michal.polkorab + * + */ +public class SwitchConnectionProviderImplTest { + + @Mock SwitchConnectionHandler handler; + + private static final int SWITCH_IDLE_TIMEOUT = 2000; + private static final int WAIT_TIMEOUT = 2000; + private InetAddress startupAddress; + private TlsConfiguration tlsConfiguration; + private SwitchConnectionProviderImpl provider; + private ConnectionConfigurationImpl config; + + /** + * Creates new {@link SwitchConnectionProvider} instance for each test + * @param protocol communication protocol + */ + public void startUp(final TransportProtocol protocol) { + MockitoAnnotations.initMocks(this); + config = null; + if (protocol != null) { + createConfig(protocol); + } + provider = new SwitchConnectionProviderImpl(); + } + + private void createConfig(final TransportProtocol protocol) { + try { + startupAddress = InetAddress.getLocalHost(); + } 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, + 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, true); + config.setTransferProtocol(protocol); + } + + /** + * Tests provider startup - without configuration and {@link SwitchConnectionHandler} + */ + @Test + public void testStartup1() { + provider = new SwitchConnectionProviderImpl(); + final ListenableFuture future = provider.startup(); + try { + future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.assertEquals("Wrong state", "java.lang.NullPointerException", e.getMessage()); + } + } + + /** + * Tests provider startup - without configuration + */ + @Test + public void testStartup2() { + startUp(null); + provider.setSwitchConnectionHandler(handler); + final ListenableFuture future = provider.startup(); + try { + future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.assertEquals("Wrong state", "java.lang.NullPointerException", e.getMessage()); + } + } + + /** + * Tests provider startup - without {@link SwitchConnectionHandler} + */ + @Test + public void testStartup3() { + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + final ListenableFuture future = provider.startup(); + try { + future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.assertEquals("Wrong state", "java.lang.IllegalStateException:" + + " SwitchConnectionHandler is not set", e.getMessage()); + } + } + + /** + * Tests correct provider startup - over TCP + */ + @Test + public void testStartup4() { + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + provider.setSwitchConnectionHandler(handler); + try { + Assert.assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.fail(); + } + } + + /** + * Tests correct provider startup - over TLS + */ + @Test + public void testStartup5() { + startUp(TransportProtocol.TLS); + provider.setConfiguration(config); + provider.setSwitchConnectionHandler(handler); + try { + Assert.assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.fail(); + } + } + + /** + * Tests correct provider startup - over UDP + */ + @Test + public void testStartup6() { + startUp(TransportProtocol.UDP); + provider.setConfiguration(config); + provider.setSwitchConnectionHandler(handler); + try { + Assert.assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + Assert.fail(); + } + } + + /** + * Tests correct provider shutdown + */ + @Test + public void testShutdown() { + startUp(TransportProtocol.TCP); + provider.setConfiguration(config); + provider.setSwitchConnectionHandler(handler); + try { + Assert.assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + Assert.assertTrue("Failed to stop", provider.shutdown().get(5 * WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java new file mode 100644 index 0000000000..72bbe8e081 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java @@ -0,0 +1,151 @@ +/* + * 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.impl.core.connection; + +import com.google.common.util.concurrent.ListenableFuture; +import java.io.IOException; +import java.net.InetAddress; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +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.UdpChannelInitializer; +import org.opendaylight.openflowjava.protocol.impl.core.UdpHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author madamjak + * + */ +public class UdpHandlerTest { + + private static final Logger LOG = LoggerFactory.getLogger(UdpHandlerTest.class); + + @Mock + private UdpChannelInitializer udpChannelInitializerMock; + private UdpHandler udpHandler; + /** + * Mock init + */ + @Before + public void startUp() { + MockitoAnnotations.initMocks(this); + } + + /** + * Test to create UdpHandler with empty address and zero port + * @throws InterruptedException + * @throws ExecutionException + * @throws IOException + */ + @Test + 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(true)); + 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 fill address and given port + * @throws InterruptedException + * @throws ExecutionException + * @throws IOException + */ + @Test + public void testWithAddressAndPort() throws Exception{ + int port = 9874; + udpHandler = new UdpHandler(InetAddress.getLocalHost(), port); + udpHandler.setChannelInitializer(udpChannelInitializerMock); + Assert.assertTrue("Wrong - start server", startupServer(false)); + try { + Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); + } catch (TimeoutException e) { + Assert.fail("Wrong - getIsOnlineFuture timed out"); + } + Assert.assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); + shutdownServer(); + } + + /** + * 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); + } + + return online.isDone(); + } + + private void shutdownServer() throws InterruptedException, ExecutionException, TimeoutException { + ListenableFuture shutdownRet = udpHandler.shutdown() ; + final Boolean shutdownSucceeded = shutdownRet.get(10, TimeUnit.SECONDS); + Assert.assertTrue("Wrong - shutdown failed", shutdownSucceeded); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapperTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapperTest.java new file mode 100644 index 0000000000..df4c7e980a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpMessageListenerWrapperTest.java @@ -0,0 +1,53 @@ +/* + * 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.impl.core.connection; + +import io.netty.util.concurrent.Future; +import io.netty.util.concurrent.GenericFutureListener; + +import java.net.InetSocketAddress; + +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.UdpMessageListenerWrapper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +/** + * + * @author madamjak + * + */ +public class UdpMessageListenerWrapperTest { + + @Mock GenericFutureListener> listener; + @Mock OfHeader msg; + + @Before + public void startUp(){ + MockitoAnnotations.initMocks(this); + } + /** + * Getters test + */ + @Test + public void test(){ + int port = 9876; + String host ="localhost"; + InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port); + UdpMessageListenerWrapper wrapper = new UdpMessageListenerWrapper(msg,listener,inetSockAddr); + + Assert.assertEquals("Wrong getAddress", inetSockAddr, wrapper.getAddress()); + Assert.assertEquals("Wrong getListener", listener, wrapper.getListener()); + Assert.assertEquals("Wrong getMsg", msg, wrapper.getMsg()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactoryTest.java new file mode 100644 index 0000000000..965e299b1d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializationFactoryTest.java @@ -0,0 +1,56 @@ +/* + * 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.impl.deserialization; + +import static org.junit.Assert.assertEquals; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class DeserializationFactoryTest { + + /** + * Test deserializer lookup & deserialization + */ + @Test + public void test() { + DeserializerRegistryImpl registry = new DeserializerRegistryImpl(); + registry.init(); + DeserializationFactory factory = new DeserializationFactory(); + factory.setRegistry(registry); + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeByte(0); + buffer.writeShort(EncodeConstants.OFHEADER_SIZE); + buffer.writeInt(1234); + factory.deserialize(buffer, EncodeConstants.OF13_VERSION_ID); + assertEquals("Deserialization failed", 0, buffer.readableBytes()); + } + + /** + * Test deserializer lookup & deserialization + */ + @Test(expected=NullPointerException.class) + public void testNotExistingDeserializer() { + DeserializerRegistryImpl registry = new DeserializerRegistryImpl(); + registry.init(); + DeserializationFactory factory = new DeserializationFactory(); + factory.setRegistry(registry); + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeByte(0); + buffer.writeShort(EncodeConstants.OFHEADER_SIZE); + buffer.writeInt(1234); + factory.deserialize(buffer, (short) 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImplTest.java new file mode 100644 index 0000000000..a689db6b02 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/DeserializerRegistryImplTest.java @@ -0,0 +1,86 @@ +/* + * 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.impl.deserialization; + +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.MatchDeserializer; +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.v10.grouping.MatchV10; +/** + * + * @author madamjak + * + */ +public class DeserializerRegistryImplTest { + + private static final short OF13 = EncodeConstants.OF13_VERSION_ID; + private static final short OF10 = EncodeConstants.OF10_VERSION_ID; + private static final int EMPTY_VALUE = EncodeConstants.EMPTY_VALUE; + + /** + * Test - register deserializer without arguments + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterDeserializerNoArgs(){ + DeserializerRegistryImpl serReg = new DeserializerRegistryImpl(); + serReg.registerDeserializer(null, null); + } + + /** + * Test - register deserializer with no key + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterDeserializerNoKey(){ + DeserializerRegistryImpl serReg = new DeserializerRegistryImpl(); + serReg.registerDeserializer(null, new MatchDeserializer()); + } + + /** + * Test - register deserializer with no deserializer + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterDeserializerNoDeserializer(){ + DeserializerRegistryImpl serReg = new DeserializerRegistryImpl(); + serReg.registerDeserializer(new MessageCodeKey(OF13, EMPTY_VALUE, Match.class), null); + } + + /** + * Test - unregister deserializer without MessageTypeKey + */ + @Test(expected = IllegalArgumentException.class) + public void testUnRegisterDeserializerNoMessageTypeKey(){ + DeserializerRegistryImpl derserReg = new DeserializerRegistryImpl(); + derserReg.init(); + derserReg.unregisterDeserializer(null); + } + + /** + * Test - unregister deserializer + */ + @Test + public void testUnRegisterDeserializer(){ + DeserializerRegistryImpl derserReg = new DeserializerRegistryImpl(); + derserReg.init(); + Assert.assertTrue("Wrong - unregister serializer",derserReg.unregisterDeserializer(new MessageCodeKey(OF13,EMPTY_VALUE, Match.class))); + Assert.assertFalse("Wrong - unregister serializer",derserReg.unregisterDeserializer(new MessageCodeKey(OF10,EMPTY_VALUE, Match.class))); + } + + /** + * Test - get deserializer + */ + @Test(expected=IllegalStateException.class) + public void testGetDeserializer(){ + DeserializerRegistryImpl registry = new DeserializerRegistryImpl(); + registry.init(); + registry.getDeserializer(new MessageCodeKey((short) 5000, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + Assert.fail(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKeyTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKeyTest.java new file mode 100644 index 0000000000..165d613bc8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/MessageTypeCodeKeyTest.java @@ -0,0 +1,62 @@ +/* + * 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.impl.deserialization; + +import org.junit.Assert; +import org.junit.Test; + + +/** + * + * @author madamjak + * + */ +public class MessageTypeCodeKeyTest { + + /** + * Tests equals and hashCode + */ + @Test + public void testEqualsAndHashcode(){ + short msgType1 = 12; + short msgVersion1 = 34; + short msgType2 = 21; + short msgVersion2 = 43; + MessageTypeCodeKey key1 = new MessageTypeCodeKey(msgVersion1, msgType1); + + Assert.assertTrue("Wrong - equals to same object", key1.equals(key1)); + Assert.assertFalse("Wrong - equals to null", key1.equals(null)); + Assert.assertFalse("Wrong - equals to different class", key1.equals(new Object())); + + MessageTypeCodeKey key2 = new MessageTypeCodeKey(msgVersion1, msgType1); + Assert.assertTrue("Wrong hashcode", key1.hashCode() == key2.hashCode()); + Assert.assertTrue("Wrong - equals to mirror object", key1.equals(key2)); + + key2 = new MessageTypeCodeKey(msgVersion2, msgType2); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + Assert.assertFalse("Wrong - equals by msgType", key1.equals(key2)); + + key2 = new MessageTypeCodeKey(msgVersion2, msgType1); + Assert.assertFalse("Wrong - equals by msgVersion", key1.equals(key2)); + Assert.assertFalse("Wrong hashcode", key1.hashCode() == key2.hashCode()); + } + + /** + * Tests getters + */ + @Test + public void testGetter(){ + short msgType = 12; + short msgVersion = 34; + MessageTypeCodeKey key1 = new MessageTypeCodeKey(msgVersion, msgType); + + Assert.assertEquals(msgType, key1.getMsgType()); + Assert.assertEquals(msgVersion, key1.getMsgVersion()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java new file mode 100644 index 0000000000..dfa0158027 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/TypeToClassMapInitializerTest.java @@ -0,0 +1,154 @@ +/* + * 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.impl.deserialization; + +import static org.junit.Assert.assertEquals; + +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.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; + + @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))); + 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", ExperimenterMessage.class, messageClassMap.get(new TypeToClassKey(version, 4))); + assertEquals("Wrong class", GetFeaturesOutput.class, messageClassMap.get(new TypeToClassKey(version, 6))); + assertEquals("Wrong class", GetConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 8))); + assertEquals("Wrong class", PacketInMessage.class, messageClassMap.get(new TypeToClassKey(version, 10))); + assertEquals("Wrong class", FlowRemovedMessage.class, messageClassMap.get(new TypeToClassKey(version, 11))); + assertEquals("Wrong class", PortStatusMessage.class, messageClassMap.get(new TypeToClassKey(version, 12))); + 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))); + 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", ExperimenterMessage.class, messageClassMap.get(new TypeToClassKey(version, 4))); + assertEquals("Wrong class", GetFeaturesOutput.class, messageClassMap.get(new TypeToClassKey(version, 6))); + assertEquals("Wrong class", GetConfigOutput.class, messageClassMap.get(new TypeToClassKey(version, 8))); + assertEquals("Wrong class", PacketInMessage.class, messageClassMap.get(new TypeToClassKey(version, 10))); + assertEquals("Wrong class", FlowRemovedMessage.class, messageClassMap.get(new TypeToClassKey(version, 11))); + assertEquals("Wrong class", PortStatusMessage.class, messageClassMap.get(new TypeToClassKey(version, 12))); + assertEquals("Wrong class", MultipartReplyMessage.class, messageClassMap.get(new TypeToClassKey(version, 19))); + assertEquals("Wrong class", BarrierOutput.class, messageClassMap.get(new TypeToClassKey(version, 21))); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierInputMessageFactoryTest.java new file mode 100644 index 0000000000..5e63639be1 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java new file mode 100644 index 0000000000..7edff8ed43 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/BarrierReplyMessageFactoryTest.java @@ -0,0 +1,54 @@ +/* + * 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 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.BarrierOutput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.BarrierReplyMessageFactory}. + * @author michal.polkorab + * @author timotej.kubas + */ +public class BarrierReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public BarrierReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 21, BarrierOutput.class)); + } + + /** + * Testing of {@link BarrierReplyMessageFactory} 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, 19, BarrierOutput.class); + testHeaderVersions(Collections.singletonList(EncodeConstants.OF10_VERSION_ID), bb); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java new file mode 100644 index 0000000000..8ec42cb14e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoReplyMessageFactoryTest.java @@ -0,0 +1,72 @@ +/* + * 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 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.protocol.rev130731.EchoOutput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoReplyMessageFactory}. + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public EchoReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 3, EchoOutput.class)); + } + + /** + * Testing {@link EchoReplyMessageFactory} 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); + } + + /** + * Testing {@link EchoReplyMessageFactory} for correct translation into POJO. + */ + @Test + public void testWithEmptyDataField() { + ByteBuf bb = BufferHelper.buildBuffer(); + EchoOutput builtByFactory = BufferHelper.deserialize(factory, bb); + Assert.assertArrayEquals("Wrong data", null, builtByFactory.getData()); + } + + /** + * 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(factory, bb); + Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java new file mode 100644 index 0000000000..fb8fc49038 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/EchoRequestMessageFactoryTest.java @@ -0,0 +1,74 @@ +/* + * 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 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.protocol.rev130731.EchoRequestMessage; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.EchoRequestMessageFactory}. + * @author michal.polkorab + * @author timotej.kubas + */ +public class EchoRequestMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public EchoRequestMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 2, EchoRequestMessage.class)); + } + + /** + * Testing {@link EchoRequestMessageFactory} 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); + } + + /** + * Testing {@link EchoRequestMessageFactory} for correct translation into POJO. + */ + @Test + public void testWithEmptyDataField() { + byte[] data = new byte[]{}; + ByteBuf bb = BufferHelper.buildBuffer(); + EchoRequestMessage builtByFactory = BufferHelper.deserialize(factory, bb); + Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); + + } + + /** + * 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(factory, bb); + Assert.assertArrayEquals("Wrong data", data, builtByFactory.getData()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactoryTest.java new file mode 100644 index 0000000000..0d7dc5c40b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ErrorMessageFactoryTest.java @@ -0,0 +1,399 @@ +/* + * 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.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage; + +/** + * @author michal.polkorab + * @author timotej.kubas + */ +@RunWith(MockitoJUnitRunner.class) +public class ErrorMessageFactoryTest { + + @Mock DeserializerRegistry registry; + @Mock ErrorMessageFactory deserializer; + + private ErrorMessageFactory errorFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + errorFactory = new ErrorMessageFactory(); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithoutData() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 00"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "INCOMPATIBLE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 01 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 1, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADREQUEST", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADVERSION", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 02 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 2, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADACTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADTYPE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 03 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADINSTRUCTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWNINST", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 04 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 4, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADMATCH", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADTYPE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 05 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 5, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "FLOWMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 06 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 6, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "GROUPMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "GROUPEXISTS", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 07 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "PORTMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADPORT", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 08 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 8, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "TABLEMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADTABLE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 09 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 9, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "QUEUEOPFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADPORT", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0A 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 10, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "SWITCHCONFIGFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADFLAGS", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0B 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 11, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "ROLEREQUESTFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "STALE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0C 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 12, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "METERMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0D 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 13, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "TABLEFEATURESFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADTABLE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + * - not existing code used + */ + @Test + public void testWithoutData2() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 FF FF"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 01 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 1, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADREQUEST", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 02 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 2, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADACTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 03 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADINSTRUCTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 04 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 4, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADMATCH", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 05 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 5, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "FLOWMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 06 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 6, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "GROUPMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 07 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "PORTMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 08 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 8, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "TABLEMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 09 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 9, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "QUEUEOPFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0A FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 10, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "SWITCHCONFIGFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0B FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 11, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "ROLEREQUESTFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0C FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 12, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "METERMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 0D FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 13, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "TABLEFEATURESFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithData() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 01 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 1, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "EPERM", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithIncorrectTypeEnum() { + ByteBuf bb = BufferHelper.buildBuffer("00 20 00 05 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 32, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 5, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "UNKNOWN_TYPE", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithIncorrectCodeEnum() { + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 10 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 16, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADINSTRUCTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testExperimenterError() { + Mockito.when(registry.getDeserializer(Matchers.any(MessageCodeKey.class))).thenReturn(deserializer); + errorFactory.injectDeserializerRegistry(registry); + ByteBuf bb = BufferHelper.buildBuffer("FF FF 00 00 00 01"); + BufferHelper.deserialize(errorFactory, bb); + + Mockito.verify(deserializer, Mockito.times(1)).deserialize(bb); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java new file mode 100644 index 0000000000..37dd6ddeb9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/ExperimenterMessageFactoryTest.java @@ -0,0 +1,62 @@ +/* + * 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.impl.deserialization.factories; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.when; + +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.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 ExperimenterDataOfChoice message; + private ExperimenterMessageFactory factory; + + /** + * Initializes mocks + */ + @Before + public void startUp() { + factory = new ExperimenterMessageFactory(); + } + + /** + * Test deserializer lookup correctness + */ + @Test + 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 00 00 00 20"); + factory.injectDeserializerRegistry(registry); + ExperimenterMessage deserializedMessage = factory.deserialize(buffer); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactoryTest.java new file mode 100644 index 0000000000..1c6fc70391 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FeaturesReplyMessageFactoryTest.java @@ -0,0 +1,75 @@ +/* + * 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.common.types.rev130731.Capabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; + +/** + * @author michal.polkorab + * @author timotej.kubas + */ +public class FeaturesReplyMessageFactoryTest { + + private OFDeserializer featuresFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + featuresFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 6, GetFeaturesOutput.class)); + } + + /** + * Testing {@link FeaturesReplyMessageFactory} for correct translation into POJO + */ + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 01 00 00 00" + + " 00 00 00 00 01 02 03"); + GetFeaturesOutput builtByFactory = BufferHelper.deserialize(featuresFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong datapathId", 0x0001020304050607L, builtByFactory.getDatapathId().longValue()); + Assert.assertEquals("Wrong buffers", 0x00010203L, builtByFactory.getBuffers().longValue()); + Assert.assertEquals("Wrong number of tables", 0x01, builtByFactory.getTables().shortValue()); + Assert.assertEquals("Wrong auxiliaryId", 0x01, builtByFactory.getAuxiliaryId().shortValue()); + Assert.assertEquals("Wrong capabilities", new Capabilities(false, false, false, false, false, false, false), builtByFactory.getCapabilities()); + Assert.assertEquals("Wrong reserved", 0x00010203L, builtByFactory.getReserved().longValue()); + } + + /** + * Testing {@link FeaturesReplyMessageFactory} for correct translation into POJO + * (capabilities set) + */ + @Test + public void testCapabilities() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 01 00 00 00" + + " 00 01 6F 00 01 02 03"); + GetFeaturesOutput builtByFactory = BufferHelper.deserialize(featuresFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong capabilities", new Capabilities(true, true, true, true, true, true, true), builtByFactory.getCapabilities()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowModInputMessageFactoryTest.java new file mode 100644 index 0000000000..f98564bd06 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactoryTest.java new file mode 100644 index 0000000000..5f9d65a3ee --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/FlowRemovedMessageFactoryTest.java @@ -0,0 +1,67 @@ +/* + * 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.common.types.rev130731.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class FlowRemovedMessageFactoryTest { + + 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, 11, FlowRemovedMessage.class)); + } + + /** + * Testing {@link FlowRemovedMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 03 02 04 00 00 00 02" + + " 00 00 00 05 00 01 00 03 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07"); + FlowRemovedMessage builtByFactory = BufferHelper.deserialize(flowFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + + Assert.assertTrue(builtByFactory.getCookie().longValue() == 0x0001020304050607L); + Assert.assertTrue(builtByFactory.getPriority() == 0x03); + Assert.assertEquals("Wrong reason", 0x02, builtByFactory.getReason().getIntValue()); + Assert.assertEquals("Wrong tableId", new TableId(4L), builtByFactory.getTableId()); + Assert.assertEquals("Wrong durationSec", 0x02L, builtByFactory.getDurationSec().longValue()); + Assert.assertEquals("Wrong durationNsec", 0x05L, builtByFactory.getDurationNsec().longValue()); + Assert.assertEquals("Wrong idleTimeout", 0x01, builtByFactory.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong hardTimeout", 0x03, builtByFactory.getHardTimeout().intValue()); + Assert.assertEquals("Wrong packetCount", 0x0001020304050607L, builtByFactory.getPacketCount().longValue()); + Assert.assertEquals("Wrong byteCount", 0x0001020304050607L, builtByFactory.getByteCount().longValue()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactoryTest.java new file mode 100644 index 0000000000..4cb07da24f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncReplyMessageFactoryTest.java @@ -0,0 +1,130 @@ +/* + * 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 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.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.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.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 timotej.kubas + * + */ +public class GetAsyncReplyMessageFactoryTest { + + private OFDeserializer asyncFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + asyncFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 27, GetAsyncOutput.class)); + } + + /** + * Testing {@link GetAsyncReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testGetAsyncReplyMessage() { + 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"); + GetAsyncOutput builtByFactory = BufferHelper.deserialize(asyncFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong packetInMask",createPacketInMask(), builtByFactory.getPacketInMask()); + Assert.assertEquals("Wrong portStatusMask",createPortStatusMask(), builtByFactory.getPortStatusMask()); + Assert.assertEquals("Wrong flowRemovedMask",createFlowRemovedMask(), builtByFactory.getFlowRemovedMask()); + } + + private static List createPacketInMask() { + List inMasks = new ArrayList<>(); + PacketInMaskBuilder maskBuilder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + maskBuilder = new PacketInMaskBuilder(); + List reasons = new ArrayList<>(); + reasons.add(PacketInReason.OFPRNOMATCH); + reasons.add(PacketInReason.OFPRACTION); + reasons.add(PacketInReason.OFPRINVALIDTTL); + maskBuilder.setMask(reasons); + inMasks.add(maskBuilder.build()); + // OFPCR_ROLE_SLAVE + maskBuilder = new PacketInMaskBuilder(); + reasons = new ArrayList<>(); + maskBuilder.setMask(reasons); + inMasks.add(maskBuilder.build()); + return inMasks; + } + + private static List createPortStatusMask() { + List inMasks = new ArrayList<>(); + PortStatusMaskBuilder maskBuilder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + maskBuilder = new PortStatusMaskBuilder(); + List reasons = new ArrayList<>(); + reasons.add(PortReason.OFPPRADD); + reasons.add(PortReason.OFPPRDELETE); + reasons.add(PortReason.OFPPRMODIFY); + inMasks.add(maskBuilder.setMask(reasons).build()); + // OFPCR_ROLE_SLAVE + maskBuilder = new PortStatusMaskBuilder(); + reasons = new ArrayList<>(); + maskBuilder.setMask(reasons); + inMasks.add(maskBuilder.build()); + return inMasks; + } + + private static List createFlowRemovedMask() { + List inMasks = new ArrayList<>(); + FlowRemovedMaskBuilder maskBuilder; + // OFPCR_ROLE_EQUAL or OFPCR_ROLE_MASTER + maskBuilder = new FlowRemovedMaskBuilder(); + List reasons = new ArrayList<>(); + reasons.add(FlowRemovedReason.OFPRRIDLETIMEOUT); + reasons.add(FlowRemovedReason.OFPRRHARDTIMEOUT); + reasons.add(FlowRemovedReason.OFPRRDELETE); + reasons.add(FlowRemovedReason.OFPRRGROUPDELETE); + maskBuilder.setMask(reasons); + inMasks.add(maskBuilder.build()); + // OFPCR_ROLE_SLAVE + maskBuilder = new FlowRemovedMaskBuilder(); + reasons = new ArrayList<>(); + maskBuilder.setMask(reasons); + inMasks.add(maskBuilder.build()); + return inMasks; + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetAsyncRequestMessageFactoryTest.java new file mode 100644 index 0000000000..dba971e3a6 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..9f2eb6ab24 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..be3d4faaf9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetConfigReplyMessageFactoryTest.java @@ -0,0 +1,63 @@ +/* + * 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 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.protocol.rev130731.GetConfigOutput; + +/** + * Test for {@link org.opendaylight.openflowjava.protocol.impl.deserialization.factories.GetConfigReplyMessageFactory}. + * @author michal.polkorab + * @author timotej.kubas + */ +public class GetConfigReplyMessageFactoryTest extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public GetConfigReplyMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 8, GetConfigOutput.class)); + } + + /** + * Testing {@link GetConfigReplyMessageFactory} 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 01 00 03"); + testHeaderVersions(versions, bb); + } + + /** + * Testing {@link GetConfigReplyMessageFactory} for correct translation into POJO. + */ + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 03"); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.java new file mode 100644 index 0000000000..0615098ce9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetFeaturesInputFactoryTest.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 GetFeaturesInputFactoryTest { + private OFDeserializer factory; + + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + factory = registry + .getDeserializer(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 5, GetFeaturesInput.class)); + } + + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer(); + GetFeaturesInput deserializedMessage = BufferHelper.deserialize(factory, bb); + BufferHelper.checkHeaderV13(deserializedMessage); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GetQueueConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..95f5197d82 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/GroupModInputMessageFactoryTest.java new file mode 100644 index 0000000000..0ede670d67 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java new file mode 100644 index 0000000000..d4ec69d446 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/HelloMessageFactoryTest.java @@ -0,0 +1,123 @@ +/* + * 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 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.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 extends DefaultDeserializerFactoryTest { + + /** + * Initializes deserializer registry and lookups OF13 deserializer. + */ + public HelloMessageFactoryTest() { + super(new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 0, HelloMessage.class)); + } + + /** + * Testing {@link HelloMessageFactory} for correct header version. + */ + @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. + */ + @Test + public void testWithoutPadding() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 " // type + + "00 08 " // length + + "00 00 00 11" // bitmap 1 + ); + 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. + */ + @Test + public void testWithPadding() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 " // type + + "00 0c " // length + + "00 00 00 11 " // bitmap 1 + + "00 00 00 00 " // bitmap 2 + + "00 00 00 00" // padding + ); + 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. + */ + @Test + public void testBadType(){ + ByteBuf bb = BufferHelper.buildBuffer("00 02 " // type + + "00 0c " // length + + "00 00 00 11 " // bitmap 1 + + "00 00 00 00 " // bitmap 2 + + "00 00 00 00" // padding + ); + HelloMessage builtByFactory = BufferHelper.deserialize(factory, bb); + Assert.assertEquals("Wrong - no element has been expected", 0, builtByFactory.getElements().size()); + } + + private static List createElement(int lengthInByte, int type) { + ElementsBuilder elementsBuilder = new ElementsBuilder(); + List elementsList = new ArrayList<>(); + List booleanList = new ArrayList<>(); + booleanList.add(true); + booleanList.add(false); + booleanList.add(false); + booleanList.add(false); + booleanList.add(true); + int inSize = booleanList.size(); + for (int i = 1; i < ((lengthInByte * 8) - inSize + 1); i++) { + booleanList.add(false); + } + elementsBuilder.setType(HelloElementType.forValue(type)); + elementsBuilder.setVersionBitmap(booleanList); + elementsList.add(elementsBuilder.build()); + return elementsList; + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MeterModInputMessageFactoryTest.java new file mode 100644 index 0000000000..72c025006c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java new file mode 100644 index 0000000000..088201b379 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartReplyMessageFactoryTest.java @@ -0,0 +1,985 @@ +/* + * 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 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.action.rev150203.action.grouping.action.choice.CopyTtlInCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlOutCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.GroupCase; +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.PopMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetFieldCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MeterFlags; +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.oxm.rev150225.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage; +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.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.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.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.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.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.group._case.MultipartReplyGroup; +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.meter._case.MultipartReplyMeter; +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.port.stats._case.MultipartReplyPortStats; +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.table._case.MultipartReplyTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class MultipartReplyMessageFactoryTest { + + private OFDeserializer multipartFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 19, MultipartReplyMessage.class)); + } + + private static final Logger LOG = LoggerFactory + .getLogger(MultipartReplyMessageFactoryTest.class); + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyDescBody(){ + final int DESC_STR_LEN = 256; + final int SERIAL_NUM_LEN = 32; + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 01 00 00 00 00"); + + String mfrDesc = "Manufacturer description"; + byte[] mfrDescBytes = new byte[256]; + mfrDescBytes = mfrDesc.getBytes(); + bb.writeBytes(mfrDescBytes); + bb.writeZero(DESC_STR_LEN - mfrDescBytes.length); + + String hwDesc = "Hardware description"; + byte[] hwDescBytes = new byte[256]; + hwDescBytes = hwDesc.getBytes(); + bb.writeBytes(hwDescBytes); + bb.writeZero(DESC_STR_LEN - hwDescBytes.length); + + String swDesc = "Software description"; + byte[] swDescBytes = new byte[256]; + swDescBytes = swDesc.getBytes(); + bb.writeBytes(swDescBytes); + bb.writeZero(DESC_STR_LEN - swDescBytes.length); + + String serialNum = "SN0123456789"; + byte[] serialNumBytes = new byte[32]; + serialNumBytes = serialNum.getBytes(); + bb.writeBytes(serialNumBytes); + bb.writeZero(SERIAL_NUM_LEN - serialNumBytes.length); + + String dpDesc = "switch3 in room 3120"; + byte[] dpDescBytes = new byte[256]; + dpDescBytes = dpDesc.getBytes(); + bb.writeBytes(dpDescBytes); + bb.writeZero(DESC_STR_LEN - dpDescBytes.length); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x00, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyDescCase messageCase = (MultipartReplyDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyDesc message = messageCase.getMultipartReplyDesc(); + Assert.assertEquals("Wrong mfrDesc", "Manufacturer description", message.getMfrDesc()); + Assert.assertEquals("Wrong hwDesc", "Hardware description", message.getHwDesc()); + Assert.assertEquals("Wrong swDesc", "Software description", message.getSwDesc()); + Assert.assertEquals("Wrong serialNum", "SN0123456789", message.getSerialNum()); + Assert.assertEquals("Wrong dpDesc", "switch3 in room 3120", message.getDpDesc()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyAggregateBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 02 00 01 00 00 00 00 "+ + "FF 01 01 01 01 01 01 01 "+//packetCount + "0F 01 01 01 01 01 01 01 "+//byteCount + "00 00 00 08 "+//flowCount + "00 00 00 00"//pad + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x02, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyAggregateCase messageCase = (MultipartReplyAggregateCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyAggregate message = messageCase.getMultipartReplyAggregate(); + Assert.assertEquals("Wrong packetCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getPacketCount()); + Assert.assertEquals("Wrong byteCount", + new BigInteger(1, new byte[]{(byte) 0x0F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getByteCount()); + Assert.assertEquals("Wrong flowCount", + 8, + message.getFlowCount().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyTableBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 01 00 00 00 00 "+ + "08 "+//tableId + "00 00 00 "+//pad + "00 00 00 10 "+//activeCount + "FF 01 01 01 01 01 01 01 "+//lookupCount + "AF 01 01 01 01 01 01 01"//matchedCount + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x03, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + + MultipartReplyTableCase messageCase = (MultipartReplyTableCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyTable message = messageCase.getMultipartReplyTable(); + Assert.assertEquals("Wrong tableId", 8, message.getTableStats().get(0).getTableId().intValue()); + Assert.assertEquals("Wrong activeCount", 16, message.getTableStats().get(0).getActiveCount().longValue()); + Assert.assertEquals("Wrong lookupCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getTableStats().get(0).getLookupCount()); + Assert.assertEquals("Wrong matchedCount", + new BigInteger(1, new byte[]{(byte) 0xAF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getTableStats().get(0).getMatchedCount()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyPortStatsBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 04 00 01 00 00 00 00 "+ + "00 00 00 FF "+//portNo + "00 00 00 00 "+//pad + "FF 01 01 01 01 01 01 01 "+//rxPackets + "FF 02 02 02 02 02 02 02 "+//txPackets + "FF 02 03 02 03 02 03 02 "+//rxBytes + "FF 02 03 02 03 02 03 02 "+//txBytes + "FF 02 03 02 03 02 03 02 "+//rxDropped + "FF 02 03 02 03 02 03 02 "+//txDropped + "FF 02 03 02 03 02 03 02 "+//rxErrors + "FF 02 03 02 03 02 03 02 "+//txErrors + "FF 02 03 02 03 02 03 02 "+//rxFrameErr + "FF 02 03 02 03 02 03 02 "+//rxOverErr + "FF 02 03 02 03 02 03 02 "+//rxCrcErr + "FF 02 03 02 03 02 03 02 "+//collisions + "00 00 00 02 "+//durationSec + "00 00 00 04"//durationNsec + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x04, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyPortStatsCase messageCase = (MultipartReplyPortStatsCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyPortStats message = messageCase.getMultipartReplyPortStats(); + Assert.assertEquals("Wrong portNo", 255, message.getPortStats().get(0).getPortNo().intValue()); + Assert.assertEquals("Wrong rxPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getPortStats().get(0).getRxPackets()); + Assert.assertEquals("Wrong txPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getPortStats().get(0).getTxPackets()); + Assert.assertEquals("Wrong rxBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxBytes()); + Assert.assertEquals("Wrong txBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxBytes()); + Assert.assertEquals("Wrong rxDropped", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxDropped()); + Assert.assertEquals("Wrong txDropped", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxDropped()); + Assert.assertEquals("Wrong rxErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxErrors()); + Assert.assertEquals("Wrong txErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxErrors()); + Assert.assertEquals("Wrong rxFrameErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxFrameErr()); + Assert.assertEquals("Wrong rxOverErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxOverErr()); + Assert.assertEquals("Wrong rxCrcErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxCrcErr()); + Assert.assertEquals("Wrong collisions", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getCollisions()); + Assert.assertEquals("Wrong durationSec", 2, message.getPortStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 4, message.getPortStats().get(0).getDurationNsec().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyQueueBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 05 00 01 00 00 00 00 "+ + "00 00 00 FF "+//portNo + "00 00 00 10 "+//queueId + "FF 02 03 02 03 02 03 02 "+//txBytes + "FF 02 02 02 02 02 02 02 "+//txPackets + "FF 02 03 02 03 02 03 02 "+//txErrors + "00 00 00 02 "+//durationSec + "00 00 00 04"//durationNsec + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x05, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyQueueCase messageCase = (MultipartReplyQueueCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyQueue message = messageCase.getMultipartReplyQueue(); + Assert.assertEquals("Wrong portNo", 255, message.getQueueStats().get(0).getPortNo().intValue()); + Assert.assertEquals("Wrong queueId", 16, message.getQueueStats().get(0).getQueueId().intValue()); + Assert.assertEquals("Wrong txBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getQueueStats().get(0).getTxBytes()); + Assert.assertEquals("Wrong txPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getQueueStats().get(0).getTxPackets()); + Assert.assertEquals("Wrong txErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getQueueStats().get(0).getTxErrors()); + Assert.assertEquals("Wrong durationSec", 2, message.getQueueStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 4, message.getQueueStats().get(0).getDurationNsec().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyGroupBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 06 00 01 00 00 00 00 "+ + "00 48 "+//length + "00 00 "+//pad1 + "00 00 00 10 "+//groupId + "00 00 00 12 "+//refCount + "00 00 00 00 "+//pad2 + "FF 01 01 01 01 01 01 01 "+//packetCount + "FF 01 01 01 01 01 01 01 "+//byteCount + "00 00 00 08 "+//durationSec + "00 00 00 09 "+//durationNsec + "FF 01 01 01 01 01 01 01 "+//packetCountBucket + "FF 01 01 01 01 01 01 01 "+//byteCountBucket + "FF 02 02 02 02 02 02 02 "+//packetCountBucket_2 + "FF 02 02 02 02 02 02 02 "+//byteCountBucket_2 + "00 48 "+//length_2 + "00 00 "+//pad1.2 + "00 00 00 10 "+//groupId_2 + "00 00 00 12 "+//refCount_2 + "00 00 00 00 "+//pad2.2 + "FF 01 01 01 01 01 01 01 "+//packetCount_2 + "FF 01 01 01 01 01 01 01 "+//byteCount_2 + "00 00 00 08 "+//durationSec_2 + "00 00 00 09 "+//durationNsec_2 + "FF 01 01 01 01 01 01 01 "+//packetCountBucket_1.2 + "FF 01 01 01 01 01 01 01 "+//byteCountBucket_1.2 + "FF 02 02 02 02 02 02 02 "+//packetCountBucket_2.2 + "FF 02 02 02 02 02 02 02"//byteCountBucket_2.2 + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x06, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupCase messageCase = (MultipartReplyGroupCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroup message = messageCase.getMultipartReplyGroup(); + Assert.assertEquals("Wrong groupId", 16, message.getGroupStats().get(0).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong refCount", 18, message.getGroupStats().get(0).getRefCount().intValue()); + Assert.assertEquals("Wrong packetCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(0).getPacketCount()); + Assert.assertEquals("Wrong byteCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(0).getByteCount()); + Assert.assertEquals("Wrong durationSec", 8, message.getGroupStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 9, message.getGroupStats().get(0).getDurationNsec().intValue()); + Assert.assertEquals("Wrong packetCountBucket", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(0).getBucketStats().get(0).getPacketCount()); + Assert.assertEquals("Wrong byteCountBucket", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(0).getBucketStats().get(0).getByteCount()); + Assert.assertEquals("Wrong packetCountBucket_2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getGroupStats().get(0).getBucketStats().get(1).getPacketCount()); + Assert.assertEquals("Wrong byteCountBucket_2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getGroupStats().get(0).getBucketStats().get(1).getByteCount()); + + Assert.assertEquals("Wrong groupId_2", 16, message.getGroupStats().get(1).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong refCount_2", 18, message.getGroupStats().get(1).getRefCount().intValue()); + Assert.assertEquals("Wrong packetCount_2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(1).getPacketCount()); + Assert.assertEquals("Wrong byteCount_2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(1).getByteCount()); + Assert.assertEquals("Wrong durationSec_2", 8, message.getGroupStats().get(1).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec_2", 9, message.getGroupStats().get(1).getDurationNsec().intValue()); + Assert.assertEquals("Wrong packetCountBucket_1.2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(1).getBucketStats().get(0).getPacketCount()); + Assert.assertEquals("Wrong byteCountBucket_1.2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getGroupStats().get(1).getBucketStats().get(0).getByteCount()); + Assert.assertEquals("Wrong packetCountBucket_2.2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getGroupStats().get(1).getBucketStats().get(1).getPacketCount()); + Assert.assertEquals("Wrong byteCountBucket_2.2", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getGroupStats().get(1).getBucketStats().get(1).getByteCount()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 09 00 01 00 00 00 00 "+ + "00 00 00 09 "+//meterId + "00 58 "+//len + "00 00 00 00 00 00 "+//pad + "00 00 00 07 "+//flowCount + "FF 01 01 01 01 01 01 01 "+//packetInCount + "FF 01 01 01 01 01 01 01 "+//byteInCount + "00 00 00 05 "+//durationSec + "00 00 00 05 "+//durationNsec + "FF 01 01 01 01 01 01 01 "+//packetBandCount_01 + "FF 01 01 01 01 01 01 01 "+//byteBandCount_01 + "FF 02 02 02 02 02 02 02 "+//packetBandCount_02 + "FF 02 02 02 02 02 02 02 "+//byteBandCount_02 + "FF 03 03 03 03 03 03 03 "+//packetBandCount_03 + "FF 03 03 03 03 03 03 03"//byteBandCount_03 + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 9, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterCase messageCase = (MultipartReplyMeterCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeter message = messageCase.getMultipartReplyMeter(); + Assert.assertEquals("Wrong meterId", 9, + message.getMeterStats().get(0).getMeterId().getValue().intValue()); + Assert.assertEquals("Wrong flowCount", 7, + message.getMeterStats().get(0).getFlowCount().intValue()); + Assert.assertEquals("Wrong packetInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getPacketInCount()); + Assert.assertEquals("Wrong byteInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getByteInCount()); + Assert.assertEquals("Wrong durationSec", 5, + message.getMeterStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 5, + message.getMeterStats().get(0).getDurationNsec().intValue()); + Assert.assertEquals("Wrong packetBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getMeterBandStats().get(0).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getMeterBandStats().get(0).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(0).getMeterBandStats().get(1).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(0).getMeterBandStats().get(1).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(0).getMeterBandStats().get(2).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(0).getMeterBandStats().get(2).getByteBandCount()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterBodyMulti(){ + ByteBuf bb = BufferHelper.buildBuffer("00 09 00 01 00 00 00 00 "+ + "00 00 00 09 "+//meterId_0 + "00 58 "+//len_0 + "00 00 00 00 00 00 "+//pad_0 + "00 00 00 07 "+//flowCount_0 + "FF 01 01 01 01 01 01 01 "+//packetInCount_0 + "FF 01 01 01 01 01 01 01 "+//byteInCount_0 + "00 00 00 05 "+//durationSec_0 + "00 00 00 05 "+//durationNsec_0 + "FF 01 01 01 01 01 01 01 "+//packetBandCount_01 + "FF 01 01 01 01 01 01 01 "+//byteBandCount_01 + "FF 02 02 02 02 02 02 02 "+//packetBandCount_02 + "FF 02 02 02 02 02 02 02 "+//byteBandCount_02 + "FF 03 03 03 03 03 03 03 "+//packetBandCount_03 + "FF 03 03 03 03 03 03 03 "+//byteBandCount_03 + "00 00 00 08 "+//meterId_1 + "00 58 "+//len_1 + "00 00 00 00 00 00 "+//pad_1 + "00 00 00 07 "+//flowCount_1 + "FF 01 01 01 01 01 01 01 "+//packetInCount_1 + "FF 01 01 01 01 01 01 01 "+//byteInCount_1 + "00 00 00 05 "+//durationSec_1 + "00 00 00 05 "+//durationNsec_1 + "FF 01 01 01 01 01 01 01 "+//packetBandCount_11 + "FF 01 01 01 01 01 01 01 "+//byteBandCount_11 + "FF 02 02 02 02 02 02 02 "+//packetBandCount_12 + "FF 02 02 02 02 02 02 02 "+//byteBandCount_12 + "FF 03 03 03 03 03 03 03 "+//packetBandCount_13 + "FF 03 03 03 03 03 03 03"//byteBandCount_13 + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 9, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterCase messageCase = (MultipartReplyMeterCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeter message = messageCase.getMultipartReplyMeter(); + Assert.assertEquals("Wrong meterId", 9, + message.getMeterStats().get(0).getMeterId().getValue().intValue()); + Assert.assertEquals("Wrong flowCount", 7, + message.getMeterStats().get(0).getFlowCount().intValue()); + Assert.assertEquals("Wrong packetInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getPacketInCount()); + Assert.assertEquals("Wrong byteInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getByteInCount()); + Assert.assertEquals("Wrong durationSec", 5, + message.getMeterStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 5, + message.getMeterStats().get(0).getDurationNsec().intValue()); + Assert.assertEquals("Wrong packetBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getMeterBandStats().get(0).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(0).getMeterBandStats().get(0).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(0).getMeterBandStats().get(1).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(0).getMeterBandStats().get(1).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(0).getMeterBandStats().get(2).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(0).getMeterBandStats().get(2).getByteBandCount()); + + Assert.assertEquals("Wrong meterId", 8, + message.getMeterStats().get(1).getMeterId().getValue().intValue()); + Assert.assertEquals("Wrong flowCount", 7, + message.getMeterStats().get(1).getFlowCount().intValue()); + Assert.assertEquals("Wrong packetInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(1).getPacketInCount()); + Assert.assertEquals("Wrong byteInCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(1).getByteInCount()); + Assert.assertEquals("Wrong durationSec", 5, + message.getMeterStats().get(1).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 5, + message.getMeterStats().get(1).getDurationNsec().intValue()); + Assert.assertEquals("Wrong packetBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(1).getMeterBandStats().get(0).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_01", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getMeterStats().get(1).getMeterBandStats().get(0).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(1).getMeterBandStats().get(1).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_02", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getMeterStats().get(1).getMeterBandStats().get(1).getByteBandCount()); + Assert.assertEquals("Wrong packetBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(1).getMeterBandStats().get(2).getPacketBandCount()); + Assert.assertEquals("Wrong byteBandCount_03", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}), + message.getMeterStats().get(1).getMeterBandStats().get(2).getByteBandCount()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterConfigBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 0A 00 01 00 00 00 00 "+ + "00 28 "+//len + "00 0A "+//flags + "00 00 00 09 "+//meterId + "00 01 "+//meterBandDrop.type + "00 10 "+//meterBandDrop.len + "00 00 00 11 "+//meterBandDrop.rate + "00 00 00 20 "+//meterBandDrop.burstSize + "00 00 00 00 "+//meterBandDrop.pad + "00 02 "+//meterBandDscp.type + "00 10 "+//meterBandDscp.len + "00 00 00 11 "+//meterBandDscp.rate + "00 00 00 20 "+//meterBandDscp.burstSize + "04 "+//meterBandDscp.precLevel + "00 00 00");//meterBandDscp.pad + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 10, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterConfigCase messageCase = (MultipartReplyMeterConfigCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeterConfig message = messageCase.getMultipartReplyMeterConfig(); + Assert.assertEquals("Wrong flags", new MeterFlags(false, false, true, true), + message.getMeterConfig().get(0).getFlags()); + Assert.assertEquals("Wrong meterId", 9, + message.getMeterConfig().get(0).getMeterId().getValue().intValue()); + + MeterBandDropCase dropCase = (MeterBandDropCase) message.getMeterConfig().get(0).getBands().get(0).getMeterBand(); + MeterBandDrop meterBandDrop = dropCase.getMeterBandDrop(); + Assert.assertEquals("Wrong meterBandDrop.type", 1, meterBandDrop.getType().getIntValue()); + Assert.assertEquals("Wrong meterBandDrop.rate", 17, meterBandDrop.getRate().intValue()); + Assert.assertEquals("Wrong meterBandDrop.burstSize", 32, meterBandDrop.getBurstSize().intValue()); + + MeterBandDscpRemarkCase dscpCase = (MeterBandDscpRemarkCase) message.getMeterConfig().get(0).getBands().get(1).getMeterBand(); + MeterBandDscpRemark meterBandDscp = dscpCase.getMeterBandDscpRemark(); + Assert.assertEquals("Wrong meterBandDscp.type", 2, meterBandDscp.getType().getIntValue()); + Assert.assertEquals("Wrong meterBandDscp.rate", 17, meterBandDscp.getRate().intValue()); + Assert.assertEquals("Wrong meterBandDscp.burstSize", 32, meterBandDscp.getBurstSize().intValue()); + Assert.assertEquals("Wrong meterBandDscp.precLevel", 4, meterBandDscp.getPrecLevel().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterConfigBodyMulti(){ + ByteBuf bb = BufferHelper.buildBuffer("00 0A 00 01 00 00 00 00 "+ + "00 28 "+//len + "00 06 "+//flags + "00 00 00 09 "+//meterId + "00 01 "+//meterBandDrop.type + "00 10 "+//meterBandDrop.len + "00 00 00 11 "+//meterBandDrop.rate + "00 00 00 20 "+//meterBandDrop.burstSize + "00 00 00 00 "+//meterBandDrop.pad + "00 02 "+//meterBandDscp.type + "00 10 "+//meterBandDscp.len + "00 00 00 11 "+//meterBandDscp.rate + "00 00 00 20 "+//meterBandDscp.burstSize + "04 "+//meterBandDscp.precLevel + "00 00 00 "+//meterBandDscp.pad + + "00 18 "+//len01 + "00 03 "+//flags01 + "00 00 00 07 "+//meterId01 + "00 02 "+//meterBandDscp01.type + "00 10 "+//meterBandDscp01.len + "00 00 00 11 "+//meterBandDscp01.rate + "00 00 00 20 "+//meterBandDscp01.burstSize + "04 "+//meterBandDscp01.precLevel + "00 00 00"//meterBandDscp01.pad + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 10, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterConfigCase messageCase = (MultipartReplyMeterConfigCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeterConfig message = messageCase.getMultipartReplyMeterConfig(); + Assert.assertEquals("Wrong flags", new MeterFlags(true, false, true, false), + message.getMeterConfig().get(0).getFlags()); + Assert.assertEquals("Wrong meterId", 9, + message.getMeterConfig().get(0).getMeterId().getValue().intValue()); + + MeterBandDropCase dropCase = (MeterBandDropCase) message.getMeterConfig().get(0).getBands().get(0).getMeterBand(); + MeterBandDrop meterBandDrop = dropCase.getMeterBandDrop(); + Assert.assertEquals("Wrong meterBandDrop.type", 1, meterBandDrop.getType().getIntValue()); + Assert.assertEquals("Wrong meterBandDrop.rate", 17, meterBandDrop.getRate().intValue()); + Assert.assertEquals("Wrong meterBandDrop.burstSize", 32, meterBandDrop.getBurstSize().intValue()); + + MeterBandDscpRemarkCase dscpCase = (MeterBandDscpRemarkCase) message.getMeterConfig().get(0).getBands().get(1).getMeterBand(); + MeterBandDscpRemark meterBandDscp = dscpCase.getMeterBandDscpRemark(); + Assert.assertEquals("Wrong meterBandDscp.type", 2, meterBandDscp.getType().getIntValue()); + Assert.assertEquals("Wrong meterBandDscp.rate", 17, meterBandDscp.getRate().intValue()); + Assert.assertEquals("Wrong meterBandDscp.burstSize", 32, meterBandDscp.getBurstSize().intValue()); + Assert.assertEquals("Wrong meterBandDscp.precLevel", 4, meterBandDscp.getPrecLevel().intValue()); + + 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, + message.getMeterConfig().get(1).getMeterId().getValue().intValue()); + + MeterBandDscpRemarkCase dscpCase01 = (MeterBandDscpRemarkCase) message.getMeterConfig().get(1).getBands().get(0).getMeterBand(); + MeterBandDscpRemark meterBandDscp01 = dscpCase01.getMeterBandDscpRemark(); + Assert.assertEquals("Wrong meterBandDscp01.type", 2, meterBandDscp01.getType().getIntValue()); + Assert.assertEquals("Wrong meterBandDscp01.rate", 17, meterBandDscp01.getRate().intValue()); + Assert.assertEquals("Wrong meterBandDscp01.burstSize", 32, meterBandDscp01.getBurstSize().intValue()); + Assert.assertEquals("Wrong meterBandDscp01.precLevel", 4, meterBandDscp01.getPrecLevel().intValue()); + + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + * Test covers bodies of actions Output, Copy TTL Out, Copy TTL In + */ + @Test + public void testMultipartReplyGroupDescBody01(){ + ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+ + "00 38 "+//len + "01 "+//type + "00 "+//pad + "00 00 00 08 "+//groupId + "00 30 "+//bucketLen + "00 06 "+//bucketWeight + "00 00 00 05 "+//bucketWatchPort + "00 00 00 04 "+//bucketWatchGroup + "00 00 00 00 "+//bucketPad + "00 00 "+//outputType + "00 10 "+//outputLen + "00 00 10 FF "+//outputPort + "FF FF "+//outputMaxLen + "00 00 00 00 00 00 "+//outputPad + "00 0B "+//copyTTLOutType + "00 08 "+//copyTTLOutLen + "00 00 00 00 "+//copyTTLOutPad + "00 0C "+//copyTTLIntType + "00 08 "+//copyTTLIntLen + "00 00 00 00"//copyTTLInPad + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupDescCase messageCase = (MultipartReplyGroupDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupDesc message = messageCase.getMultipartReplyGroupDesc(); + Assert.assertEquals("Wrong type", 1, + message.getGroupDesc().get(0).getType().getIntValue()); + Assert.assertEquals("Wrong groupId", 8, + message.getGroupDesc().get(0).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong bucketWeight", 6, + message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue()); + Assert.assertEquals("Wrong bucketWatchPort", 5, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort(). + getValue().intValue()); + Assert.assertEquals("Wrong bucketWatchGroup", 4, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue()); + + Assert.assertTrue("Wrong outputType",message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(0).getActionChoice() instanceof OutputActionCase); + + Assert.assertEquals("Wrong outputPort", 4351, ((OutputActionCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(0).getActionChoice()) + .getOutputAction().getPort().getValue().intValue()); + + Assert.assertEquals("Wrong outputMaxLen", 65535, ((OutputActionCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(0).getActionChoice()) + .getOutputAction().getMaxLength().intValue()); + + Assert.assertTrue("Wrong copyTtlOutType", message.getGroupDesc().get(0).getBucketsList() + .get(0).getAction().get(1).getActionChoice() instanceof CopyTtlOutCase); + + Assert.assertTrue("Wrong copyTtlInType", message.getGroupDesc().get(0).getBucketsList() + .get(0).getAction().get(2).getActionChoice() instanceof CopyTtlInCase); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + * Test covers bodies of actions Set MPLS TTL , Dec MPLS TTL, Push VLAN. Push MPLS, Push PBB + */ + @Test + public void testMultipartReplyGroupDescBody02(){ + ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+ + "00 40 "+//len + "01 "+//type + "00 "+//pad + "00 00 00 08 "+//groupId + "00 38 "+//bucketLen + "00 06 "+//bucketWeight + "00 00 00 05 "+//bucketWatchPort + "00 00 00 04 "+//bucketWatchGroup + "00 00 00 00 "+//bucketPad + "00 0F "+//setMplsTtlType + "00 08 "+//setMplsTtlLen + "09 "+//setMplsTtlMPLS_TTL + "00 00 00 "+//setMplsTtlPad + "00 10 "+//decMplsTtlType + "00 08 "+//decMplsTtlLen + "00 00 00 00 "+//decMplsTtlPad + "00 11 "+//pushVlanType + "00 08 "+//pushVlanLen + "00 20 "+//pushVlanEthertype + "00 00 "+//pushVlanPad + "00 13 "+//pushMplsType + "00 08 "+//pushMplsLen + "00 FF "+//pushMplsEthertype + "00 00 "+//pushMplsPad + "00 1A "+//pushPbbType + "00 08 "+//pushPbbLen + "0F FF "+//pushPbbEthertype + "00 00"//pushPbbPad + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupDescCase messageCase = (MultipartReplyGroupDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupDesc message = messageCase.getMultipartReplyGroupDesc(); + Assert.assertEquals("Wrong type", 1, + message.getGroupDesc().get(0).getType().getIntValue()); + Assert.assertEquals("Wrong groupId", 8, + message.getGroupDesc().get(0).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong bucketWeight", 6, + message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue()); + Assert.assertEquals("Wrong bucketWatchPort", 5, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().getValue().intValue()); + Assert.assertEquals("Wrong bucketWatchGroup", 4, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue()); + Assert.assertTrue("Wrong setMplsTtlType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(0).getActionChoice() instanceof SetMplsTtlCase); + Assert.assertEquals("Wrong setMplsTtlMPLS_TTL", 9, ((SetMplsTtlCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(0).getActionChoice()).getSetMplsTtlAction() + .getMplsTtl().intValue()); + Assert.assertTrue("Wrong decMplsTtlType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(1).getActionChoice() instanceof DecMplsTtlCase); + Assert.assertTrue("Wrong pushVlanType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(2).getActionChoice() instanceof PushVlanCase); + Assert.assertEquals("Wrong pushVlanEthertype", 32,((PushVlanCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(2).getActionChoice()) + .getPushVlanAction().getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong pushMplsType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(3).getActionChoice() instanceof PushMplsCase); + Assert.assertEquals("Wrong pushMplsEthertype", 255, ((PushMplsCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(3).getActionChoice()) + .getPushMplsAction().getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong pushPbbType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(4).getActionChoice() instanceof PushPbbCase); + Assert.assertEquals("Wrong pushPbbEthertype", 4095, ((PushPbbCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(4).getActionChoice()) + .getPushPbbAction().getEthertype().getValue().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + * Test covers bodies of actions Pop VLAN, Pop PBB, Pop MPLS, Group, Dec NW TTL + */ + @Test + public void testMultipartReplyGroupDescBody03(){ + ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+ + "00 48 "+//len + "01 "+//type + "00 "+//pad + "00 00 00 08 "+//groupId + "00 40 "+//bucketLen + "00 06 "+//bucketWeight + "00 00 00 05 "+//bucketWatchPort + "00 00 00 04 "+//bucketWatchGroup + "00 00 00 00 "+//bucketPad + "00 12 "+//popVlanType + "00 08 "+//popVlanLen + "00 00 00 00 "+//popVlanPad + "00 1B "+//popPbbType + "00 08 "+//popPbbLen + "00 00 00 00 "+//popPbbPad + "00 14 "+//popMplsType + "00 08 "+//popMplsLen + "00 CF "+//popMplsEthertype + "00 00 "+//popMplsPad + "00 15 "+//setQueueType + "00 08 "+//setQueueLen + "00 CF 00 00 "+//setQueueQueueId + "00 16 "+//groupType + "00 08 "+//groupLen + "00 CF 00 00 "+//groupGroupId + "00 18 "+//decNwTtlType + "00 08 "+//decNwTtlLen + "00 00 00 00"//decNwTtlPad + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupDescCase messageCase = (MultipartReplyGroupDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupDesc message = messageCase.getMultipartReplyGroupDesc(); + Assert.assertEquals("Wrong type", 1, message.getGroupDesc().get(0).getType().getIntValue()); + Assert.assertEquals("Wrong groupId", 8, message.getGroupDesc().get(0).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong bucketWeight", 6, + message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue()); + Assert.assertEquals("Wrong bucketWatchPort", 5, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort().getValue().intValue()); + Assert.assertEquals("Wrong bucketWatchGroup", 4, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue()); + Assert.assertTrue("Wrong popVlanType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(0).getActionChoice() instanceof PopVlanCase); + Assert.assertTrue("Wrong popPbbType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(1).getActionChoice() instanceof PopPbbCase); + Assert.assertTrue("Wrong popMplsType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(2).getActionChoice() instanceof PopMplsCase); + Assert.assertEquals("Wrong popMplsEthertype", 207, ((PopMplsCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(2).getActionChoice()) + .getPopMplsAction().getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong setQueueType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(3).getActionChoice() instanceof SetQueueCase); + Assert.assertEquals("Wrong setQueueQueueId", 13565952, ((SetQueueCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(3).getActionChoice()) + .getSetQueueAction().getQueueId().intValue()); + Assert.assertTrue("Wrong groupType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(4).getActionChoice() instanceof GroupCase); + Assert.assertEquals("Wrong groupGroupId", 13565952, ((GroupCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(4).getActionChoice()) + .getGroupAction().getGroupId().intValue()); + Assert.assertTrue("Wrong decNwTtlType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(5).getActionChoice() instanceof DecNwTtlCase); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + * Test covers bodies of actions NW TTL, Experimenter + */ + @Test + public void testMultipartReplyGroupDescBody04(){ + ByteBuf bb = BufferHelper.buildBuffer("00 07 00 01 00 00 00 00 "+ + "00 30 "+//len + "01 "+//type + "00 "+//pad + "00 00 00 08 "+//groupId + "00 28 "+//bucketLen + "00 06 "+//bucketWeight + "00 00 00 05 "+//bucketWatchPort + "00 00 00 04 "+//bucketWatchGroup + "00 00 00 00 "+//bucketPad + "00 17 "+//nwTTlType + "00 08 "+//nwTTlLen + "0E "+//nwTTlnwTTL + "00 00 00 "+//nwTTlPad + "00 19 "+//setFieldType + "00 10 "+//setFieldLen + "80 00 "+//setFieldOXMClass + "00 "+//setFieldOXMField + "04 "+//setFieldOXMLength + "00 00 00 FF "+ //setFieldPort + "00 00 00 00" + ); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(multipartFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 7, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupDescCase messageCase = (MultipartReplyGroupDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupDesc message = messageCase.getMultipartReplyGroupDesc(); + Assert.assertEquals("Wrong type", 1, + message.getGroupDesc().get(0).getType().getIntValue()); + Assert.assertEquals("Wrong groupId", 8, + message.getGroupDesc().get(0).getGroupId().getValue().intValue()); + Assert.assertEquals("Wrong bucketWeight", 6, + message.getGroupDesc().get(0).getBucketsList().get(0).getWeight().intValue()); + Assert.assertEquals("Wrong bucketWatchPort", 5, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchPort(). + getValue().intValue()); + Assert.assertEquals("Wrong bucketWatchGroup", 4, + message.getGroupDesc().get(0).getBucketsList().get(0).getWatchGroup().intValue()); + + Assert.assertTrue("Wrong nwTTlType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(0).getActionChoice() instanceof SetNwTtlCase); + + Assert.assertEquals("Wrong nwTTlnwTTL", 14, ((SetNwTtlCase) message.getGroupDesc().get(0) + .getBucketsList().get(0).getAction().get(0).getActionChoice()) + .getSetNwTtlAction().getNwTtl().intValue()); + + Assert.assertTrue("Wrong setFieldType", message.getGroupDesc().get(0).getBucketsList().get(0) + .getAction().get(1).getActionChoice() instanceof SetFieldCase); + + Assert.assertEquals("Wrong setFieldOXMClass", OpenflowBasicClass.class, + ((SetFieldCase) message.getGroupDesc().get(0).getBucketsList().get(0).getAction().get(1) + .getActionChoice()).getSetFieldAction().getMatchEntry().get(0).getOxmClass()); + + Assert.assertEquals("Wrong setFieldOXMField", InPort.class, + ((SetFieldCase) message.getGroupDesc().get(0).getBucketsList().get(0).getAction().get(1) + .getActionChoice()).getSetFieldAction().getMatchEntry().get(0).getOxmMatchField()); + + MatchEntry entry = ((SetFieldCase) message.getGroupDesc().get(0).getBucketsList().get(0).getAction().get(1) + .getActionChoice()).getSetFieldAction().getMatchEntry().get(0); + Assert.assertEquals("Wrong setFieldOXMValue", 255, ((InPortCase) entry.getMatchEntryValue()) + .getInPort().getPortNumber().getValue().intValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestAggregateInputMessageFactoryTest.java new file mode 100644 index 0000000000..43397a8e7f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestDescInputMessageFactoryTest.java new file mode 100644 index 0000000000..89aea312a3 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestFlowInputMessageFactoryTest.java new file mode 100644 index 0000000000..d8f9d0a004 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestGroupInputMessageFactoryTest.java new file mode 100644 index 0000000000..6f73801c0f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..46c3a13b63 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestMeterInputMessageFactoryTest.java new file mode 100644 index 0000000000..b4f334f931 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestPortStatsInputMessageFactoryTest.java new file mode 100644 index 0000000000..68482e366f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestQueueInputMessageFactoryTest.java new file mode 100644 index 0000000000..6a746eada6 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableFeaturesInputMessageFactoryTest.java new file mode 100644 index 0000000000..600a7aafd2 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/MultipartRequestTableInputMessageFactoryTest.java new file mode 100644 index 0000000000..8719dc2bb8 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactoryTest.java new file mode 100644 index 0000000000..c90a2ea91d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10ErrorMessageFactoryTest.java @@ -0,0 +1,222 @@ +/* + * 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.ErrorMessage; + +/** + * @author michal.polkorab + */ +public class OF10ErrorMessageFactoryTest { + private OFDeserializer errorFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + errorFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 1, ErrorMessage.class)); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithoutData() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 00"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "INCOMPATIBLE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 01 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 1, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADREQUEST", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADVERSION", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 02 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 2, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADACTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADTYPE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 03 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "FLOWMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "ALLTABLESFULL", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 04 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 4, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "PORTMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADPORT", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 05 00 00"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 5, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 0, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "QUEUEOPFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "BADPORT", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + } + + /** + * Test of {@link ErrorMessageFactory} for correct translation into POJO + * - not existing code used + */ + @Test + public void testWithoutData2() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 FF FF"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 01 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 1, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADREQUEST", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 02 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 2, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "BADACTION", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 03 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "FLOWMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 04 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 4, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "PORTMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + + bb = BufferHelper.buildBuffer("00 05 FF FF"); + builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 5, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 65535, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "QUEUEOPFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertNull("Data is not null", builtByFactory.getData()); + } + + /** + * Test of {@link OF10ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithData() { + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 01 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 1, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "HELLOFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "EPERM", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + + /** + * Test of {@link OF10ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithIncorrectTypeEnum() { + ByteBuf bb = BufferHelper.buildBuffer("00 0A 00 05 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 10, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 5, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "UNKNOWN_TYPE", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + + /** + * Test of {@link OF10ErrorMessageFactory} for correct translation into POJO + */ + @Test + public void testWithIncorrectCodeEnum() { + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 06 00 01 02 03"); + ErrorMessage builtByFactory = BufferHelper.deserialize(errorFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 3, builtByFactory.getType().intValue()); + Assert.assertEquals("Wrong code", 6, builtByFactory.getCode().intValue()); + Assert.assertEquals("Wrong type string", "FLOWMODFAILED", builtByFactory.getTypeString()); + Assert.assertEquals("Wrong code string", "UNKNOWN_CODE", builtByFactory.getCodeString()); + Assert.assertArrayEquals("Wrong data", new byte[]{0x00, 0x01, 0x02, 0x03}, builtByFactory.getData()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java new file mode 100644 index 0000000000..594ca829a1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesReplyMessageFactoryTest.java @@ -0,0 +1,131 @@ +/* + * 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.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.features.reply.PhyPort; + +/** + * @author michal.polkorab + * + */ +public class OF10FeaturesReplyMessageFactoryTest { + + private OFDeserializer featuresFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + featuresFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 6, GetFeaturesOutput.class)); + } + + /** + * Testing {@link OF10FeaturesReplyMessageFactory} for correct translation into POJO + */ + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 " + + "00 00 00 FF 00 00 0F FF " + + "00 10 01 01 05 01 04 02 41 4C 4F 48 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 7F 00 00 02 00 " + + "00 00 0F FF 00 00 00 00 00 00 03 0C 00 00 08 88"); + GetFeaturesOutput builtByFactory = BufferHelper.deserialize(featuresFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong datapathId", 0x0001020304050607L, builtByFactory.getDatapathId().longValue()); + Assert.assertEquals("Wrong n-buffers", 0x00010203L, builtByFactory.getBuffers().longValue()); + Assert.assertEquals("Wrong n-tables", 0x01, builtByFactory.getTables().shortValue()); + Assert.assertEquals("Wrong capabilities", new CapabilitiesV10(true, true, true, true, true, true, true, true), + builtByFactory.getCapabilitiesV10()); + Assert.assertEquals("Wrong actions", new ActionTypeV10(true, true, true, true, true, true, true, + true, true, true, true, true, false), builtByFactory.getActionsV10()); + PhyPort port = builtByFactory.getPhyPort().get(0); + Assert.assertEquals("Wrong port - port-no", 16, port.getPortNo().intValue()); + Assert.assertEquals("Wrong port - hw-addr", new MacAddress("01:01:05:01:04:02"), port.getHwAddr()); + Assert.assertEquals("Wrong port - name", new String("ALOHA"), port.getName()); + Assert.assertEquals("Wrong port - config", new PortConfigV10(true, true, true, true, true, true, true), + port.getConfigV10()); + Assert.assertEquals("Wrong port - state", new PortStateV10(false, false, false, false, true, false, true, false), + port.getStateV10()); + Assert.assertEquals("Wrong port - curr", new PortFeaturesV10(true, true, true, true, true, true, true, + true, true, true, true, true), port.getCurrentFeaturesV10()); + Assert.assertEquals("Wrong port - advertised", new PortFeaturesV10(false, false, false, false, false, false, + false, false, false, false, false, false), port.getAdvertisedFeaturesV10()); + Assert.assertEquals("Wrong port - supported", new PortFeaturesV10(true, true, false, false, false, false, + false, true, false, true, false, false), port.getSupportedFeaturesV10()); + Assert.assertEquals("Wrong port - peer", new PortFeaturesV10(true, false, false, false, false, false, false, + false, true, false, false, true), port.getPeerFeaturesV10()); + } + + /** + * Testing {@link OF10FeaturesReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testWithTwoPortsSet() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 " + + "00 00 00 8B 00 00 03 B5 " + + "00 10 01 01 05 01 04 02 41 4C 4F 48 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 01 " + + "00 00 00 31 00 00 04 42 00 00 03 0C 00 00 08 88 " + + "00 10 01 01 05 01 04 02 41 4C 4F 48 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 00 00 00 00 " + + "00 00 00 31 00 00 04 42 00 00 03 0C 00 00 08 88"); + GetFeaturesOutput builtByFactory = BufferHelper.deserialize(featuresFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong ports size", 2, builtByFactory.getPhyPort().size()); + PhyPort port = builtByFactory.getPhyPort().get(0); + Assert.assertEquals("Wrong port - port-no", 16, port.getPortNo().intValue()); + Assert.assertEquals("Wrong port - hw-addr", new MacAddress("01:01:05:01:04:02"), port.getHwAddr()); + Assert.assertEquals("Wrong port - name", new String("ALOHA"), port.getName()); + Assert.assertEquals("Wrong port - config", new PortConfigV10(false, false, false, false, false, false, false), + port.getConfigV10()); + Assert.assertEquals("Wrong port - state", new PortStateV10(false, true, false, true, true, true, false, true), + port.getStateV10()); + port = builtByFactory.getPhyPort().get(1); + Assert.assertEquals("Wrong port - state", new PortStateV10(false, false, false, false, false, false, true, false), + port.getStateV10()); + } + + /** + * Testing {@link OF10FeaturesReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testWithNoPortsSet() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 " + + "00 00 00 00 00 00 00 00"); + GetFeaturesOutput builtByFactory = BufferHelper.deserialize(featuresFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong capabilities", new CapabilitiesV10(false, false, false, false, false, false, false, false), + builtByFactory.getCapabilitiesV10()); + Assert.assertEquals("Wrong actions", new ActionTypeV10(false, false, false, false, false, false, false, + false, false, false, false, false, false), builtByFactory.getActionsV10()); + Assert.assertEquals("Wrong ports size", 0, builtByFactory.getPhyPort().size()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FeaturesRequestMessageFactoryTest.java new file mode 100644 index 0000000000..97682d8908 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowModInputMessageFactoryTest.java new file mode 100644 index 0000000000..9ff3f05585 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactoryTest.java new file mode 100644 index 0000000000..c98b14f584 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10FlowRemovedMessageFactoryTest.java @@ -0,0 +1,64 @@ +/* + * 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.FlowRemovedMessage; + +/** + * @author michal.polkorab + */ +public class OF10FlowRemovedMessageFactoryTest { + + 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.OF10_VERSION_ID, 11, FlowRemovedMessage.class)); + } + + /** + * Testing {@link OF10FlowRemovedMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 24 08 D1 00 20 AA BB CC DD EE FF " + + "AA BB CC DD EE FF 00 05 10 00 00 08 07 06 00 00 10 11 12 13 01 02 03 04 "//36 + + "50 50 20 20 "// match + + "00 01 02 03 04 05 06 07 00 03 01 00 00 00 00 02 " + + "00 00 00 05 00 08 00 00 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07");//41 + FlowRemovedMessage builtByFactory = BufferHelper.deserialize(flowFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong cookie", 0x0001020304050607L, builtByFactory.getCookie().longValue()); + Assert.assertEquals("Wrong priority", 0x03, builtByFactory.getPriority().intValue()); + Assert.assertEquals("Wrong reason", 0x01, builtByFactory.getReason().getIntValue()); + Assert.assertEquals("Wrong durationSec", 0x00000002L, builtByFactory.getDurationSec().longValue()); + Assert.assertEquals("Wrong durationNsec", 0x00000005L, builtByFactory.getDurationNsec().longValue()); + Assert.assertEquals("Wrong idleTimeout", 0x08, builtByFactory.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong packetCount", 0x0001020304050607L, builtByFactory.getPacketCount().longValue()); + Assert.assertEquals("Wrong byteCount", 0x0001020304050607L, builtByFactory.getByteCount().longValue()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10GetQueueConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..15873bd158 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactoryTest.java new file mode 100644 index 0000000000..baee268809 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10HelloMessageFactoryTest.java @@ -0,0 +1,73 @@ +/* + * 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.HelloMessage; + +/** + * @author michal.polkorab + */ +public class OF10HelloMessageFactoryTest { + + private OFDeserializer helloFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + helloFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 0, HelloMessage.class)); + } + + /** + * Testing {@link OF10HelloMessageFactory} for correct translation into POJO + */ + @Test + public void testWithoutElements() { + ByteBuf bb = BufferHelper.buildBuffer(); + HelloMessage builtByFactory = BufferHelper.deserialize( + helloFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertNull("Wrong elements", builtByFactory.getElements()); + } + + /** + * Testing {@link OF10HelloMessageFactory} for correct translation into POJO + */ + @Test + public void testWithElements() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 " // type + + "00 0c " // length + + "00 00 00 11 " // bitmap 1 + + "00 00 00 00 " // bitmap 2 + + "00 00 00 00" // padding + ); + HelloMessage builtByFactory = BufferHelper.deserialize( + helloFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertNull("Wrong elements", builtByFactory.getElements()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactoryTest.java new file mode 100644 index 0000000000..53ed80fcd0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketInMessageFactoryTest.java @@ -0,0 +1,69 @@ +/* + * 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.util.ByteBufUtils; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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; + +/** + * @author michal.polkorab + */ +public class OF10PacketInMessageFactoryTest { + + private OFDeserializer packetInFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + packetInFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 10, PacketInMessage.class)); + } + + /** + * Testing {@link OF10PacketInMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 01 02 01 02 00 00 01 02 03 04"); + PacketInMessage builtByFactory = BufferHelper.deserialize(packetInFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong bufferID", 0x00010203L, builtByFactory.getBufferId().longValue()); + Assert.assertEquals("Wrong totalLength", 0x0102, builtByFactory.getTotalLen().intValue()); + Assert.assertEquals("Wrong inPort", 0x0102, builtByFactory.getInPort().intValue()); + Assert.assertEquals("Wrong reason", PacketInReason.OFPRNOMATCH, builtByFactory.getReason()); + Assert.assertArrayEquals("Wrong data", ByteBufUtils.hexStringToBytes("01 02 03 04"), builtByFactory.getData()); + } + + /** + * Testing {@link OF10PacketInMessageFactory} for correct translation into POJO + */ + @Test + public void testWithNoAdditionalData(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 01 02 01 02 00 00"); + PacketInMessage builtByFactory = BufferHelper.deserialize(packetInFactory, bb); + + Assert.assertNull("Wrong data", builtByFactory.getData()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PacketOutInputMessageFactoryTest.java new file mode 100644 index 0000000000..93425026d0 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortModInputMessageFactoryTest.java new file mode 100644 index 0000000000..660ab5ce1e --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java new file mode 100644 index 0000000000..9467e8d127 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10PortStatusMessageFactoryTest.java @@ -0,0 +1,76 @@ +/* + * 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.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; + +/** + * @author michal.polkorab + * + */ +public class OF10PortStatusMessageFactoryTest { + + private OFDeserializer statusFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + statusFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 12, PortStatusMessage.class)); + } + + /** + * Testing {@link OF10PortStatusMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 00 00 00 00 00 " + + "00 10 01 01 05 01 04 02 41 4C 4F 48 41 00 00 00 00 00 00 00 00 00 00 " + + "00 00 00 00 15 00 00 00 01 00 00 00 31 00 00 04 42 00 00 03 0C 00 00 08 88"); + PortStatusMessage builtByFactory = BufferHelper.deserialize(statusFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong reason", PortReason.OFPPRADD, builtByFactory.getReason()); + Assert.assertEquals("Wrong port - port-no", 16, builtByFactory.getPortNo().intValue()); + Assert.assertEquals("Wrong builtByFactory - hw-addr", new MacAddress("01:01:05:01:04:02"), builtByFactory.getHwAddr()); + Assert.assertEquals("Wrong builtByFactory - name", new String("ALOHA"), builtByFactory.getName()); + Assert.assertEquals("Wrong builtByFactory - config", new PortConfigV10(true, false, false, true, false, false, true), + builtByFactory.getConfigV10()); + Assert.assertEquals("Wrong builtByFactory - state", new PortStateV10(false, true, false, false, false, false, true, false), + builtByFactory.getStateV10()); + Assert.assertEquals("Wrong builtByFactory - curr", new PortFeaturesV10(false, false, false, false, true, true, true, + false, false, false, false, false), builtByFactory.getCurrentFeaturesV10()); + Assert.assertEquals("Wrong builtByFactory - advertised", new PortFeaturesV10(false, false, true, true, false, false, + false, false, false, false, true, false), builtByFactory.getAdvertisedFeaturesV10()); + Assert.assertEquals("Wrong builtByFactory - supbuiltByFactoryed", new PortFeaturesV10(true, true, false, false, false, false, + false, true, false, true, false, false), builtByFactory.getSupportedFeaturesV10()); + Assert.assertEquals("Wrong builtByFactory - peer", new PortFeaturesV10(true, false, false, false, false, false, false, + false, true, false, false, true), builtByFactory.getPeerFeaturesV10()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..c4ccb4e341 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java @@ -0,0 +1,79 @@ +/* + * 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.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.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; + +/** + * @author michal.polkorab + * + */ +public class OF10QueueGetConfigReplyMessageFactoryTest { + + private OFDeserializer queueFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + queueFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 21, GetQueueConfigOutput.class)); + } + + /** + * Testing of {@link OF10QueueGetConfigReplyMessageFactory} for correct + * translation into POJO + */ + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 00 00 00 00 00 " + + "00 00 00 08 00 10 00 00 00 00 00 08 00 00 00 00 " + + "00 00 00 02 00 28 00 00 00 01 00 10 00 00 00 00 00 20 00 00 00 00 00 00 " + + "00 01 00 10 00 00 00 00 00 30 00 00 00 00 00 00"); + GetQueueConfigOutput builtByFactory = BufferHelper.deserialize( + queueFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong port", 1, builtByFactory.getPort().getValue().intValue()); + Assert.assertEquals("Wrong queues size", 2, builtByFactory.getQueues().size()); + Queues queue1 = builtByFactory.getQueues().get(0); + Queues queue2 = builtByFactory.getQueues().get(1); + Assert.assertEquals("Wrong queueId", 8, queue1.getQueueId().getValue().intValue()); + Assert.assertEquals("Wrong queue - # properties", 1, queue1.getQueueProperty().size()); + Assert.assertEquals("Wrong queue - wrong property", QueueProperties.OFPQTNONE, + queue1.getQueueProperty().get(0).getProperty()); + Assert.assertEquals("Wrong queueId", 2, queue2.getQueueId().getValue().intValue()); + Assert.assertEquals("Wrong queue - # properties", 2, queue2.getQueueProperty().size()); + Assert.assertEquals("Wrong queue - wrong property", QueueProperties.OFPQTMINRATE, + queue2.getQueueProperty().get(0).getProperty()); + Assert.assertEquals("Wrong queue - wrong property", QueueProperties.OFPQTMINRATE, + queue2.getQueueProperty().get(1).getProperty()); + RateQueueProperty rate1 = queue2.getQueueProperty().get(0).getAugmentation(RateQueueProperty.class); + RateQueueProperty rate2 = queue2.getQueueProperty().get(1).getAugmentation(RateQueueProperty.class); + Assert.assertEquals("Wrong queue - wrong property rate", 32, rate1.getRate().intValue()); + Assert.assertEquals("Wrong queue - wrong property rate", 48, rate2.getRate().intValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactoryTest.java new file mode 100644 index 0000000000..ce43d0f16f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsReplyMessageFactoryTest.java @@ -0,0 +1,314 @@ +/* + * 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 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.action.rev150203.action.grouping.action.choice.OutputActionCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanVidCase; +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.protocol.rev130731.MultipartReplyMessage; +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.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.flow._case.MultipartReplyFlow; +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.queue._case.MultipartReplyQueue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.table._case.MultipartReplyTable; + +/** + * @author michal.polkorab + * + */ +public class OF10StatsReplyMessageFactoryTest { + + private OFDeserializer statsFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + statsFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, 17, MultipartReplyMessage.class)); + } + + /** + * Testing OF10StatsReplyMessageFactory (Desc) for correct deserialization + */ + @Test + public void testDesc() { + final int DESC_STR_LEN = 256; + final int SERIAL_NUM_LEN = 32; + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 00"); + + String mfrDesc = "Manufacturer description"; + byte[] mfrDescBytes = new byte[256]; + mfrDescBytes = mfrDesc.getBytes(); + bb.writeBytes(mfrDescBytes); + bb.writeZero(DESC_STR_LEN - mfrDescBytes.length); + + String hwDesc = "Hardware description"; + byte[] hwDescBytes = new byte[256]; + hwDescBytes = hwDesc.getBytes(); + bb.writeBytes(hwDescBytes); + bb.writeZero(DESC_STR_LEN - hwDescBytes.length); + + String swDesc = "Software description"; + byte[] swDescBytes = new byte[256]; + swDescBytes = swDesc.getBytes(); + bb.writeBytes(swDescBytes); + bb.writeZero(DESC_STR_LEN - swDescBytes.length); + + String serialNum = "SN0123456789"; + byte[] serialNumBytes = new byte[32]; + serialNumBytes = serialNum.getBytes(); + bb.writeBytes(serialNumBytes); + bb.writeZero(SERIAL_NUM_LEN - serialNumBytes.length); + + String dpDesc = "switch3 in room 3120"; + byte[] dpDescBytes = new byte[256]; + dpDescBytes = dpDesc.getBytes(); + bb.writeBytes(dpDescBytes); + bb.writeZero(DESC_STR_LEN - dpDescBytes.length); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE().booleanValue()); + MultipartReplyDescCase messageCase = (MultipartReplyDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyDesc message = messageCase.getMultipartReplyDesc(); + Assert.assertEquals("Wrong mfrDesc", "Manufacturer description", message.getMfrDesc()); + Assert.assertEquals("Wrong hwDesc", "Hardware description", message.getHwDesc()); + Assert.assertEquals("Wrong swDesc", "Software description", message.getSwDesc()); + Assert.assertEquals("Wrong serialNum", "SN0123456789", message.getSerialNum()); + Assert.assertEquals("Wrong dpDesc", "switch3 in room 3120", message.getDpDesc()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + + /** + * Testing OF10StatsReplyMessageFactory (Flow) for correct deserialization + */ + @Test + public void testFlow() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 01 00 68 01 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 00 00 00 00 00 00 " + + "00 00 00 02 00 00 00 03 00 04 00 05 00 06 00 00 00 00 00 00 " + + "FF 01 02 03 04 05 06 07 FF 01 02 03 04 05 06 07 FF 00 00 00 00 00 00 20 " + + "00 00 00 08 00 01 00 02 00 01 00 08 00 03 00 00"); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0x01, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE().booleanValue()); + MultipartReplyFlowCase messageCase = (MultipartReplyFlowCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyFlow message = messageCase.getMultipartReplyFlow(); + Assert.assertEquals("Wrong tableId", 1, message.getFlowStats().get(0).getTableId().intValue()); + Assert.assertEquals("Wrong durationSec", 2, message.getFlowStats().get(0).getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 3, message.getFlowStats().get(0).getDurationNsec().intValue()); + Assert.assertEquals("Wrong priority", 4, message.getFlowStats().get(0).getPriority().intValue()); + Assert.assertEquals("Wrong idleTimeOut", 5, message.getFlowStats().get(0).getIdleTimeout().intValue()); + Assert.assertEquals("Wrong hardTimeOut", 6, message.getFlowStats().get(0).getHardTimeout().intValue()); + Assert.assertEquals("Wrong cookie", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}), + message.getFlowStats().get(0).getCookie()); + Assert.assertEquals("Wrong packetCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}), + message.getFlowStats().get(0).getPacketCount()); + Assert.assertEquals("Wrong byteCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20}), + message.getFlowStats().get(0).getByteCount()); + Action action1 = message.getFlowStats().get(0).getAction().get(0); + Assert.assertTrue("Wrong action type", action1.getActionChoice() instanceof OutputActionCase); + Assert.assertEquals("Wrong action port", 1, ((OutputActionCase) action1.getActionChoice()) + .getOutputAction().getPort().getValue().intValue()); + Assert.assertEquals("Wrong action port", 2, ((OutputActionCase) action1.getActionChoice()) + .getOutputAction().getMaxLength().intValue()); + Action action2 = message.getFlowStats().get(0).getAction().get(1); + Assert.assertTrue("Wrong action type",action2.getActionChoice() instanceof SetVlanVidCase); + Assert.assertEquals("Wrong action port", 3, ((SetVlanVidCase) action2.getActionChoice()) + .getSetVlanVidAction().getVlanVid().intValue()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + + /** + * Testing OF10StatsReplyMessageFactory (Aggregate) for correct deserialization + */ + @Test + public void testAggregate() { + ByteBuf bb = BufferHelper.buildBuffer("00 02 00 01 " + + "FF 01 02 03 04 05 06 07 FF 00 00 00 00 00 00 20 00 00 00 30 00 00 00 00"); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0x02, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE().booleanValue()); + MultipartReplyAggregateCase messageCase = (MultipartReplyAggregateCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyAggregate message = messageCase.getMultipartReplyAggregate(); + Assert.assertEquals("Wrong packet-count", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}), + message.getPacketCount()); + Assert.assertEquals("Wrong byte-count", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20}), + message.getByteCount()); + Assert.assertEquals("Wrong flow-count", 48, message.getFlowCount().intValue()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + + /** + * Testing OF10StatsReplyMessageFactory (Table) for correct deserialization + */ + @Test + public void testTable() { + ByteBuf bb = BufferHelper.buildBuffer("00 03 00 01 " + + "08 00 00 00 4A 41 4D 45 53 20 42 4F 4E 44 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 30 00 00 00 10 FF 01 01 01 01 01 01 01 FF 01 01 01 01 01 01 00"); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0x03, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + + MultipartReplyTableCase messageCase = (MultipartReplyTableCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyTable message = messageCase.getMultipartReplyTable(); + Assert.assertEquals("Wrong tableId", 8, message.getTableStats().get(0).getTableId().intValue()); + Assert.assertEquals("Wrong name", "JAMES BOND", message.getTableStats().get(0).getName()); + Assert.assertEquals("Wrong wildcards", new FlowWildcardsV10(false, false, false, false, false, false, false, + false, false, false), message.getTableStats().get(0).getWildcards()); + Assert.assertEquals("Wrong src-mask", 32, message.getTableStats().get(0).getNwSrcMask().intValue()); + Assert.assertEquals("Wrong dst-mask", 32, message.getTableStats().get(0).getNwDstMask().intValue()); + Assert.assertEquals("Wrong max-entries", 48, message.getTableStats().get(0).getMaxEntries().longValue()); + Assert.assertEquals("Wrong activeCount", 16, message.getTableStats().get(0).getActiveCount().longValue()); + Assert.assertEquals("Wrong lookupCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getTableStats().get(0).getLookupCount()); + Assert.assertEquals("Wrong matchedCount", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}), + message.getTableStats().get(0).getMatchedCount()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + + /** + * Testing OF10StatsReplyMessageFactory (Port) for correct deserialization + */ + @Test + public void testPort() { + ByteBuf bb = BufferHelper.buildBuffer("00 04 00 01 " + + "00 FF 00 00 00 00 00 00 " + + "FF 01 01 01 01 01 01 01 FF 02 02 02 02 02 02 02 " + + "FF 02 03 02 03 02 03 02 FF 02 03 02 03 02 03 02 " + + "FF 02 03 02 03 02 03 02 FF 02 03 02 03 02 03 02 " + + "FF 02 03 02 03 02 03 02 FF 02 03 02 03 02 03 02 " + + "FF 02 03 02 03 02 03 02 FF 02 03 02 03 02 03 02 FF 02 03 02 03 02 03 02 " + + "FF 02 03 02 03 02 03 02"); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0x04, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyPortStatsCase messageCase = (MultipartReplyPortStatsCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyPortStats message = messageCase.getMultipartReplyPortStats(); + Assert.assertEquals("Wrong portNo", 255, message.getPortStats().get(0).getPortNo().intValue()); + Assert.assertEquals("Wrong rxPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}), + message.getPortStats().get(0).getRxPackets()); + Assert.assertEquals("Wrong txPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getPortStats().get(0).getTxPackets()); + Assert.assertEquals("Wrong rxBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxBytes()); + Assert.assertEquals("Wrong txBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxBytes()); + Assert.assertEquals("Wrong rxDropped", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxDropped()); + Assert.assertEquals("Wrong txDropped", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxDropped()); + Assert.assertEquals("Wrong rxErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxErrors()); + Assert.assertEquals("Wrong txErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getTxErrors()); + Assert.assertEquals("Wrong rxFrameErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxFrameErr()); + Assert.assertEquals("Wrong rxOverErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxOverErr()); + Assert.assertEquals("Wrong rxCrcErr", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getRxCrcErr()); + Assert.assertEquals("Wrong collisions", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getPortStats().get(0).getCollisions()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + + /** + * Testing OF10StatsReplyMessageFactory (Queue) for correct deserialization + */ + @Test + public void testQueue() { + ByteBuf bb = BufferHelper.buildBuffer("00 05 00 00 " + + "00 FF 00 00 00 00 00 10 " + + "FF 02 03 02 03 02 03 02 " + + "FF 02 02 02 02 02 02 02 " + + "FF 02 03 02 03 02 03 02"); + + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(statsFactory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 0x05, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyQueueCase messageCase = (MultipartReplyQueueCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyQueue message = messageCase.getMultipartReplyQueue(); + Assert.assertEquals("Wrong portNo", 255, message.getQueueStats().get(0).getPortNo().intValue()); + Assert.assertEquals("Wrong queueId", 16, message.getQueueStats().get(0).getQueueId().intValue()); + Assert.assertEquals("Wrong txBytes", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getQueueStats().get(0).getTxBytes()); + Assert.assertEquals("Wrong txPackets", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02}), + message.getQueueStats().get(0).getTxPackets()); + Assert.assertEquals("Wrong txErrors", + new BigInteger(1, new byte[]{(byte) 0xFF, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02}), + message.getQueueStats().get(0).getTxErrors()); + Assert.assertTrue("Unread data", bb.readableBytes() == 0); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputAggregateFactoryTest.java new file mode 100644 index 0000000000..5c8ce2159c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputDescFactoryTest.java new file mode 100644 index 0000000000..545d1d7b93 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputFlowFactoryTest.java new file mode 100644 index 0000000000..613ff4a109 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputPortStatsFactoryTest.java new file mode 100644 index 0000000000..afe70c929f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputQueueFactoryTest.java new file mode 100644 index 0000000000..39c571cd7c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/OF10StatsRequestInputTableFactoryTest.java new file mode 100644 index 0000000000..bc9bdf7783 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactoryTest.java new file mode 100644 index 0000000000..105329dbe2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketInMessageFactoryTest.java @@ -0,0 +1,64 @@ +/* + * 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.util.ByteBufUtils; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +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.TableId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; + +/** + * @author timotej.kubas + * + */ +public class PacketInMessageFactoryTest { + + private OFDeserializer packetInFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + packetInFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 10, PacketInMessage.class)); + } + + /** + * Testing {@link PacketInMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 01 02 01 04 00 01 02 03 04 05 06 07 00 01 00 0C" + + " 80 00 02 04 00 00 00 01 00 00 00 00 00 00 01 02 03 04"); + PacketInMessage builtByFactory = BufferHelper.deserialize(packetInFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + + Assert.assertEquals("Wrong bufferID", 0x00010203L, builtByFactory.getBufferId().longValue()); + Assert.assertEquals("Wrong totalLength", 0x0102, builtByFactory.getTotalLen().intValue()); + Assert.assertEquals("Wrong reason", PacketInReason.OFPRACTION, builtByFactory.getReason()); + Assert.assertEquals("Wrong tableID", new TableId(4L), builtByFactory.getTableId()); + Assert.assertEquals("Wrong cookie", 0x0001020304050607L, builtByFactory.getCookie().longValue()); + Assert.assertArrayEquals("Wrong data", ByteBufUtils.hexStringToBytes("01 02 03 04"), builtByFactory.getData()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PacketOutInputMessageFactoryTest.java new file mode 100644 index 0000000000..8a2b1e98bf --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortModInputMessageFactoryTest.java new file mode 100644 index 0000000000..b27bb27913 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java new file mode 100644 index 0000000000..84653207f9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/PortStatusMessageFactoryTest.java @@ -0,0 +1,121 @@ +/* + * 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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class PortStatusMessageFactoryTest { + + private OFDeserializer statusFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + statusFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 12, PortStatusMessage.class)); + } + + /** + * Testing {@link PortStatusMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("01 " + //reason + "00 00 00 00 00 00 00 " + //padding + "00 01 02 03 " + //port no + "00 00 00 00 " + //padding in ofp_port1 + "08 00 27 00 B0 EB " + //mac address + "00 00 " + //padding in ofp_port2 + "73 31 2d 65 74 68 31 00 00 00 00 00 00 00 00 00 " + // port name, String "s1-eth1" + "00 00 00 41 " + //port config + "00 00 00 05 " + //port state + "00 00 00 81 " + //current features + "00 00 00 A1 " + //advertised features + "00 00 00 B1 " + //supported features + "00 00 00 81 " + //peer features + "00 00 00 81 " + //curr speed + "00 00 00 80" //max speed + ); + + PortStatusMessage builtByFactory = BufferHelper.deserialize(statusFactory, bb); + + 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 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()); + Assert.assertEquals("Wrong currentFeatures", new PortFeatures(false, false, false, false, + false, true, false, false, false, true, false, false, + false, false, false, false), builtByFactory.getCurrentFeatures()); + Assert.assertEquals("Wrong advertisedFeatures", new PortFeatures(false, false, false, false, + false, true, true, false, false, true, false, false, + false, false, false, false), builtByFactory.getAdvertisedFeatures()); + Assert.assertEquals("Wrong supportedFeatures", new PortFeatures(false, false, false, false, + false, true, true, true, false, true, false, false, + false, false, false, false), builtByFactory.getSupportedFeatures()); + Assert.assertEquals("Wrong peerFeatures", new PortFeatures(false, false, false, false, + false, true, false, false, false, true, false, false, + false, false, false, false), builtByFactory.getPeerFeatures()); + Assert.assertEquals("Wrong currSpeed", 129L, builtByFactory.getCurrSpeed().longValue()); + Assert.assertEquals("Wrong maxSpeed", 128L, builtByFactory.getMaxSpeed().longValue()); + } + + /** + * Testing {@link PortStatusMessageFactory} for correct translation into POJO + */ + @Test + public void testWithDifferentBitmaps(){ + ByteBuf bb = BufferHelper.buildBuffer("01 00 00 00 00 00 00 00 " + //reason, padding + "00 01 02 03 00 00 00 00 " + //port no, padding + "08 00 27 00 B0 EB 00 00 " + //mac address, padding + "73 31 2d 65 74 68 31 00 00 00 00 00 00 00 00 00 " + // port name, String "s1-eth1" + "00 00 00 24 " + //port config + "00 00 00 02 " + //port state + "00 00 00 81 00 00 00 A1 " + //current + advertised features + "00 00 FF FF 00 00 00 00 " + //supported + peer features + "00 00 00 81 00 00 00 80" //curr speed, max speed + ); + PortStatusMessage message = BufferHelper.deserialize(statusFactory, bb); + + Assert.assertEquals("Wrong portConfig", new PortConfig(true, false, true, false), message.getConfig()); + Assert.assertEquals("Wrong portState", new PortState(true, false, false), message.getState()); + Assert.assertEquals("Wrong supportedFeatures", new PortFeatures(true, true, true, true, + true, true, true, true, true, true, true, true, true, true, true, true), + message.getSupportedFeatures()); + Assert.assertEquals("Wrong peerFeatures", new PortFeatures(false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + false, false), message.getPeerFeatures()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryMultiTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryMultiTest.java new file mode 100644 index 0000000000..f8102e5fc2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryMultiTest.java @@ -0,0 +1,114 @@ +/* + * 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 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.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.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 timotej.kubas + * @author michal.polkorab + */ +public class QueueGetConfigReplyMessageFactoryMultiTest { + + private OFDeserializer queueFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + queueFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 23, GetQueueConfigOutput.class)); + } + + /** + * Testing of {@link QueueGetConfigReplyMessageFactory} for correct + * translation into POJO + */ + @Test + public void test() { + ByteBuf bb = BufferHelper.buildBuffer("00 01 02 03 " + // port + "00 00 00 00 " + // padding + "00 00 00 01 " + // queueId + "00 00 00 01 " + // port + "00 20 " + // length + "00 00 00 00 00 00 " + // pad + "00 02 " + // property + "00 10 " + // length + "00 00 00 00 " + // pad + "00 05 " + // rate + "00 00 00 00 00 00 " + // pad + "00 00 00 02 " + // queueId + "00 00 00 02 " + // port + "00 20 " + // length + "00 00 00 00 00 00 " + // pad + "00 02 " + // property + "00 10 " + // length + "00 00 00 00 " + // pad + "00 05 " + // rate + "00 00 00 00 00 00" // pad + ); + + GetQueueConfigOutput builtByFactory = BufferHelper.deserialize( + queueFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong port", 66051L, builtByFactory.getPort().getValue().longValue()); + Assert.assertEquals("Wrong queues", createQueuesList(), builtByFactory.getQueues()); + } + + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..3be61213d8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactoryTest.java @@ -0,0 +1,88 @@ +/* + * 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 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.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.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 timotej.kubas + * @author michal.polkorab + */ +public class QueueGetConfigReplyMessageFactoryTest { + + private OFDeserializer queueFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + queueFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 23, GetQueueConfigOutput.class)); + } + + /** + * Testing {@link QueueGetConfigReplyMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 03 00 00 00 00 00 00 00 01 00 00 00 03 00 20 00 00 00 00 00 00 00 02 00 10 00 00 00 00 00 05 00 00 00 00 00 00"); + GetQueueConfigOutput builtByFactory = BufferHelper.deserialize(queueFactory, bb); + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong port", 3L, builtByFactory.getPort().getValue().longValue()); + Assert.assertEquals("Wrong queues", builtByFactory.getQueues(), createQueuesList()); + } + + private static List createQueuesList(){ + List queuesList = new ArrayList<>(); + QueuesBuilder qb = new QueuesBuilder(); + qb.setQueueId(new QueueId(1L)); + qb.setPort(new PortNumber(3L)); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactoryTest.java new file mode 100644 index 0000000000..318f85aceb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleReplyMessageFactoryTest.java @@ -0,0 +1,56 @@ +/* + * 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.RoleRequestOutput; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class RoleReplyMessageFactoryTest { + + private OFDeserializer roleFactory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + roleFactory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 25, RoleRequestOutput.class)); + } + + /** + * Testing of {@link RoleReplyMessageFactory} for correct translation into POJO + */ + @Test + public void test(){ + ByteBuf bb = BufferHelper.buildBuffer("00 00 00 02 00 00 00 00 00 01 02 03 04 05 06 07"); + RoleRequestOutput builtByFactory = BufferHelper.deserialize(roleFactory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + + Assert.assertEquals("Wrong role", 0x02, builtByFactory.getRole().getIntValue()); + Assert.assertEquals("Wrong generationId", 0x01020304050607L, builtByFactory.getGenerationId().longValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/RoleRequestInputMessageFactoryTest.java new file mode 100644 index 0000000000..368aca40a6 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetAsyncInputMessageFactoryTest.java new file mode 100644 index 0000000000..e5c1d9afa0 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/SetConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..fe4b4bb80e --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/TableModInputMessageFactoryTest.java new file mode 100644 index 0000000000..3b63748ead --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java new file mode 100644 index 0000000000..aaa94680c7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/VendorMessageFactoryTest.java @@ -0,0 +1,47 @@ +/* + * 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.impl.deserialization.factories; + +import io.netty.buffer.ByteBuf; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.util.ByteBufUtils; + +/** + * @author michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class VendorMessageFactoryTest { + + @Mock DeserializerRegistry registry; + @Mock ExperimenterMessageFactory deserializer; + + /** + * Tests {@link VendorMessageFactory#deserialize(ByteBuf)} + */ + @Test + public void test() { + 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", 4, buffer.readableBytes()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java new file mode 100644 index 0000000000..5acb3f326d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyExperimenterTest.java @@ -0,0 +1,57 @@ +/* + * 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.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.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 + * + */ +@RunWith(MockitoJUnitRunner.class) +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 + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 65535, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + + Mockito.verify(vendorDeserializer).deserialize(bb); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyFlowTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyFlowTest.java new file mode 100644 index 0000000000..4183a352d2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyFlowTest.java @@ -0,0 +1,136 @@ +/* + * 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.impl.deserialization.factories.multipart; + +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.deserialization.factories.MultipartReplyMessageFactory; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowModFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType; +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.multipart.reply.body.MultipartReplyFlowCase; +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; + +/** + * @author michal.polkorab + * + */ +public class MultipartReplyFlowTest { + + private OFDeserializer factory; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + factory = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, 19, MultipartReplyMessage.class)); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testEmptyMultipartReplyFlowBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 01 00 00 00 00"); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x01, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyFlowCase messageCase = (MultipartReplyFlowCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyFlow message = messageCase.getMultipartReplyFlow(); + Assert.assertEquals("Wrong flow stats size", 0, message.getFlowStats().size()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyFlowBody(){ + ByteBuf bb = BufferHelper.buildBuffer("00 01 00 01 00 00 00 00 "+ + // first flow stat + "00 48 08 00 "+ // length, tableId, padding + "00 00 00 09 "+//durationSec + "00 00 00 07 "+//durationNsec + "00 0C 00 0E 00 0F 00 1F "+//priority, idleTimeout, hardTimeout, flags + "00 00 00 00 "+//pad_02 + "FF 01 01 01 01 01 01 01 "+//cookie + "EF 01 01 01 01 01 01 01 "+//packetCount + "7F 01 01 01 01 01 01 01 "+//byteCount + "00 01 00 04 00 00 00 00 "+//empty match + "00 01 00 08 06 00 00 00 "+ + "00 01 00 08 06 00 00 00 "+ + // second flow stat + "00 48 08 00 "+ // length, tableId, padding + "00 00 00 09 "+//durationSec + "00 00 00 07 "+//durationNsec + "00 0C 00 0E 00 0F 00 00 "+//priority, idleTimeout, hardTimeout, flags + "00 00 00 00 "+//pad_02 + "FF 01 01 01 01 01 01 01 "+//cookie + "EF 01 01 01 01 01 01 01 "+//packetCount + "7F 01 01 01 01 01 01 01 "+//byteCount + "00 01 00 04 00 00 00 00 "+//empty match + "00 01 00 08 06 00 00 00 "+ + "00 01 00 08 06 00 00 00"); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 0x01, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyFlowCase messageCase = (MultipartReplyFlowCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyFlow message = messageCase.getMultipartReplyFlow(); + Assert.assertEquals("Wrong flow stats size", 2, message.getFlowStats().size()); + FlowStats flowStats1 = message.getFlowStats().get(0); + Assert.assertEquals("Wrong tableId", 8, flowStats1.getTableId().intValue()); + Assert.assertEquals("Wrong durationSec", 9, flowStats1.getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 7, flowStats1.getDurationNsec().intValue()); + Assert.assertEquals("Wrong priority", 12, flowStats1.getPriority().intValue()); + Assert.assertEquals("Wrong idleTimeOut", 14, flowStats1.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong hardTimeOut", 15, flowStats1.getHardTimeout().intValue()); + Assert.assertEquals("Wrong flags", new FlowModFlags(true, true, true, true, true), flowStats1.getFlags()); + Assert.assertEquals("Wrong cookie", new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01}), flowStats1.getCookie()); + Assert.assertEquals("Wrong packetCount", new BigInteger(1, new byte[]{(byte) 0xEF, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01}), flowStats1.getPacketCount()); + Assert.assertEquals("Wrong byteCount", new BigInteger(1, new byte[]{(byte) 0x7F, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01}), flowStats1.getByteCount()); + Assert.assertEquals("Wrong match type", OxmMatchType.class, flowStats1.getMatch().getType()); + flowStats1 = message.getFlowStats().get(1); + Assert.assertEquals("Wrong tableId", 8, flowStats1.getTableId().intValue()); + Assert.assertEquals("Wrong durationSec", 9, flowStats1.getDurationSec().intValue()); + Assert.assertEquals("Wrong durationNsec", 7, flowStats1.getDurationNsec().intValue()); + Assert.assertEquals("Wrong priority", 12, flowStats1.getPriority().intValue()); + Assert.assertEquals("Wrong idleTimeOut", 14, flowStats1.getIdleTimeout().intValue()); + Assert.assertEquals("Wrong hardTimeOut", 15, flowStats1.getHardTimeout().intValue()); + Assert.assertEquals("Wrong flags", new FlowModFlags(false, false, false, false, false), flowStats1.getFlags()); + Assert.assertEquals("Wrong cookie", new BigInteger(1, new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01}), flowStats1.getCookie()); + Assert.assertEquals("Wrong packetCount", new BigInteger(1, new byte[]{(byte) 0xEF, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01}), flowStats1.getPacketCount()); + Assert.assertEquals("Wrong byteCount", new BigInteger(1, new byte[]{(byte) 0x7F, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01}), flowStats1.getByteCount()); + Assert.assertEquals("Wrong match type", OxmMatchType.class, flowStats1.getMatch().getType()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyGroupFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyGroupFeaturesTest.java new file mode 100644 index 0000000000..5ac385c750 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyGroupFeaturesTest.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.protocol.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +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.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.protocol.rev130731.MultipartReplyMessage; +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.multipart.reply.group.features._case.MultipartReplyGroupFeatures; + +/** + * @author michal.polkorab + * + */ +public class MultipartReplyGroupFeaturesTest { + + private MultipartReplyMessageFactory factory = new MultipartReplyMessageFactory(); + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyGroupFeatures() { + ByteBuf bb = BufferHelper.buildBuffer("00 08 00 01 00 00 00 00 "+ + "00 00 00 0F "+// types + "00 00 00 0F "+// capabilities + "00 00 00 01 "+// max groups + "00 00 00 02 "+// max groups + "00 00 00 03 "+// max groups + "00 00 00 04 "+// max groups + "0F FF 98 01 "+// actions bitmap (all actions included) + "00 00 00 00 "+// actions bitmap (no actions included) + "00 00 00 00 "+// actions bitmap (no actions included) + "00 00 00 00"// actions bitmap (no actions included) + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 8, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupFeaturesCase messageCase = + (MultipartReplyGroupFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupFeatures message = messageCase.getMultipartReplyGroupFeatures(); + Assert.assertEquals("Wrong group types", new GroupTypes(true, true, true, true), message.getTypes()); + Assert.assertEquals("Wrong capabilities", new GroupCapabilities(true, true, true, true), + message.getCapabilities()); + Assert.assertEquals("Wrong max groups", 1, message.getMaxGroups().get(0).intValue()); + Assert.assertEquals("Wrong max groups", 2, message.getMaxGroups().get(1).intValue()); + Assert.assertEquals("Wrong max groups", 3, message.getMaxGroups().get(2).intValue()); + Assert.assertEquals("Wrong max groups", 4, message.getMaxGroups().get(3).intValue()); + Assert.assertEquals("Wrong actions bitmap", new ActionType(true, true, true, true, false, true, true, true, true, + true, true, true, true, true, true, true, true), message.getActionsBitmap().get(0)); + Assert.assertEquals("Wrong actions bitmap", new ActionType(false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), message.getActionsBitmap().get(1)); + Assert.assertEquals("Wrong actions bitmap", new ActionType(false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), message.getActionsBitmap().get(2)); + Assert.assertEquals("Wrong actions bitmap", new ActionType(false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), message.getActionsBitmap().get(3)); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + * (with different group types and capabilities) + */ + @Test + public void testMultipartReplyGroupFeatures2() { + ByteBuf bb = BufferHelper.buildBuffer("00 08 00 01 00 00 00 00 "+ + "00 00 00 00 "+// types + "00 00 00 00 "+// capabilities + "00 00 00 01 "+// max groups + "00 00 00 02 "+// max groups + "00 00 00 03 "+// max groups + "00 00 00 04 "+// max groups + "00 00 00 00 "+// actions bitmap (all actions included) + "00 00 00 00 "+// actions bitmap (no actions included) + "00 00 00 00 "+// actions bitmap (no actions included) + "00 00 00 00"// actions bitmap (no actions included) + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 8, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyGroupFeaturesCase messageCase = + (MultipartReplyGroupFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyGroupFeatures message = messageCase.getMultipartReplyGroupFeatures(); + Assert.assertEquals("Wrong group types", new GroupTypes(false, false, false, false), message.getTypes()); + Assert.assertEquals("Wrong capabilities", new GroupCapabilities(false, false, false, false), + message.getCapabilities()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyMeterFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyMeterFeaturesTest.java new file mode 100644 index 0000000000..453c755dc5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyMeterFeaturesTest.java @@ -0,0 +1,80 @@ +/* + * 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.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +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.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.protocol.rev130731.MultipartReplyMessage; +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.multipart.reply.meter.features._case.MultipartReplyMeterFeatures; + +/** + * @author michal.polkorab + * + */ +public class MultipartReplyMeterFeaturesTest { + + private MultipartReplyMessageFactory factory = new MultipartReplyMessageFactory(); + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterFeatures(){ + ByteBuf bb = BufferHelper.buildBuffer("00 0B 00 01 00 00 00 00 "+ + "00 00 00 0A " + // maxMeter + "00 00 00 06 " + // bandTypes + "00 00 00 0F " + // capabilities + "07 08 00 00" // maxBands, maxColor, padding + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 11, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterFeaturesCase messageCase = (MultipartReplyMeterFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeterFeatures message = messageCase.getMultipartReplyMeterFeatures(); + Assert.assertEquals("Wrong maxMeter", 10, message.getMaxMeter().intValue()); + Assert.assertEquals("Wrong bandTypes", new MeterBandTypeBitmap(true, true), message.getBandTypes()); + Assert.assertEquals("Wrong capabilities", new MeterFlags(true, true, true, true), message.getCapabilities()); + Assert.assertEquals("Wrong maxBands", 7, message.getMaxBands().intValue()); + Assert.assertEquals("Wrong maxColor", 8, message.getMaxColor().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyMeterFeatures2(){ + ByteBuf bb = BufferHelper.buildBuffer("00 0B 00 01 00 00 00 00 "+ + "00 00 00 09 " + // maxMeter + "00 00 00 00 " + // bandTypes + "00 00 00 00 " + // capabilities + "03 04 00 00" // maxBands, maxColor, padding + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 11, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyMeterFeaturesCase messageCase = (MultipartReplyMeterFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyMeterFeatures message = messageCase.getMultipartReplyMeterFeatures(); + Assert.assertEquals("Wrong maxMeter", 9, message.getMaxMeter().intValue()); + Assert.assertEquals("Wrong bandTypes", new MeterBandTypeBitmap(false, false), message.getBandTypes()); + Assert.assertEquals("Wrong capabilities", new MeterFlags(false, false, false, false), message.getCapabilities()); + Assert.assertEquals("Wrong maxBands", 3, message.getMaxBands().intValue()); + Assert.assertEquals("Wrong maxColor", 4, message.getMaxColor().intValue()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java new file mode 100644 index 0000000000..d601cfa56a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyPortDescTest.java @@ -0,0 +1,122 @@ +/* + * 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.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +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.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; +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.multipart.reply.body.MultipartReplyPortDescCase; +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; + +/** + * @author michal.polkorab + * + */ +public class MultipartReplyPortDescTest { + + private MultipartReplyMessageFactory factory = new MultipartReplyMessageFactory(); + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testEmptyMultipartReplyPortDesc() { + ByteBuf bb = BufferHelper.buildBuffer("00 0D 00 00 00 00 00 00"); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 13, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyPortDescCase messageCase = (MultipartReplyPortDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyPortDesc message = messageCase.getMultipartReplyPortDesc(); + Assert.assertEquals("Wrong table features size", 0, message.getPorts().size()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyPortDesc() { + ByteBuf bb = BufferHelper.buildBuffer("00 0D 00 00 00 00 00 00 " + + // first port desc + "00 01 02 03 00 00 00 00 " + // portNo, padding + "08 00 27 00 B0 EB 00 00 " + // mac address, padding + "4F 70 65 6E 64 61 79 6C 69 67 68 74 00 00 00 00 " + // name + "00 00 00 65 " + //port config + "00 00 00 07 " + //port state + "00 00 00 81 " + //current features + "00 00 FF FF " + //advertised features + "00 00 C1 89 " + //supported features + "00 00 C5 8D " + //peer features + "00 00 00 81 " + //curr speed + "00 00 00 80 " + //max speed + // second port desc + "00 00 00 01 00 00 00 00 " + // portNo, padding + "08 00 27 00 B0 EB 00 00 " + // mac address, padding + "4F 70 65 6E 64 61 79 6C 69 67 68 74 00 00 00 00 " + // name + "00 00 00 00 " + //port config + "00 00 00 00 " + //port state + "00 00 00 00 " + //current features + "00 00 00 00 " + //advertised features + "00 00 00 00 " + //supported features + "00 00 00 00 " + //peer features + "00 00 00 05 " + //curr speed + "00 00 00 06" //max speed + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 13, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyPortDescCase messageCase = (MultipartReplyPortDescCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyPortDesc message = messageCase.getMultipartReplyPortDesc(); + 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 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()); + Assert.assertEquals("Wrong currentFeatures", new PortFeatures(false, false, false, false, false, true, + false, false, false, true, false, false, false, false, false, false), port.getCurrentFeatures()); + Assert.assertEquals("Wrong advertisedFeatures", new PortFeatures(true, true, true, true, true, true, + true, true, true, true, true, true, true, true, true, true), port.getAdvertisedFeatures()); + Assert.assertEquals("Wrong supportedFeatures", new PortFeatures(true, true, false, false, false, true, + false, false, false, true, false, false, false, false, true, true), port.getSupportedFeatures()); + Assert.assertEquals("Wrong peerFeatures", new PortFeatures(true, true, true, false, false, true, false, + false, false, true, false, false, false, true, true, true), port.getPeerFeatures()); + Assert.assertEquals("Wrong currSpeed", 129L, port.getCurrSpeed().longValue()); + 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 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()); + Assert.assertEquals("Wrong currentFeatures", new PortFeatures(false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), port.getCurrentFeatures()); + Assert.assertEquals("Wrong advertisedFeatures", new PortFeatures(false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), port.getAdvertisedFeatures()); + Assert.assertEquals("Wrong supportedFeatures", new PortFeatures(false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), port.getSupportedFeatures()); + Assert.assertEquals("Wrong peerFeatures", new PortFeatures(false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), port.getPeerFeatures()); + Assert.assertEquals("Wrong currSpeed", 5L, port.getCurrSpeed().longValue()); + Assert.assertEquals("Wrong maxSpeed", 6L, port.getMaxSpeed().longValue()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyTableFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyTableFeaturesTest.java new file mode 100644 index 0000000000..96a7c1c0aa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/MultipartReplyTableFeaturesTest.java @@ -0,0 +1,187 @@ +/* + * 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.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; + +import java.util.List; + +import org.junit.Assert; +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.opendaylight.openflow.augments.rev150225.NextTableRelatedTableFeatureProperty; +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.types.rev130731.TableFeaturesPropType; +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.multipart.reply.body.MultipartReplyTableFeaturesCase; +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 michal.polkorab + * + */ +public class MultipartReplyTableFeaturesTest { + + private MultipartReplyMessageFactory factory = new MultipartReplyMessageFactory(); + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testEmptyMultipartReplyTableFeatures() { + ByteBuf bb = BufferHelper.buildBuffer("00 0C 00 00 00 00 00 00"); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 12, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyTableFeaturesCase messageCase = (MultipartReplyTableFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyTableFeatures message = messageCase.getMultipartReplyTableFeatures(); + Assert.assertEquals("Wrong table features size", 0, message.getTableFeatures().size()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyTableFeatures() { + ByteBuf bb = BufferHelper.buildBuffer("00 0C 00 00 00 00 00 00 "+ + // first table feature + "00 40 01 00 00 00 00 00 "+// length, tableId, padding + "4F 70 65 6E 64 61 79 6C 69 67 68 74 00 00 00 00 00 00 00 "+ + "00 00 00 00 00 00 00 00 00 00 00 00 00 "+// name + "00 00 00 00 00 00 00 01 "+// metadata match + "00 00 00 00 00 00 00 02 "+// metadata write + "00 00 00 00 "+// config + "00 00 00 2A "+// max entries + // second table feature + "00 40 02 00 00 00 00 00 "+// length, tableId, padding + "4F 70 65 6E 64 61 79 6C 69 67 68 74 00 00 00 00 00 00 00" + + " 00 00 00 00 00 00 00 00 00 00 00 00 00 "+// name + "00 00 00 00 00 00 00 03 "+// metadata match + "00 00 00 00 00 00 00 04 "+// metadata write + "00 00 00 03 "+// config + "00 00 00 2B" // max entries + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 12, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyTableFeaturesCase messageCase = (MultipartReplyTableFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyTableFeatures message = messageCase.getMultipartReplyTableFeatures(); + Assert.assertEquals("Wrong table features size", 2, message.getTableFeatures().size()); + TableFeatures feature = message.getTableFeatures().get(0); + Assert.assertEquals("Wrong table id", 1, feature.getTableId().intValue()); + Assert.assertEquals("Wrong name", "Opendaylight", feature.getName()); + Assert.assertArrayEquals("Wrong metadata match", new byte[]{0, 0, 0, 0, 0, 0, 0, 1}, feature.getMetadataMatch()); + Assert.assertArrayEquals("Wrong metadata write", new byte[]{0, 0, 0, 0, 0, 0, 0, 2}, feature.getMetadataWrite()); + Assert.assertEquals("Wrong config", false, feature.getConfig().isOFPTCDEPRECATEDMASK()); + Assert.assertEquals("Wrong max entries", 42, feature.getMaxEntries().intValue()); + feature = message.getTableFeatures().get(1); + Assert.assertEquals("Wrong table id", 2, feature.getTableId().intValue()); + Assert.assertEquals("Wrong name", "Opendaylight", feature.getName()); + Assert.assertArrayEquals("Wrong metadata match", new byte[]{0, 0, 0, 0, 0, 0, 0, 3}, feature.getMetadataMatch()); + Assert.assertArrayEquals("Wrong metadata write", new byte[]{0, 0, 0, 0, 0, 0, 0, 4}, feature.getMetadataWrite()); + Assert.assertEquals("Wrong config", true, feature.getConfig().isOFPTCDEPRECATEDMASK()); + Assert.assertEquals("Wrong max entries", 43, feature.getMaxEntries().intValue()); + } + + /** + * Testing {@link MultipartReplyMessageFactory} for correct translation into POJO + */ + @Test + public void testMultipartReplyTableFeatures2() { + ByteBuf bb = BufferHelper.buildBuffer("00 0C 00 00 00 00 00 00 "+ + "00 B0 01 00 00 00 00 00 "+// length, tableId, padding + "4F 70 65 6E 64 61 79 6C 69 67 68 74 00 00 00 00 00 00 00 "+ + "00 00 00 00 00 00 00 00 00 00 00 00 00 "+// name + "00 00 00 00 00 00 00 01 "+// metadata match + "00 00 00 00 00 00 00 02 "+// metadata write + "00 00 00 00 "+// config + "00 00 00 2A "+// max entries + "00 00 00 04 00 00 00 00 "+ + "00 01 00 04 00 00 00 00 "+ + "00 02 00 08 01 02 03 04 "+ + "00 03 00 07 05 06 07 00 "+ + "00 04 00 04 00 00 00 00 "+ + "00 05 00 04 00 00 00 00 "+ + "00 06 00 04 00 00 00 00 "+ + "00 07 00 04 00 00 00 00 "+ + "00 08 00 04 00 00 00 00 "+ + "00 0A 00 04 00 00 00 00 "+ + "00 0C 00 04 00 00 00 00 "+ + "00 0D 00 04 00 00 00 00 "+ + "00 0E 00 04 00 00 00 00 "+ + "00 0F 00 04 00 00 00 00" + ); + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV13(builtByFactory); + Assert.assertEquals("Wrong type", 12, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", false, builtByFactory.getFlags().isOFPMPFREQMORE()); + MultipartReplyTableFeaturesCase messageCase = (MultipartReplyTableFeaturesCase) builtByFactory.getMultipartReplyBody(); + MultipartReplyTableFeatures message = messageCase.getMultipartReplyTableFeatures(); + Assert.assertEquals("Wrong table features size", 1, message.getTableFeatures().size()); + TableFeatures feature = message.getTableFeatures().get(0); + Assert.assertEquals("Wrong table id", 1, feature.getTableId().intValue()); + Assert.assertEquals("Wrong name", "Opendaylight", feature.getName()); + Assert.assertArrayEquals("Wrong metadata match", new byte[]{0, 0, 0, 0, 0, 0, 0, 1}, feature.getMetadataMatch()); + Assert.assertArrayEquals("Wrong metadata write", new byte[]{0, 0, 0, 0, 0, 0, 0, 2}, feature.getMetadataWrite()); + Assert.assertEquals("Wrong config", false, feature.getConfig().isOFPTCDEPRECATEDMASK()); + Assert.assertEquals("Wrong max entries", 42, feature.getMaxEntries().intValue()); + Assert.assertEquals("Wrong properties size", 14, feature.getTableFeatureProperties().size()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTINSTRUCTIONS, + feature.getTableFeatureProperties().get(0).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTINSTRUCTIONSMISS, + feature.getTableFeatureProperties().get(1).getType()); + TableFeatureProperties property = feature.getTableFeatureProperties().get(2); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTNEXTTABLES, + property.getType()); + List tableIds = property.getAugmentation(NextTableRelatedTableFeatureProperty.class) + .getNextTableIds(); + Assert.assertEquals("Wrong next table id size", 4, tableIds.size()); + Assert.assertEquals("Wrong next table id", 1, tableIds.get(0).getTableId().intValue()); + Assert.assertEquals("Wrong next table id", 2, tableIds.get(1).getTableId().intValue()); + Assert.assertEquals("Wrong next table id", 3, tableIds.get(2).getTableId().intValue()); + Assert.assertEquals("Wrong next table id", 4, tableIds.get(3).getTableId().intValue()); + property = feature.getTableFeatureProperties().get(3); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTNEXTTABLESMISS, + property.getType()); + tableIds = property.getAugmentation(NextTableRelatedTableFeatureProperty.class) + .getNextTableIds(); + Assert.assertEquals("Wrong next table id size", 3, tableIds.size()); + Assert.assertEquals("Wrong next table id", 5, tableIds.get(0).getTableId().intValue()); + Assert.assertEquals("Wrong next table id", 6, tableIds.get(1).getTableId().intValue()); + Assert.assertEquals("Wrong next table id", 7, tableIds.get(2).getTableId().intValue()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTWRITEACTIONS, + feature.getTableFeatureProperties().get(4).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTWRITEACTIONSMISS, + feature.getTableFeatureProperties().get(5).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTAPPLYACTIONS, + feature.getTableFeatureProperties().get(6).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTAPPLYACTIONSMISS, + feature.getTableFeatureProperties().get(7).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTMATCH, + feature.getTableFeatureProperties().get(8).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTWILDCARDS, + feature.getTableFeatureProperties().get(9).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTWRITESETFIELD, + feature.getTableFeatureProperties().get(10).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTWRITESETFIELDMISS, + feature.getTableFeatureProperties().get(11).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTAPPLYSETFIELD, + feature.getTableFeatureProperties().get(12).getType()); + Assert.assertEquals("Wrong property type", TableFeaturesPropType.OFPTFPTAPPLYSETFIELDMISS, + feature.getTableFeatureProperties().get(13).getType()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java new file mode 100644 index 0000000000..69d420feb0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/multipart/OF10StatsReplyExperimenterTest.java @@ -0,0 +1,56 @@ +/* + * 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.impl.deserialization.factories.multipart; + +import io.netty.buffer.ByteBuf; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.extensibility.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 + * + */ +@RunWith(MockitoJUnitRunner.class) +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); + + ByteBuf bb = BufferHelper.buildBuffer("FF FF 00 01 00 00 00 00 " + + "00 00 00 01"); // expID + MultipartReplyMessage builtByFactory = BufferHelper.deserialize(factory, bb); + + BufferHelper.checkHeaderV10(builtByFactory); + Assert.assertEquals("Wrong type", 65535, builtByFactory.getType().getIntValue()); + Assert.assertEquals("Wrong flag", true, builtByFactory.getFlags().isOFPMPFREQMORE()); + + Mockito.verify(vendorDeserializer).deserialize(bb); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractInstructionDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractInstructionDeserializerTest.java new file mode 100644 index 0000000000..1d8c843184 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/instruction/AbstractInstructionDeserializerTest.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.impl.deserialization.instruction; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class AbstractInstructionDeserializerTest { + + /** + * Tests {@link AbstractInstructionDeserializer#deserializeHeader(ByteBuf)} with different + * instruction types + */ + @Test + public void test() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 01 00 04"); + Instruction instruction = new GoToTableInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof GotoTableCase); + + buffer = ByteBufUtils.hexStringToByteBuf("00 02 00 04"); + instruction = new WriteMetadataInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof WriteMetadataCase); + + buffer = ByteBufUtils.hexStringToByteBuf("00 03 00 04"); + instruction = new WriteActionsInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof WriteActionsCase); + + buffer = ByteBufUtils.hexStringToByteBuf("00 04 00 04"); + instruction = new ApplyActionsInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof ApplyActionsCase); + + buffer = ByteBufUtils.hexStringToByteBuf("00 05 00 04"); + instruction = new ClearActionsInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof ClearActionsCase); + + buffer = ByteBufUtils.hexStringToByteBuf("00 06 00 04"); + instruction = new MeterInstructionDeserializer().deserializeHeader(buffer); + Assert.assertTrue("Wrong type", instruction.getInstructionChoice() instanceof MeterCase); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java new file mode 100644 index 0000000000..6fbdbaa470 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6ExtHdrDeserializerTest.java @@ -0,0 +1,49 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +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.entry.value.grouping.match.entry.value.Ipv6ExthdrCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6ExtHdrDeserializerTest { + + /** + * Tests {@link OxmIpv6ExtHdrDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 4E 02 01 FF"); + + buffer.skipBytes(4); // skip XID + OxmIpv6ExtHdrDeserializer deserializer = new OxmIpv6ExtHdrDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Exthdr.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", + new Ipv6ExthdrFlags(true, true, true, true, true, true, true, true, true), + ((Ipv6ExthdrCase) entry.getMatchEntryValue()).getIpv6Exthdr().getPseudoField()); + Assert.assertEquals("Wrong entry mask", null, ((Ipv6ExthdrCase) entry.getMatchEntryValue()) + .getIpv6Exthdr().getMask()); + Assert.assertTrue("Unread data", buffer.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java new file mode 100644 index 0000000000..2a08e85ed1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmIpv6FlabelDeserializerTest.java @@ -0,0 +1,66 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; +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.entry.value.grouping.match.entry.value.Ipv6FlabelCase; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6FlabelDeserializerTest { + + /** + * Tests {@link OxmIpv6FlabelDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 38 04 00 00 00 02"); + + buffer.skipBytes(4); // skip XID + OxmIpv6FlabelDeserializer deserializer = new OxmIpv6FlabelDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Flabel.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + ((Ipv6FlabelCase) entry.getMatchEntryValue()).getIpv6Flabel() + .getIpv6Flabel().getValue().intValue()); + } + + /** + * Tests {@link OxmIpv6FlabelDeserializer#deserialize(ByteBuf)} + */ + @Test + public void testWithMask() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 39 08 00 00 00 02 00 00 00 05"); + + buffer.skipBytes(4); // skip XID + OxmIpv6FlabelDeserializer deserializer = new OxmIpv6FlabelDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Flabel.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + ((Ipv6FlabelCase) entry.getMatchEntryValue()).getIpv6Flabel() + .getIpv6Flabel().getValue().intValue()); + Assert.assertArrayEquals("Wrong entry mask", new byte[]{0, 0, 0, 5}, + ((Ipv6FlabelCase) entry.getMatchEntryValue()).getIpv6Flabel().getMask()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java new file mode 100644 index 0000000000..d8c60a655b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMetadataDeserializerTest.java @@ -0,0 +1,45 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata; +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.entry.value.grouping.match.entry.value.MetadataCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMetadataDeserializerTest { + + /** + * Tests {@link OxmMetadataDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 04 08 00 00 00 00 00 00 00 03"); + + buffer.skipBytes(4); // skip XID + OxmMetadataDeserializer deserializer = new OxmMetadataDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Metadata.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertArrayEquals("Wrong entry value", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 03"), + ((MetadataCase) entry.getMatchEntryValue()).getMetadata().getMetadata()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java new file mode 100644 index 0000000000..2756f063ed --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmMplsBosDeserializerTest.java @@ -0,0 +1,44 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsBos; +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.entry.value.grouping.match.entry.value.MplsBosCase; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsBosDeserializerTest { + + /** + * Tests {@link OxmMplsBosDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 48 01 00"); + + buffer.skipBytes(4); // skip XID + OxmMplsBosDeserializer deserializer = new OxmMplsBosDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", MplsBos.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", false, + ((MplsBosCase) entry.getMatchEntryValue()).getMplsBos().isBos()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java new file mode 100644 index 0000000000..45e4a4fd46 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmPbbIsidDeserializerTest.java @@ -0,0 +1,44 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.PbbIsid; +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.entry.value.grouping.match.entry.value.PbbIsidCase; + +/** + * @author michal.polkorab + * + */ +public class OxmPbbIsidDeserializerTest { + + /** + * Tests {@link OxmPbbIsidDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 4A 03 00 00 02"); + + buffer.skipBytes(4); // skip XID + OxmPbbIsidDeserializer deserializer = new OxmPbbIsidDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", PbbIsid.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, ((PbbIsidCase) entry.getMatchEntryValue()) + .getPbbIsid().getIsid().intValue()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java new file mode 100644 index 0000000000..8d2d182822 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/deserialization/match/OxmVlanVidDeserializerTest.java @@ -0,0 +1,46 @@ +/* + * 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.impl.deserialization.match; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; +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.entry.value.grouping.match.entry.value.VlanVidCase; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanVidDeserializerTest { + + /** + * Tests {@link OxmVlanVidDeserializer#deserialize(ByteBuf)} + */ + @Test + public void test() { + ByteBuf buffer = BufferHelper.buildBuffer("80 00 0C 02 20 0A"); + + buffer.skipBytes(4); // skip XID + OxmVlanVidDeserializer deserializer = new OxmVlanVidDeserializer(); + MatchEntry entry = deserializer.deserialize(buffer); + + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", VlanVid.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertEquals("Wrong entry value", 10, + ((VlanVidCase) entry.getMatchEntryValue()).getVlanVid().getVlanVid().intValue()); + Assert.assertEquals("Wrong entry value", false, + ((VlanVidCase) entry.getMatchEntryValue()).getVlanVid().isCfiBit()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactoryTest.java new file mode 100644 index 0000000000..3ffbca7048 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializationFactoryTest.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.impl.serialization; + +import static org.junit.Assert.assertEquals; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class SerializationFactoryTest { + + /** + * Test serializer lookup & serialization + */ + @Test + public void test() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + SerializationFactory factory = new SerializationFactory(); + factory.setSerializerTable(registry); + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + HelloInputBuilder helloBuilder = new HelloInputBuilder(); + helloBuilder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + helloBuilder.setXid(123456L); + helloBuilder.setElements(null); + factory.messageToBuffer(EncodeConstants.OF10_VERSION_ID, buffer, helloBuilder.build()); + assertEquals("Serialization failed", EncodeConstants.OFHEADER_SIZE, buffer.readableBytes()); + } + + /** + * Test serializer not found scenario + */ + @Test(expected=IllegalStateException.class) + public void testNotExistingSerializer() { + SerializerRegistry registry = new SerializerRegistryImpl(); + registry.init(); + SerializationFactory factory = new SerializationFactory(); + factory.setSerializerTable(registry); + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + HelloInputBuilder helloBuilder = new HelloInputBuilder(); + helloBuilder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + helloBuilder.setXid(123456L); + helloBuilder.setElements(null); + factory.messageToBuffer((short) 0, buffer, helloBuilder.build()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImplTest.java new file mode 100644 index 0000000000..abed50d9e9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/SerializerRegistryImplTest.java @@ -0,0 +1,61 @@ +/* + * 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.impl.serialization; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.util.OF13MatchSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; + +/** + * + * @author madamjak + * + */ +public class SerializerRegistryImplTest { + + private static final short OF13 = EncodeConstants.OF13_VERSION_ID; + private static final short OF10 = EncodeConstants.OF10_VERSION_ID; + + /** + * Test - register serializer without arguments + */ + @Test(expected = IllegalArgumentException.class) + public void testRegisterSerializerNoArgs(){ + + SerializerRegistryImpl serReg = new SerializerRegistryImpl(); + serReg.registerSerializer(null, null); + } + + /** + * Test - unregister serializer without MessageTypeKye + */ + @Test(expected = IllegalArgumentException.class) + public void testUnRegisterSerializerNoMessageTypeKey(){ + SerializerRegistryImpl serReg = new SerializerRegistryImpl(); + serReg.init(); + serReg.registerSerializer(new MessageTypeKey<>(OF13, Match.class), new OF13MatchSerializer()); + serReg.unregisterSerializer(null); + } + + /** + * Test - unregister serializer + */ + @Test + public void testUnRegisterSerializer(){ + SerializerRegistryImpl serReg = new SerializerRegistryImpl(); + serReg.init(); + serReg.registerSerializer(new MessageTypeKey<>(OF13, Match.class), new OF13MatchSerializer()); + Assert.assertTrue("Wrong - unregister serializer",serReg.unregisterSerializer(new MessageTypeKey<>(OF13, Match.class))); + + serReg.registerSerializer(new MessageTypeKey<>(OF13, Match.class), new OF13MatchSerializer()); + Assert.assertFalse("Wrong - unregister serializer",serReg.unregisterSerializer(new MessageTypeKey<>(OF10, Match.class))); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializerTest.java new file mode 100644 index 0000000000..45a4fc94cc --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/action/OF13SetFieldActionSerializerTest.java @@ -0,0 +1,97 @@ +/* + * 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.impl.serialization.action; +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.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; +import org.opendaylight.openflowjava.protocol.impl.util.ActionConstants; +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.action.rev150203.action.grouping.action.choice.SetFieldCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.field._case.SetFieldActionBuilder; +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.ExperimenterId; +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.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; + +/** + * @author madamjak + * + */ +public class OF13SetFieldActionSerializerTest { + + private SerializerRegistry registry; + @Mock OFSerializer serializerMock; + + /** + * Initialize registry and mock + */ + @Before + public void startUp() { + MockitoAnnotations.initMocks(this); + registry = new SerializerRegistryImpl(); + registry.init(); + } + + /** + * Test identify ExperimenterClass serializer + */ + @Test + public void test(){ + OF13SetFieldActionSerializer ser = new OF13SetFieldActionSerializer(); + ser.injectSerializerRegistry(registry); + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder actionBuilder = new ActionBuilder(); + long experimenterId = 12L; + ExperimenterIdCaseBuilder expCaseBuilder = new ExperimenterIdCaseBuilder(); + ExperimenterBuilder expBuilder = new ExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(experimenterId)); + expCaseBuilder.setExperimenter(expBuilder.build()); + MatchEntryBuilder meb = new MatchEntryBuilder(); + meb.setOxmClass(ExperimenterClass.class); + meb.setOxmMatchField(OxmMatchFieldClass.class); + meb.setMatchEntryValue(expCaseBuilder.build()); + List matchEntry = new ArrayList<>(); + MatchEntry me = meb.build(); + matchEntry.add(me); + SetFieldCaseBuilder caseBuilder = new SetFieldCaseBuilder(); + SetFieldActionBuilder setFieldBuilder = new SetFieldActionBuilder(); + setFieldBuilder.setMatchEntry(matchEntry); + caseBuilder.setSetFieldAction(setFieldBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + MatchEntrySerializerKey key = new MatchEntrySerializerKey<>( + EncodeConstants.OF13_VERSION_ID, ExperimenterClass.class, OxmMatchFieldClass.class); + key.setExperimenterId(experimenterId); + registry.registerSerializer(key, serializerMock); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ser.serialize(actionBuilder.build(), out); + Mockito.verify(serializerMock, Mockito.times(1)).serialize((MatchEntry)Mockito.anyObject(), (ByteBuf)Mockito.anyObject()); + int lenght = out.readableBytes(); + Assert.assertEquals("Wrong - bad field code", ActionConstants.SET_FIELD_CODE, out.readUnsignedShort()); + Assert.assertEquals("Wrong - bad lenght", lenght, out.readUnsignedShort()); + } + + private class OxmMatchFieldClass extends MatchField { + // only for testing purposes + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactoryTest.java new file mode 100644 index 0000000000..c0263c3065 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierInputMessageFactoryTest.java @@ -0,0 +1,62 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class BarrierInputMessageFactoryTest { + + private static final byte BARRIER_REQUEST_MESSAGE_CODE_TYPE = 20; + private SerializerRegistry registry; + private OFSerializer barrierFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + barrierFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, BarrierInput.class)); + } + + /** + * Testing of {@link BarrierInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void test() throws Exception { + BarrierInputBuilder bib = new BarrierInputBuilder(); + BufferHelper.setupHeader(bib, EncodeConstants.OF13_VERSION_ID); + BarrierInput bi = bib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + barrierFactory.serialize(bi, out); + + BufferHelper.checkHeaderV13(out, BARRIER_REQUEST_MESSAGE_CODE_TYPE, 8); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/BarrierReplyMessageFactoryTest.java new file mode 100644 index 0000000000..cbe260d546 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactoryTest.java new file mode 100644 index 0000000000..0d6db4e062 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoInputMessageFactoryTest.java @@ -0,0 +1,94 @@ +/* + * 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.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.protocol.rev130731.EchoInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class EchoInputMessageFactoryTest { + + private static final byte ECHO_REQUEST_MESSAGE_CODE_TYPE = 2; + private SerializerRegistry registry; + private OFSerializer echoFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + echoFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, EchoInput.class)); + } + + /** + * Testing of {@link EchoInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV13() throws Exception { + EchoInputBuilder eib = new EchoInputBuilder(); + BufferHelper.setupHeader(eib, EncodeConstants.OF13_VERSION_ID); + EchoInput ei = eib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(ei, out); + BufferHelper.checkHeaderV13(out, ECHO_REQUEST_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link EchoInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV10() throws Exception { + EchoInputBuilder eib = new EchoInputBuilder(); + BufferHelper.setupHeader(eib, EncodeConstants.OF10_VERSION_ID); + EchoInput ei = eib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(ei, out); + BufferHelper.checkHeaderV10(out, ECHO_REQUEST_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link EchoInputMessageFactory} for correct data serialization + * @throws Exception + */ + @Test + public void testData() throws Exception{ + byte[] dataToTest = new byte[]{91,92,93,94,95,96,97,98}; + EchoInputBuilder eib = new EchoInputBuilder(); + BufferHelper.setupHeader(eib, EncodeConstants.OF13_VERSION_ID); + eib.setData(dataToTest); + EchoInput ei = eib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(ei, out); + BufferHelper.checkHeaderV13(out, ECHO_REQUEST_MESSAGE_CODE_TYPE, 8+dataToTest.length); + byte[] outData = new byte[dataToTest.length]; + out.readBytes(outData); + Assert.assertArrayEquals("Wrong - different output data.", dataToTest, outData); + out.release(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoOutputMessageFactoryTest.java new file mode 100644 index 0000000000..0f70b3eace --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactoryTest.java new file mode 100644 index 0000000000..98bd9a63c2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoReplyInputMessageFactoryTest.java @@ -0,0 +1,95 @@ +/* + * 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.serialization.factories; + +import org.junit.Assert; + +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.EchoReplyInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class EchoReplyInputMessageFactoryTest { + + private static final byte ECHO_REPLY_MESSAGE_CODE_TYPE = 3; + private SerializerRegistry registry; + private OFSerializer echoFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + echoFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, EchoReplyInput.class)); + } + + /** + * Testing of {@link EchoReplyInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV13() throws Exception { + EchoReplyInputBuilder erib = new EchoReplyInputBuilder(); + BufferHelper.setupHeader(erib, EncodeConstants.OF13_VERSION_ID); + EchoReplyInput eri = erib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(eri, out); + BufferHelper.checkHeaderV13(out, ECHO_REPLY_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link EchoReplyInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV10() throws Exception { + EchoReplyInputBuilder erib = new EchoReplyInputBuilder(); + BufferHelper.setupHeader(erib, EncodeConstants.OF10_VERSION_ID); + EchoReplyInput eri = erib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(eri, out); + BufferHelper.checkHeaderV10(out, ECHO_REPLY_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link EchoReplyInputMessageFactory} for correct message serialization + * @throws Exception + */ + @Test + public void testDataSerialize()throws Exception { + byte[] dataToTest = new byte[]{91,92,93,94,95,96,97,98}; + EchoReplyInputBuilder erib = new EchoReplyInputBuilder(); + BufferHelper.setupHeader(erib, EncodeConstants.OF13_VERSION_ID); + erib.setData(dataToTest); + EchoReplyInput eri = erib.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + echoFactory.serialize(eri, out); + BufferHelper.checkHeaderV13(out, ECHO_REPLY_MESSAGE_CODE_TYPE, 8+dataToTest.length); + byte[] outData = new byte[dataToTest.length]; + out.readBytes(outData); + Assert.assertArrayEquals("Wrong - different output data.",dataToTest, outData); + out.release(); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/EchoRequestMessageFactoryTest.java new file mode 100644 index 0000000000..22135bb640 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ErrorMessageFactoryTest.java new file mode 100644 index 0000000000..929cbefe6b --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java new file mode 100644 index 0000000000..9b6720e493 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/ExperimenterInputMessageFactoryTest.java @@ -0,0 +1,140 @@ +/* + * 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.impl.serialization.factories; + +import io.netty.buffer.ByteBuf; +import org.junit.Test; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +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.ExperimenterIdSerializerKey; +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.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 + * + */ +public class ExperimenterInputMessageFactoryTest { + + @Mock SerializerRegistry registry; + @Mock + private OFSerializer serializer; + private OFSerializer expFactory; + @Mock + private ExperimenterDataOfChoice vendorData; + @Mock + private ByteBuf out; + + /** + * Sets up ExperimenterInputMessageFactory + * @param real true if setup should use real registry, false when mock is desired + */ + public void startUp(boolean real) { + MockitoAnnotations.initMocks(this); + expFactory = new ExperimenterInputMessageFactory(); + if (real) { + SerializerRegistry realRegistry = new SerializerRegistryImpl(); + realRegistry.init(); + ((SerializerRegistryInjector) expFactory).injectSerializerRegistry(realRegistry); + } else { + ((SerializerRegistryInjector) expFactory).injectSerializerRegistry(registry); + } + } + + /** + * Testing of {@link ExperimenterInputMessageFactory} for correct serializer + * lookup and serialization + * @throws Exception + */ + @Test(expected=IllegalStateException.class) + public void testV10Real() throws Exception { + startUp(true); + 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(); + + expFactory.serialize(input, out); + } + + /** + * Testing of {@link ExperimenterInputMessageFactory} for correct serializer + * lookup and serialization + * @throws Exception + */ + @Test(expected=IllegalStateException.class) + public void testV13Real() throws Exception { + startUp(true); + 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(); + + expFactory.serialize(input, out); + } + + /** + * Testing of {@link ExperimenterInputMessageFactory} for correct serializer + * lookup and serialization + * @throws Exception + */ + @Test + public void testV10() throws Exception { + startUp(false); + 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); + + expFactory.serialize(input, out); + Mockito.verify(serializer, Mockito.times(1)).serialize(input.getExperimenterDataOfChoice(), out); + } + + /** + * Testing of {@link ExperimenterInputMessageFactory} for correct serializer + * lookup and serialization + * @throws Exception + */ + @Test + public void testV13() throws Exception { + startUp(false); + 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); + + expFactory.serialize(input, out); + Mockito.verify(serializer, Mockito.times(1)).serialize(input.getExperimenterDataOfChoice(), out); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java new file mode 100644 index 0000000000..a3a72a27d4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowModInputMessageFactoryTest.java @@ -0,0 +1,235 @@ +/* + * 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.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.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.MatchBuilder; +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 timotej.kubas + * @author michal.polkorab + */ +public class FlowModInputMessageFactoryTest { + private static final byte PADDING_IN_FLOW_MOD_MESSAGE = 2; + private SerializerRegistry registry; + private OFSerializer flowModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + flowModFactory = registry.getSerializer(new MessageTypeKey<>( + EncodeConstants.OF13_VERSION_ID, FlowModInput.class)); + } + + /** + * @throws Exception + * Testing of {@link FlowModInputMessageFactory} for correct translation from POJO + */ + @Test + public void testFlowModInputMessageFactory() throws Exception { + FlowModInputBuilder builder = new FlowModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + byte[] cookie = new byte[]{(byte) 0xFF, 0x01, 0x04, 0x01, 0x06, 0x00, 0x07, 0x01}; + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookieMask = new byte[]{(byte) 0xFF, 0x05, 0x00, 0x00, 0x09, 0x30, 0x00, 0x30}; + builder.setCookieMask(new BigInteger(1, cookieMask)); + builder.setTableId(new TableId(65L)); + builder.setCommand(FlowModCommand.forValue(2)); + builder.setIdleTimeout(12); + builder.setHardTimeout(0); + builder.setPriority(126); + builder.setBufferId(2L); + builder.setOutPort(new PortNumber(4422L)); + builder.setOutGroup(98L); + builder.setFlags(new FlowModFlags(true, false, true, false, true)); + 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<>(); + 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(); + metadataBuilder.setMetadata(cookie); + metadataBuilder.setMetadataMask(cookieMask); + 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()); + builder.setInstruction(instructions); + 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); + Assert.assertEquals("Wrong cookie", message.getCookie(), new BigInteger(1, cookie)); + cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(cookieMask); + Assert.assertEquals("Wrong cookieMask", message.getCookieMask(), new BigInteger(1, cookieMask)); + Assert.assertEquals("Wrong tableId", message.getTableId().getValue().intValue(), out.readUnsignedByte()); + Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readUnsignedByte()); + Assert.assertEquals("Wrong idleTimeOut", message.getIdleTimeout().intValue(), out.readShort()); + Assert.assertEquals("Wrong hardTimeOut", message.getHardTimeout().intValue(), out.readShort()); + Assert.assertEquals("Wrong priority", message.getPriority().intValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong bufferId", message.getBufferId().intValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong outPort", message.getOutPort().getValue().intValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong outGroup", message.getOutGroup().intValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong flags", message.getFlags(), createFlowModFlagsFromBitmap(out.readUnsignedShort())); + out.skipBytes(PADDING_IN_FLOW_MOD_MESSAGE); + Assert.assertEquals("Wrong match type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong oxm class", 0x8000, out.readUnsignedShort()); + short fieldAndMask = out.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 1, fieldAndMask >> 1); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong oxm class", 0x8000, out.readUnsignedShort()); + fieldAndMask = out.readUnsignedByte(); + Assert.assertEquals("Wrong oxm hasMask", 0, fieldAndMask & 1); + Assert.assertEquals("Wrong oxm field", 9, fieldAndMask >> 1); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong oxm value", 4, out.readUnsignedByte()); + out.skipBytes(7); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong instruction value", 43, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + out.skipBytes(EncodeConstants.SIZE_OF_INT_IN_BYTES); + byte[] cookieRead = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(cookieRead); + byte[] cookieMaskRead = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(cookieMaskRead); + Assert.assertArrayEquals("Wrong metadata", cookie, cookieRead); + Assert.assertArrayEquals("Wrong metadata mask", cookieMask, cookieMaskRead); + Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 24, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-length", 52, out.readUnsignedShort()); + out.skipBytes(6); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + 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); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/FlowRemovedMessageFactoryTest.java new file mode 100644 index 0000000000..0ba90a23d9 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetAsyncReplyMessageFactoryTest.java new file mode 100644 index 0000000000..f645944bde --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..35f5eef993 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigInputMessageFactoryTest.java @@ -0,0 +1,78 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.GetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class GetConfigInputMessageFactoryTest { + + private static final byte GET_CONFIG_REQUEST_MESSAGE_CODE_TYPE = 7; + private SerializerRegistry registry; + private OFSerializer getConfigFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + getConfigFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetConfigInput.class)); + } + + /** + * Testing of {@link GetConfigInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV13() throws Exception { + GetConfigInputBuilder gcib = new GetConfigInputBuilder(); + BufferHelper.setupHeader(gcib, EncodeConstants.OF13_VERSION_ID); + GetConfigInput gci = gcib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + getConfigFactory.serialize(gci, out); + + BufferHelper.checkHeaderV13(out, GET_CONFIG_REQUEST_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link GetConfigInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV10() throws Exception { + GetConfigInputBuilder gcib = new GetConfigInputBuilder(); + BufferHelper.setupHeader(gcib, EncodeConstants.OF10_VERSION_ID); + GetConfigInput gci = gcib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + getConfigFactory.serialize(gci, out); + + BufferHelper.checkHeaderV10(out, GET_CONFIG_REQUEST_MESSAGE_CODE_TYPE, 8); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..a6d00adf7c --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactoryTest.java new file mode 100644 index 0000000000..fdf097c235 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesInputMessageFactoryTest.java @@ -0,0 +1,77 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class GetFeaturesInputMessageFactoryTest { + + private static final byte FEATURES_REQUEST_MESSAGE_CODE_TYPE = 5; + private SerializerRegistry registry; + private OFSerializer featuresFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + featuresFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetFeaturesInput.class)); + } + + /** + * Testing of {@link GetFeaturesInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV13() throws Exception { + GetFeaturesInputBuilder gfib = new GetFeaturesInputBuilder(); + BufferHelper.setupHeader(gfib, EncodeConstants.OF13_VERSION_ID); + GetFeaturesInput gfi = gfib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + featuresFactory.serialize(gfi, out); + + BufferHelper.checkHeaderV13(out, FEATURES_REQUEST_MESSAGE_CODE_TYPE, 8); + } + + /** + * Testing of {@link GetFeaturesInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testV10() throws Exception { + GetFeaturesInputBuilder gfib = new GetFeaturesInputBuilder(); + BufferHelper.setupHeader(gfib, EncodeConstants.OF10_VERSION_ID); + GetFeaturesInput gfi = gfib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + featuresFactory.serialize(gfi, out); + + BufferHelper.checkHeaderV10(out, FEATURES_REQUEST_MESSAGE_CODE_TYPE, 8); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetFeaturesOutputFactoryTest.java new file mode 100644 index 0000000000..271933d345 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..780e148e2d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetQueueConfigInputMessageFactoryTest.java @@ -0,0 +1,65 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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 timotej.kubas + * @author michal.polkorab + */ +public class GetQueueConfigInputMessageFactoryTest { + private static final byte GET_QUEUE_CONFIG_INPUT_MESSAGE_CODE_TYPE = 22; + private static final byte PADDING_IN_QUEUE_CONFIG_INPUT_MESSAGE = 4; + private SerializerRegistry registry; + private OFSerializer getQueueFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + getQueueFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetQueueConfigInput.class)); + } + + /** + * Testing of {@link GetQueueConfigInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testGetQueueConfigInputMessage() throws Exception { + GetQueueConfigInputBuilder builder = new GetQueueConfigInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPort(new PortNumber(0x00010203L)); + GetQueueConfigInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + getQueueFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, GET_QUEUE_CONFIG_INPUT_MESSAGE_CODE_TYPE, 16); + Assert.assertEquals("Wrong port", 0x00010203, out.readUnsignedInt()); + out.skipBytes(PADDING_IN_QUEUE_CONFIG_INPUT_MESSAGE); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetaAsyncRequestMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetaAsyncRequestMessageFactoryTest.java new file mode 100644 index 0000000000..0bdc867587 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GetaAsyncRequestMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.GetAsyncInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInputBuilder; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class GetaAsyncRequestMessageFactoryTest { + private static final byte MESSAGE_TYPE = 26; + private static final int MESSAGE_LENGTH = 8; + private SerializerRegistry registry; + private OFSerializer getAsyncFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + getAsyncFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GetAsyncInput.class)); + } + + /** + * Testing of {@link GetAsyncRequestMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testGetAsyncReques() throws Exception { + GetAsyncInputBuilder builder = new GetAsyncInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + GetAsyncInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + getAsyncFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, MESSAGE_LENGTH); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java new file mode 100644 index 0000000000..6e75130f9e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/GroupModInputMessageFactoryTest.java @@ -0,0 +1,143 @@ +/* + * 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.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.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 timotej.kubas + * + */ +public class GroupModInputMessageFactoryTest { + private static final byte MESSAGE_TYPE = 15; + private static final byte PADDING_IN_GROUP_MOD_MESSAGE = 1; + private SerializerRegistry registry; + private OFSerializer groupModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + groupModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, GroupModInput.class)); + } + + /** + * @throws Exception + * Testing of {@link GroupModInputMessageFactory} for correct translation from POJO + */ + @Test + public void testGroupModInputMessage() throws Exception { + GroupModInputBuilder builder = new GroupModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setCommand(GroupModCommand.forValue(2)); + builder.setType(GroupType.forValue(3)); + builder.setGroupId(new GroupId(256L)); + List exp = createBucketsList(); + builder.setBucketsList(exp); + 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()); + out.skipBytes(PADDING_IN_GROUP_MOD_MESSAGE); + Assert.assertEquals("Wrong groupId", message.getGroupId().getValue().intValue(), out.readUnsignedInt()); + List rec = createBucketsListFromBufer(out); + Assert.assertArrayEquals("Wrong bucketList", exp.toArray(), rec.toArray()); + } + + private static List createBucketsList(){ + List bucketsList = new ArrayList<>(); + BucketsListBuilder bucketsBuilder = new BucketsListBuilder(); + BucketsList bucket; + bucketsBuilder.setWeight(10); + bucketsBuilder.setWatchPort(new PortNumber(65L)); + bucketsBuilder.setWatchGroup(22L); + bucket = bucketsBuilder.build(); + bucketsList.add(bucket); + return bucketsList; + } + + private static List createBucketsListFromBufer(ByteBuf out){ + List bucketsList = new ArrayList<>(); + BucketsListBuilder bucketsBuilder = new BucketsListBuilder(); + BucketsList bucket; + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + bucketsBuilder.setWeight(out.readUnsignedShort()); + bucketsBuilder.setWatchPort(new PortNumber(out.readUnsignedInt())); + bucketsBuilder.setWatchGroup(out.readUnsignedInt()); + out.skipBytes(4); + bucket = bucketsBuilder.build(); + bucketsList.add(bucket); + return bucketsList; + } + + /** + * Testing of {@link GroupModInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testGroupModInputWithNoBuckets() throws Exception { + GroupModInputBuilder builder = new GroupModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setCommand(GroupModCommand.forValue(2)); + builder.setType(GroupType.forValue(3)); + builder.setGroupId(new GroupId(256L)); + GroupModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + groupModFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 16); + Assert.assertEquals("Wrong command", message.getCommand().getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readUnsignedByte()); + out.skipBytes(PADDING_IN_GROUP_MOD_MESSAGE); + Assert.assertEquals("Wrong groupId", message.getGroupId().getValue().intValue(), out.readUnsignedInt()); + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java new file mode 100644 index 0000000000..e9319a9620 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/HelloInputMessageFactoryTest.java @@ -0,0 +1,190 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.opendaylight.openflow.common.types.rev130731.HelloElementType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; +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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class HelloInputMessageFactoryTest { + + private static final Logger LOG = LoggerFactory.getLogger(HelloInputMessageFactoryTest.class); + private SerializerRegistry registry; + private OFSerializer helloFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + helloFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, HelloInput.class)); + } + + /** + * Testing of {@link HelloInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testWithoutElementsSet() throws Exception { + HelloInputBuilder hib = new HelloInputBuilder(); + BufferHelper.setupHeader(hib, EncodeConstants.OF13_VERSION_ID); + HelloInput hi = hib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + helloFactory.serialize(hi, out); + + BufferHelper.checkHeaderV13(out,(byte) 0, EncodeConstants.OFHEADER_SIZE); + } + + /** + * Testing of {@link HelloInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testWith4BitVersionBitmap() throws Exception { + int lengthOfBitmap = 4; + HelloInputBuilder builder = new HelloInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + List expectedElement = createElement(lengthOfBitmap); + builder.setElements(expectedElement); + HelloInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + helloFactory.serialize(message, out); + if (LOG.isDebugEnabled()) { + LOG.debug("bytebuf: {}", ByteBufUtils.byteBufToHexString(out)); + } + + BufferHelper.checkHeaderV13(out, (byte) 0, 16); + Elements element = readElement(out).get(0); + Assert.assertEquals("Wrong element type", expectedElement.get(0).getType(), element.getType()); + Elements comparation = createComparationElement(lengthOfBitmap).get(0); + Assert.assertArrayEquals("Wrong element bitmap", comparation.getVersionBitmap().toArray(), element.getVersionBitmap().toArray()); + } + + /** + * Testing of {@link HelloInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testWith64BitVersionBitmap() throws Exception { + int lengthOfBitmap = 64; + HelloInputBuilder builder = new HelloInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + List expectedElement = createElement(lengthOfBitmap); + builder.setElements(expectedElement); + HelloInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + helloFactory.serialize(message, out); + if (LOG.isDebugEnabled()) { + LOG.debug("bytebuf: ", ByteBufUtils.byteBufToHexString(out)); + } + + BufferHelper.checkHeaderV13(out, (byte) 0, 24); + Elements element = readElement(out).get(0); + Assert.assertEquals("Wrong element type", expectedElement.get(0).getType(), element.getType()); + Elements comparation = createComparationElement(lengthOfBitmap).get(0); + Assert.assertArrayEquals("Wrong element bitmap", comparation.getVersionBitmap().toArray(), element.getVersionBitmap().toArray()); + } + + private static List createElement(int lengthOfBitmap) { + ElementsBuilder elementsBuilder = new ElementsBuilder(); + List elementsList = new ArrayList<>(); + List booleanList = new ArrayList<>(); + for (int i = 0; i < lengthOfBitmap; i++) { + booleanList.add(true); + } + elementsBuilder.setType(HelloElementType.forValue(1)); + elementsBuilder.setVersionBitmap(booleanList); + elementsList.add(elementsBuilder.build()); + return elementsList; + } + + private static List createComparationElement(int lengthOfBitmap) { + ElementsBuilder elementsBuilder = new ElementsBuilder(); + List elementsList = new ArrayList<>(); + List booleanList = new ArrayList<>(); + for (int i = 0; i < lengthOfBitmap; i++) { + booleanList.add(true); + } + if ((lengthOfBitmap % Integer.SIZE) != 0) { + for (int i = 0; i < (Integer.SIZE - (lengthOfBitmap % Integer.SIZE)); i++) { + booleanList.add(false); + } + } + LOG.debug("boolsize {}", booleanList.size()); + elementsBuilder.setType(HelloElementType.forValue(1)); + elementsBuilder.setVersionBitmap(booleanList); + elementsList.add(elementsBuilder.build()); + return elementsList; + } + + private static List readElement(ByteBuf input) { + List elementsList = new ArrayList<>(); + while (input.readableBytes() > 0) { + ElementsBuilder elementsBuilder = new ElementsBuilder(); + int type = input.readUnsignedShort(); + int elementLength = input.readUnsignedShort(); + if (type == HelloElementType.VERSIONBITMAP.getIntValue()) { + elementsBuilder.setType(HelloElementType.forValue(type)); + int[] versionBitmap = new int[(elementLength - 4) / 4]; + for (int i = 0; i < versionBitmap.length; i++) { + versionBitmap[i] = (int) input.readUnsignedInt(); + } + elementsBuilder.setVersionBitmap(readVersionBitmap(versionBitmap)); + int paddingRemainder = elementLength % EncodeConstants.PADDING; + if (paddingRemainder != 0) { + input.readBytes(EncodeConstants.PADDING - paddingRemainder); + } + } + elementsList.add(elementsBuilder.build()); + } + return elementsList; + } + + private static List readVersionBitmap(int[] input){ + List versionBitmapList = new ArrayList<>(); + for (int i = 0; i < input.length; i++) { + int mask = input[i]; + for (int j = 0; j < Integer.SIZE; j++) { + versionBitmapList.add((mask & (1< 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactoryTest.java new file mode 100644 index 0000000000..115c0755da --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MeterModInputMessageFactoryTest.java @@ -0,0 +1,160 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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.MeterModInputBuilder; +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 timotej.kubas + * @author michal.polkorab + */ +public class MeterModInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer meterModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + meterModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MeterModInput.class)); + } + + /** + * @throws Exception + * Testing of {@link MeterModInputMessageFactory} for correct translation from POJO + */ + @Test + public void testMeterModInputMessage() throws Exception { + MeterModInputBuilder builder = new MeterModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setCommand(MeterModCommand.forValue(1)); + builder.setFlags(new MeterFlags(false, true, true, false)); + builder.setMeterId(new MeterId(2248L)); + builder.setBands(createBandsList()); + MeterModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + meterModFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 29, 48); + Assert.assertEquals("Wrong meterModCommand", message.getCommand().getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong meterFlags", message.getFlags(), decodeMeterModFlags(out.readShort())); + Assert.assertEquals("Wrong meterId", message.getMeterId().getValue().intValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong bands", message.getBands(), decodeBandsList(out)); + } + + private static MeterFlags decodeMeterModFlags(short input){ + final Boolean _oFPMFKBPS = (input & (1 << 0)) > 0; + final Boolean _oFPMFPKTPS = (input & (1 << 1)) > 0; + final Boolean _oFPMFBURST = (input & (1 << 2)) > 0; + final Boolean _oFPMFSTATS = (input & (1 << 3)) > 0; + return new MeterFlags(_oFPMFBURST, _oFPMFKBPS, _oFPMFPKTPS, _oFPMFSTATS); + } + + 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 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()); + input.skipBytes(4); + 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(input.readUnsignedByte()); + input.skipBytes(3); + dscpCaseBuilder.setMeterBandDscpRemark(dscpRemarkBand.build()); + bandsList.add(bandsBuilder.setMeterBand(dscpCaseBuilder.build()).build()); + return bandsList; + } + + /** + * @throws Exception + * Testing of {@link MeterModInputMessageFactory} for correct translation from POJO + */ + @Test + public void testMeterModInputMessageWithNoBands() throws Exception { + MeterModInputBuilder builder = new MeterModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setCommand(MeterModCommand.forValue(1)); + builder.setFlags(new MeterFlags(false, true, true, false)); + builder.setMeterId(new MeterId(2248L)); + builder.setBands(null); + MeterModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + meterModFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 29, 16); + Assert.assertEquals("Wrong meterModCommand", message.getCommand().getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong meterFlags", message.getFlags(), decodeMeterModFlags(out.readShort())); + Assert.assertEquals("Wrong meterId", message.getMeterId().getValue().intValue(), out.readUnsignedInt()); + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartReplyMessageFactoryTest.java new file mode 100644 index 0000000000..a6e18bde80 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java new file mode 100644 index 0000000000..f87a18a071 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/MultipartRequestInputFactoryTest.java @@ -0,0 +1,454 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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.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.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.MultipartRequestAggregateCaseBuilder; +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.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.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.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.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.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.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.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; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class MultipartRequestInputFactoryTest { + /** padding in MultipartRequest message */ + public static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = 4; + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestFlowInputFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(1)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestFlow()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 48); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong flow", message.getMultipartRequestBody(), decodeRequestFlow(out)); + } + + 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()); + //TODO match field + return caseBuilder.build(); + } + + private static MultipartRequestFlowCase decodeRequestFlow(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01 = 3; + final byte PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02 = 4; + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder builder = new MultipartRequestFlowBuilder(); + builder.setTableId(output.readUnsignedByte()); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_01); + builder.setOutPort(output.readUnsignedInt()); + builder.setOutGroup(output.readUnsignedInt()); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_FLOW_BODY_02); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + output.readBytes(cookie); + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + output.readBytes(cookieMask); + builder.setCookieMask(new BigInteger(1, cookieMask)); + caseBuilder.setMultipartRequestFlow(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestInputAggregateBodyFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(2)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestAggregate()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 48); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong aggregate", message.getMultipartRequestBody(), decodeRequestAggregate(out)); + } + + private static MultipartRequestFlags decodeMultipartRequestFlags(short input){ + final Boolean _oFPMPFREQMORE = (input & (1 << 0)) > 0; + return new MultipartRequestFlags(_oFPMPFREQMORE); + } + + + 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()); + //TODO match field + return caseBuilder.build(); + } + + private static MultipartRequestAggregateCase decodeRequestAggregate(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY_01 = 3; + final byte PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY_02 = 4; + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder builder = new MultipartRequestAggregateBuilder(); + builder.setTableId(output.readUnsignedByte()); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY_01); + builder.setOutPort(output.readUnsignedInt()); + builder.setOutGroup(output.readUnsignedInt()); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_AGGREGATE_BODY_02); + byte[] cookie = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + output.readBytes(cookie); + builder.setCookie(new BigInteger(1, cookie)); + byte[] cookieMask = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + output.readBytes(cookieMask); + builder.setCookieMask(new BigInteger(1, cookieMask)); + caseBuilder.setMultipartRequestAggregate(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestInputTableFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(3)); + builder.setFlags(new MultipartRequestFlags(true)); + //multipart request for registry does not have body + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestPortStatsMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(4)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestPortStats()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 24); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong portStatsBody", message.getMultipartRequestBody(), decodeRequestPortStats(out)); + } + + private static MultipartRequestPortStatsCase createRequestPortStats() { + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder builder = new MultipartRequestPortStatsBuilder(); + builder.setPortNo(2251L); + caseBuilder.setMultipartRequestPortStats(builder.build()); + return caseBuilder.build(); + } + + private static MultipartRequestPortStatsCase decodeRequestPortStats(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY = 4; + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder builder = new MultipartRequestPortStatsBuilder(); + builder.setPortNo(output.readUnsignedInt()); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_PORTSTATS_BODY); + caseBuilder.setMultipartRequestPortStats(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestQueueMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(5)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestQueue()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 24); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong queueBody", message.getMultipartRequestBody(), decodeRequestQueue(out)); + } + + 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(); + } + + private static MultipartRequestQueueCase decodeRequestQueue(ByteBuf output) { + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder builder = new MultipartRequestQueueBuilder(); + builder.setPortNo(output.readUnsignedInt()); + builder.setQueueId(output.readUnsignedInt()); + caseBuilder.setMultipartRequestQueue(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestGroupMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(6)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestGroup()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 24); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong groupBody", message.getMultipartRequestBody(), decodeRequestGroup(out)); + } + + private static MultipartRequestGroupCase createRequestGroup() { + MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder(); + MultipartRequestGroupBuilder builder = new MultipartRequestGroupBuilder(); + builder.setGroupId(new GroupId(2258L)); + caseBuilder.setMultipartRequestGroup(builder.build()); + return caseBuilder.build(); + } + + private static MultipartRequestGroupCase decodeRequestGroup(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_GROUP_BODY = 4; + MultipartRequestGroupCaseBuilder caseBuilder = new MultipartRequestGroupCaseBuilder(); + MultipartRequestGroupBuilder builder = new MultipartRequestGroupBuilder(); + builder.setGroupId(new GroupId(output.readUnsignedInt())); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_GROUP_BODY); + caseBuilder.setMultipartRequestGroup(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestMeterMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(9)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestMeter()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 24); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong meterBody", message.getMultipartRequestBody(), decodeRequestMeter(out)); + } + + private static MultipartRequestMeterCase createRequestMeter() { + MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder(); + MultipartRequestMeterBuilder builder = new MultipartRequestMeterBuilder(); + builder.setMeterId(new MeterId(1121L)); + caseBuilder.setMultipartRequestMeter(builder.build()); + return caseBuilder.build(); + } + + private static MultipartRequestMeterCase decodeRequestMeter(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_METER_BODY = 4; + MultipartRequestMeterCaseBuilder caseBuilder = new MultipartRequestMeterCaseBuilder(); + MultipartRequestMeterBuilder builder = new MultipartRequestMeterBuilder(); + builder.setMeterId(new MeterId(output.readUnsignedInt())); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_METER_BODY); + caseBuilder.setMultipartRequestMeter(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestMeterConfigMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(10)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestMeterConfig()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 24); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong meterConfigBody", message.getMultipartRequestBody(), decodeRequestMeterConfig(out)); + } + + private static MultipartRequestMeterConfigCase createRequestMeterConfig() { + MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder(); + MultipartRequestMeterConfigBuilder builder = new MultipartRequestMeterConfigBuilder(); + builder.setMeterId(new MeterId(1133L)); + caseBuilder.setMultipartRequestMeterConfig(builder.build()); + return caseBuilder.build(); + } + + private static MultipartRequestMeterConfigCase decodeRequestMeterConfig(ByteBuf output) { + final byte PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY = 4; + MultipartRequestMeterConfigCaseBuilder caseBuilder = new MultipartRequestMeterConfigCaseBuilder(); + MultipartRequestMeterConfigBuilder builder = new MultipartRequestMeterConfigBuilder(); + builder.setMeterId(new MeterId(output.readUnsignedInt())); + output.skipBytes(PADDING_IN_MULTIPART_REQUEST_METER_CONFIG_BODY); + caseBuilder.setMultipartRequestMeterConfig(builder.build()); + return caseBuilder.build(); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestDescMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(0)); + builder.setFlags(new MultipartRequestFlags(true)); + builder.setMultipartRequestBody(createRequestDesc()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", message.getType().getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", message.getFlags(), decodeMultipartRequestFlags(out.readShort())); + } + + private static MultipartRequestBody createRequestDesc() { + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder builder = new MultipartRequestDescBuilder(); + caseBuilder.setMultipartRequestDesc(builder.build()); + return caseBuilder.build(); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactoryTest.java new file mode 100644 index 0000000000..cc31a00e84 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierInputMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.BarrierInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class OF10BarrierInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer barrierFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + barrierFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, BarrierInput.class)); + } + + /** + * Testing of {@link OF10BarrierInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void test() throws Exception { + BarrierInputBuilder bib = new BarrierInputBuilder(); + BufferHelper.setupHeader(bib, EncodeConstants.OF10_VERSION_ID); + BarrierInput bi = bib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + barrierFactory.serialize(bi, out); + + BufferHelper.checkHeaderV10(out, (byte) 18, 8); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10BarrierReplyMessageFactoryTest.java new file mode 100644 index 0000000000..7ec4e44643 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FeaturesReplyMessageFactoryTest.java new file mode 100644 index 0000000000..ecfbcad559 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java new file mode 100644 index 0000000000..b8343bbd8a --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowModInputMessageFactoryTest.java @@ -0,0 +1,158 @@ +/* + * 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.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.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.MatchV10Builder; +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 michal.polkorab + * + */ +public class OF10FlowModInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer flowModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + flowModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, FlowModInput.class)); + } + + /** + * @throws Exception + * Testing of {@link OF10FlowModInputMessageFactory} for correct translation from POJO + */ + @Test + public void testFlowModInputMessageFactory() throws Exception { + FlowModInputBuilder builder = new FlowModInputBuilder(); + 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, 0x06, 0x00, 0x07, 0x01}; + builder.setCookie(new BigInteger(1, cookie)); + builder.setCommand(FlowModCommand.forValue(0)); + builder.setIdleTimeout(12); + builder.setHardTimeout(16); + builder.setPriority(1); + builder.setBufferId(2L); + builder.setOutPort(new PortNumber(4422L)); + builder.setFlagsV10(new FlowModFlagsV10(true, false, true)); + 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()); + builder.setAction(actions); + FlowModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + flowModFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 14, 88); + Assert.assertEquals("Wrong wildcards", 3678463, out.readUnsignedInt()); + Assert.assertEquals("Wrong inPort", 58, out.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + out.readBytes(dlSrc); + Assert.assertEquals("Wrong dlSrc", "01:01:01:01:01:01", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + out.readBytes(dlDst); + Assert.assertEquals("Wrong dlDst", "FF:FF:FF:FF:FF:FF", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dlVlan", 18, out.readUnsignedShort()); + Assert.assertEquals("Wrong dlVlanPcp", 5, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong dlType", 42, out.readUnsignedShort()); + Assert.assertEquals("Wrong nwTos", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong nwProto", 7, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong nwSrc", 134744072, out.readUnsignedInt()); + Assert.assertEquals("Wrong nwDst", 269488144, out.readUnsignedInt()); + Assert.assertEquals("Wrong tpSrc", 6653, out.readUnsignedShort()); + Assert.assertEquals("Wrong tpDst", 6633, out.readUnsignedShort()); + byte[] cookieRead = new byte[8]; + out.readBytes(cookieRead); + Assert.assertArrayEquals("Wrong cookie", cookie, cookieRead); + Assert.assertEquals("Wrong command", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong idleTimeOut", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong hardTimeOut", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong priority", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong bufferId", 2, out.readUnsignedInt()); + Assert.assertEquals("Wrong outPort", 4422, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong action - type", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong action - length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 33686018, out.readUnsignedInt()); + Assert.assertEquals("Wrong action - type", 9, out.readUnsignedShort()); + Assert.assertEquals("Wrong action - length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 42, out.readUnsignedShort()); + out.skipBytes(2); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10FlowRemovedMessageFactoryTest.java new file mode 100644 index 0000000000..ed54d82e8a --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactoryTest.java new file mode 100644 index 0000000000..b7ed855b8c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10HelloInputMessageFactoryTest.java @@ -0,0 +1,61 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class OF10HelloInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer helloFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + helloFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, HelloInput.class)); + } + + /** + * Testing of {@link OF10HelloInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testWithoutElementsSet() throws Exception { + HelloInputBuilder hib = new HelloInputBuilder(); + BufferHelper.setupHeader(hib, EncodeConstants.OF10_VERSION_ID); + HelloInput hi = hib.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + helloFactory.serialize(hi, out); + + BufferHelper.checkHeaderV10(out, (byte) 0, 8); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketInMessageFactoryTest.java new file mode 100644 index 0000000000..abe0055dd2 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java new file mode 100644 index 0000000000..af4f139e93 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PacketOutInputMessageFactoryTest.java @@ -0,0 +1,125 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class OF10PacketOutInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer packetOutFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + packetOutFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, PacketOutInput.class)); + } + + /** + * Testing of {@link OF10PacketOutInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPacketOutInputMessage() throws Exception { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setBufferId(256L); + builder.setInPort(new PortNumber(257L)); + 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()); + builder.setAction(actions); + actions.add(actionBuilder.build()); + builder.setAction(actions); + builder.setData(ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14")); + PacketOutInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + packetOutFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 13, 48); + Assert.assertEquals("Wrong BufferId", 256, out.readUnsignedInt()); + Assert.assertEquals("Wrong PortNumber", 257, out.readUnsignedShort()); + Assert.assertEquals("Wrong actions length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 42, out.readUnsignedShort()); + Assert.assertEquals("Wrong maxlength", 50, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + byte[] readData = new byte[out.readableBytes()]; + out.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing of {@link OF10PacketOutInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPacketOutInputWithNoData() throws Exception { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setBufferId(256L); + builder.setInPort(new PortNumber(257L)); + List actions = new ArrayList<>(); + builder.setAction(actions); + builder.setData(null); + PacketOutInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + packetOutFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 13, 16); + out.skipBytes(8); // skip packet out message to data index + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java new file mode 100644 index 0000000000..da063fbd33 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortModInputMessageFactoryTest.java @@ -0,0 +1,81 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class OF10PortModInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer portModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + portModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, PortModInput.class)); + } + + /** + * Testing of {@link OF10PortModInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPortModInput() throws Exception { + PortModInputBuilder builder = new PortModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setPortNo(new PortNumber(6633L)); + builder.setHwAddress(new MacAddress("08:00:27:00:B0:EB")); + builder.setConfigV10(new PortConfigV10(true, false, false, true, false, false, true)); + builder.setMaskV10(new PortConfigV10(false, true, true, false, false, true, false)); + builder.setAdvertiseV10(new PortFeaturesV10(true, true, false, false, false, false, + false, true, true, false, false, false)); + PortModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + portModFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 15, 32); + Assert.assertEquals("Wrong PortNo", message.getPortNo().getValue().longValue(), out.readUnsignedShort()); + byte[] address = new byte[6]; + out.readBytes(address); + Assert.assertEquals("Wrong MacAddress", message.getHwAddress(), + new MacAddress(ByteBufUtils.macAddressToString(address))); + Assert.assertEquals("Wrong config", 21, out.readUnsignedInt()); + Assert.assertEquals("Wrong mask", 98, out.readUnsignedInt()); + Assert.assertEquals("Wrong advertise", 652, out.readUnsignedInt()); + out.skipBytes(4); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10PortStatusMessageFactoryTest.java new file mode 100644 index 0000000000..116882797e --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactoryTest.java new file mode 100644 index 0000000000..81234dde45 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigInputMessageFactoryTest.java @@ -0,0 +1,65 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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 michal.polkorab + * + */ +public class OF10QueueGetConfigInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer queueFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + queueFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, GetQueueConfigInput.class)); + } + + /** + * Testing of {@link OF10QueueGetConfigInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void test() throws Exception { + GetQueueConfigInputBuilder builder = new GetQueueConfigInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setPort(new PortNumber(6653L)); + GetQueueConfigInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + queueFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 20, 12); + Assert.assertEquals("Wrong port", 6653L, out.readUnsignedShort()); + out.skipBytes(2); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..c46d03d7fd --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsReplyMessageFactoryTest.java new file mode 100644 index 0000000000..8b52cb01ed --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java new file mode 100644 index 0000000000..c44b9f0c86 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/OF10StatsRequestInputFactoryTest.java @@ -0,0 +1,303 @@ +/* + * 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.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.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; +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.MultipartRequestInputBuilder; +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.MultipartRequestFlowCaseBuilder; +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.MultipartRequestQueueCaseBuilder; +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.desc._case.MultipartRequestDescBuilder; +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 michal.polkorab + * + */ +public class OF10StatsRequestInputFactoryTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Testing OF10StatsRequestInputFactory (Desc) for correct serialization + * @throws Exception + */ + @Test + public void testDesc() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPDESC); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestDescCaseBuilder caseBuilder = new MultipartRequestDescCaseBuilder(); + MultipartRequestDescBuilder descBuilder = new MultipartRequestDescBuilder(); + caseBuilder.setMultipartRequestDesc(descBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 12); + Assert.assertEquals("Wrong type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing OF10StatsRequestInputFactory (Flow) for correct serialization + * @throws Exception + */ + @Test + public void testFlow() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPFLOW); + builder.setFlags(new MultipartRequestFlags(false)); + 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()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 56); + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong wildcards", 3414271, out.readUnsignedInt()); + Assert.assertEquals("Wrong in-port", 51, out.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + out.readBytes(dlSrc); + Assert.assertEquals("Wrong dl-src", "00:01:02:03:04:05", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + out.readBytes(dlDst); + Assert.assertEquals("Wrong dl-dst", "05:04:03:02:01:00", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dl-vlan", 52, out.readUnsignedShort()); + Assert.assertEquals("Wrong dl-vlan-pcp", 53, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong dl-type", 54, out.readUnsignedShort()); + Assert.assertEquals("Wrong nw-tos", 55, out.readUnsignedByte()); + Assert.assertEquals("Wrong nw-proto", 56, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong nw-src", 167772161, out.readUnsignedInt()); + Assert.assertEquals("Wrong nw-dst", 167772162, out.readUnsignedInt()); + Assert.assertEquals("Wrong tp-src", 57, out.readUnsignedShort()); + Assert.assertEquals("Wrong tp-dst", 58, out.readUnsignedShort()); + Assert.assertEquals("Wrong table-id", 1, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong out-port", 42, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing OF10StatsRequestInputFactory (Aggregate) for correct serialization + * @throws Exception + */ + @Test + public void testAggregate() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPAGGREGATE); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestFlowCaseBuilder caseBuilder = new MultipartRequestFlowCaseBuilder(); + MultipartRequestFlowBuilder flowBuilder = new MultipartRequestFlowBuilder(); + 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); + flowBuilder.setMatchV10(matchBuilder.build()); + flowBuilder.setTableId((short) 42); + flowBuilder.setOutPort(6653L); + caseBuilder.setMultipartRequestFlow(flowBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 56); + Assert.assertEquals("Wrong type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong wildcards", 0, out.readUnsignedInt()); + Assert.assertEquals("Wrong in-port", 51, out.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + out.readBytes(dlSrc); + Assert.assertEquals("Wrong dl-src", "00:01:02:03:04:05", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + out.readBytes(dlDst); + Assert.assertEquals("Wrong dl-dst", "05:04:03:02:01:00", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dl-vlan", 52, out.readUnsignedShort()); + Assert.assertEquals("Wrong dl-vlan-pcp", 53, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong dl-type", 54, out.readUnsignedShort()); + Assert.assertEquals("Wrong nw-tos", 55, out.readUnsignedByte()); + Assert.assertEquals("Wrong nw-proto", 56, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong nw-src", 167772161, out.readUnsignedInt()); + Assert.assertEquals("Wrong nw-dst", 167772162, out.readUnsignedInt()); + Assert.assertEquals("Wrong tp-src", 57, out.readUnsignedShort()); + Assert.assertEquals("Wrong tp-dst", 58, out.readUnsignedShort()); + Assert.assertEquals("Wrong table-id", 42, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong out-port", 6653, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing OF10StatsRequestInputFactory (Table) for correct serialization + * @throws Exception + */ + @Test + public void testTable() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPTABLE); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder(); + MultipartRequestTableBuilder tableBuilder = new MultipartRequestTableBuilder(); + caseBuilder.setMultipartRequestTable(tableBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 12); + Assert.assertEquals("Wrong type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing OF10StatsRequestInputFactory (Port) for correct serialization + * @throws Exception + */ + @Test + public void testPort() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPPORTSTATS); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestPortStatsCaseBuilder caseBuilder = new MultipartRequestPortStatsCaseBuilder(); + MultipartRequestPortStatsBuilder portBuilder = new MultipartRequestPortStatsBuilder(); + portBuilder.setPortNo(15L); + caseBuilder.setMultipartRequestPortStats(portBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 20); + Assert.assertEquals("Wrong type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong port-no", 15, out.readUnsignedShort()); + out.skipBytes(6); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing OF10StatsRequestInputFactory (Queue) for correct serialization + * @throws Exception + */ + @Test + public void testQueue() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPQUEUE); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestQueueCaseBuilder caseBuilder = new MultipartRequestQueueCaseBuilder(); + MultipartRequestQueueBuilder queueBuilder = new MultipartRequestQueueBuilder(); + queueBuilder.setPortNo(15L); + queueBuilder.setQueueId(16L); + caseBuilder.setMultipartRequestQueue(queueBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 20); + Assert.assertEquals("Wrong type", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong port-no", 15, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong queue-id", 16, out.readUnsignedInt()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketInMessageFactoryTest.java new file mode 100644 index 0000000000..8f917b7b14 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java new file mode 100644 index 0000000000..60ee5210f1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PacketOutInputMessageFactoryTest.java @@ -0,0 +1,126 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder; + +/** + * @author timotej.kubas + * + */ +public class PacketOutInputMessageFactoryTest { + private static final byte MESSAGE_TYPE = 13; + private static final byte PADDING_IN_PACKET_OUT_MESSAGE = 6; + private static final int PADDING_IN_ACTION_HEADER = 4; + private SerializerRegistry registry; + private OFSerializer packetOutFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + packetOutFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, PacketOutInput.class)); + } + + /** + * Testing of {@link PacketOutInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPacketOutInputMessage() throws Exception { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setBufferId(256L); + builder.setInPort(new PortNumber(256L)); + 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()); + builder.setAction(actions); + builder.setData(ByteBufUtils.hexStringToBytes("00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14")); + PacketOutInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + packetOutFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 56); + Assert.assertEquals("Wrong BufferId", message.getBufferId().longValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong PortNumber", message.getInPort().getValue().longValue(), out.readUnsignedInt()); + Assert.assertEquals("Wrong ActionsLength", 16, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_PACKET_OUT_MESSAGE); + Assert.assertEquals("Wrong action type", 17, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong ethertype", 25, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong action type", 18, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_ACTION_HEADER); + byte[] readData = new byte[out.readableBytes()]; + out.readBytes(readData); + Assert.assertArrayEquals("Wrong data", message.getData(), readData); + } + + /** + * Testing of {@link PacketOutInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPacketOutInputWithNoData() throws Exception { + PacketOutInputBuilder builder = new PacketOutInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setBufferId(256L); + builder.setInPort(new PortNumber(256L)); + List actions = new ArrayList<>(); + builder.setAction(actions); + builder.setData(null); + PacketOutInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + packetOutFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 24); + out.skipBytes(16); // skip packet out message to data index + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java new file mode 100644 index 0000000000..f931901917 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortModInputMessageFactoryTest.java @@ -0,0 +1,129 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInputBuilder; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class PortModInputMessageFactoryTest { + 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; + private static final int MESSAGE_LENGTH = 40; + private SerializerRegistry registry; + private OFSerializer portModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + portModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, PortModInput.class)); + } + + /** + * Testing of {@link PortModInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testPortModInput() throws Exception { + PortModInputBuilder builder = new PortModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPortNo(new PortNumber(9L)); + builder.setHwAddress(new MacAddress("08:00:27:00:B0:EB")); + builder.setConfig(new PortConfig(true, false, true, false)); + builder.setMask(new PortConfig(false, true, false, true)); + builder.setAdvertise(new PortFeatures(true, false, false, false, + false, false, false, true, + false, false, false, false, + false, false, false, false)); + 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); + byte[] address = new byte[6]; + out.readBytes(address); + Assert.assertEquals("Wrong MacAddress", message.getHwAddress().getValue(), + new MacAddress(ByteBufUtils.macAddressToString(address)).getValue()); + out.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_02); + Assert.assertEquals("Wrong config", message.getConfig(), createPortConfig(out.readInt())); + Assert.assertEquals("Wrong mask", message.getMask(), createPortConfig(out.readInt())); + Assert.assertEquals("Wrong advertise", message.getAdvertise(), createPortFeatures(out.readInt())); + out.skipBytes(PADDING_IN_PORT_MOD_MESSAGE_03); + } + + 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); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/PortStatusMessageFactoryTest.java new file mode 100644 index 0000000000..362d2fd86f --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/QueueGetConfigReplyMessageFactoryTest.java new file mode 100644 index 0000000000..c69a0da130 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleReplyMessageFactoryTest.java new file mode 100644 index 0000000000..8ed5855319 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactoryTest.java new file mode 100644 index 0000000000..ac09080bf8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/RoleRequestInputMessageFactoryTest.java @@ -0,0 +1,74 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.common.types.rev130731.ControllerRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInputBuilder; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class RoleRequestInputMessageFactoryTest { + private static final byte MESSAGE_TYPE = 24; + private static final int MESSAGE_LENGTH = 24; + private static final byte PADDING_IN_ROLE_REQUEST_MESSAGE = 4; + private SerializerRegistry registry; + private OFSerializer roleFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + roleFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, RoleRequestInput.class)); + } + + /** + * Testing of {@link RoleRequestInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testRoleRequestInputMessage() throws Exception { + RoleRequestInputBuilder builder = new RoleRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setRole(ControllerRole.forValue(2)); + byte[] generationId = new byte[]{(byte) 0xFF, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; + builder.setGenerationId(new BigInteger(1, generationId)); + RoleRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + roleFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, MESSAGE_LENGTH); + Assert.assertEquals("Wrong role", message.getRole().getIntValue(), ControllerRole.forValue((int) out.readUnsignedInt()).getIntValue()); + out.skipBytes(PADDING_IN_ROLE_REQUEST_MESSAGE); + byte[] genId = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(genId); + Assert.assertEquals("Wrong generation ID", message.getGenerationId(), new BigInteger(1, genId)); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactoryTest.java new file mode 100644 index 0000000000..1f2ff731d0 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetAsyncInputMessageFactoryTest.java @@ -0,0 +1,161 @@ +/* + * 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.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.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 timotej.kubas + * @author michal.polkorab + */ +public class SetAsyncInputMessageFactoryTest { + + private SerializerRegistry registry; + private OFSerializer setAsyncFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + setAsyncFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, SetAsyncInput.class)); + } + + /** + * @throws Exception + * Testing of {@link SetAsyncInputMessageFactory} for correct translation from POJO + */ + @Test + public void testSetAsyncInputMessage() throws Exception { + SetAsyncInputBuilder builder = new SetAsyncInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPacketInMask(createPacketInMask()); + builder.setPortStatusMask(createPortStatusMask()); + builder.setFlowRemovedMask(createFlowRemowedMask()); + SetAsyncInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + setAsyncFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out,(byte) 28, 32); + Assert.assertEquals("Wrong packetInMask", 7, out.readUnsignedInt()); + Assert.assertEquals("Wrong packetInMask", 0, out.readUnsignedInt()); + Assert.assertEquals("Wrong portStatusMask", 7, out.readUnsignedInt()); + Assert.assertEquals("Wrong portStatusMask", 0, out.readUnsignedInt()); + Assert.assertEquals("Wrong flowRemovedMask", 15, out.readUnsignedInt()); + Assert.assertEquals("Wrong flowRemovedMask", 0, out.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; + } + + /** + * @throws Exception + * Testing of {@link SetAsyncInputMessageFactory} for correct translation from POJO + */ + @Test + public void testSetAsyncInputWithNullMasks() throws Exception { + SetAsyncInputBuilder builder = new SetAsyncInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setPacketInMask(null); + builder.setPortStatusMask(null); + builder.setFlowRemovedMask(null); + SetAsyncInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + setAsyncFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out,(byte) 28, 8); + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactoryTest.java new file mode 100644 index 0000000000..700d1641f3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/SetConfigMessageFactoryTest.java @@ -0,0 +1,89 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.common.types.rev130731.SwitchConfigFlag; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInputBuilder; + +/** + * @author timotej.kubas + * @author michal.polkorab + */ +public class SetConfigMessageFactoryTest { + private static final byte MESSAGE_TYPE = 9; + private static final int MESSAGE_LENGTH = 12; + private SerializerRegistry registry; + private OFSerializer setConfigFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + setConfigFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, SetConfigInput.class)); + } + + /** + * Testing of {@link SetConfigMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testSetConfigMessageV13() throws Exception { + SetConfigInputBuilder builder = new SetConfigInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + SwitchConfigFlag flag = SwitchConfigFlag.FRAGNORMAL; + builder.setFlags(flag); + builder.setMissSendLen(10); + SetConfigInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + setConfigFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, MESSAGE_LENGTH); + Assert.assertEquals("Wrong flags", SwitchConfigFlag.FRAGNORMAL.getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong missSendLen", 10, out.readUnsignedShort()); + } + + /** + * Testing of {@link SetConfigMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testSetConfigMessageV10() throws Exception { + SetConfigInputBuilder builder = new SetConfigInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + SwitchConfigFlag flag = SwitchConfigFlag.OFPCFRAGDROP; + builder.setFlags(flag); + builder.setMissSendLen(85); + SetConfigInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + setConfigFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, MESSAGE_TYPE, MESSAGE_LENGTH); + Assert.assertEquals("Wrong flags", SwitchConfigFlag.OFPCFRAGDROP.getIntValue(), out.readUnsignedShort()); + Assert.assertEquals("Wrong missSendLen", 85, out.readUnsignedShort()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactoryTest.java new file mode 100644 index 0000000000..27ae645785 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/TableModInputMessageFactoryTest.java @@ -0,0 +1,69 @@ +/* + * 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.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.impl.serialization.SerializerRegistryImpl; +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.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 timotej.kubas + * @author michal.polkorab + */ +public class TableModInputMessageFactoryTest { + private static final byte MESSAGE_TYPE = 17; + private static final byte PADDING_IN_TABLE_MOD_MESSAGE = 3; + private SerializerRegistry registry; + private OFSerializer tableModFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + tableModFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, TableModInput.class)); + } + + /** + * Testing of {@link TableModInputMessageFactory} for correct translation from POJO + * @throws Exception + */ + @Test + public void testTableModInput() throws Exception { + TableModInputBuilder builder = new TableModInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setTableId(new TableId(9L)); + builder.setConfig(new TableConfig(true)); + TableModInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + tableModFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, MESSAGE_TYPE, 16); + Assert.assertEquals("Wrong TableID", message.getTableId().getValue().intValue(), out.readUnsignedByte()); + out.skipBytes(PADDING_IN_TABLE_MOD_MESSAGE); + Assert.assertEquals("Wrong TableConfig", 8, out.readUnsignedInt()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java new file mode 100644 index 0000000000..f299e818e9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/VendorInputMessageFactoryTest.java @@ -0,0 +1,64 @@ +/* + * 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.impl.serialization.factories; + +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 + * + */ +@RunWith(MockitoJUnitRunner.class) +public class VendorInputMessageFactoryTest { + + @Mock SerializerRegistry registry; + @Mock OFSerializer foundSerializer; + @Mock ExperimenterDataOfChoice vendorData; + VendorInputMessageFactory serializer; + + /** + * Tests {@link VendorInputMessageFactory#serialize(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterOfMessage, ByteBuf)} + */ + @Test + public void test() { + Mockito.when(registry.getSerializer(Matchers.>any())) + .thenReturn(serializer); + VendorInputMessageFactory factory = new VendorInputMessageFactory(); + factory.injectSerializerRegistry(registry); + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + ExperimenterInputBuilder builder = new ExperimenterInputBuilder(); + builder.setVersion((short) EncodeConstants.OF10_VERSION_ID); + 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(foundSerializer, Mockito.times(1)).serialize(experimenterInput.getExperimenterDataOfChoice(), buffer); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java new file mode 100644 index 0000000000..ce94f426a6 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestExperimenterTest.java @@ -0,0 +1,78 @@ +/* + * 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.impl.serialization.factories.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +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.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.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.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; + +/** + * @author michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class MultipartRequestExperimenterTest { + + @Mock SerializerRegistry mockRegistry; + @Mock OFSerializer serializer; + + @Mock ExperimenterDataOfChoice vendorData; + + /** + * Testing OF10StatsRequestInputFactory (Experimenter) for correct serialization + * @throws Exception + */ + @Test + public void testExperimenter() throws Exception { + Mockito.when(mockRegistry.getSerializer(Matchers.>any())) + .thenReturn(serializer); + MultipartRequestInputFactory multipartFactory = new MultipartRequestInputFactory(); + multipartFactory.injectSerializerRegistry(mockRegistry); + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPEXPERIMENTER); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); + MultipartRequestExperimenterBuilder expBuilder = new MultipartRequestExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(42L)); + expBuilder.setExpType(21L); + expBuilder.setExperimenterDataOfChoice(vendorData); + caseBuilder.setMultipartRequestExperimenter(expBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + 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(vendorData, out); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupDescTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupDescTest.java new file mode 100644 index 0000000000..08b46cd10b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupDescTest.java @@ -0,0 +1,77 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.serialization.factories.MultipartRequestInputFactory; +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.MultipartRequestInputBuilder; +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.multipart.request.group.desc._case.MultipartRequestGroupDescBuilder; + +/** + * @author michal.polkorab + * + */ +public class MultipartRequestGroupDescTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link MultipartRequestInputFactory} - GroupDesc case + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPGROUPDESC); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestGroupDescCaseBuilder caseBuilder = new MultipartRequestGroupDescCaseBuilder(); + MultipartRequestGroupDescBuilder descBuilder = new MultipartRequestGroupDescBuilder(); + descBuilder.setEmpty(true); + caseBuilder.setMultipartRequestGroupDesc(descBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(4); // skip padding + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupFeaturesTest.java new file mode 100644 index 0000000000..d619b0f3e2 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestGroupFeaturesTest.java @@ -0,0 +1,77 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.serialization.factories.MultipartRequestInputFactory; +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.MultipartRequestInputBuilder; +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.multipart.request.group.features._case.MultipartRequestGroupFeaturesBuilder; + +/** + * @author michal.polkorab + * + */ +public class MultipartRequestGroupFeaturesTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link MultipartRequestInputFactory} - GroupFeatures case + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPGROUPFEATURES); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestGroupFeaturesCaseBuilder caseBuilder = new MultipartRequestGroupFeaturesCaseBuilder(); + MultipartRequestGroupFeaturesBuilder featuresBuilder = new MultipartRequestGroupFeaturesBuilder(); + featuresBuilder.setEmpty(true); + caseBuilder.setMultipartRequestGroupFeatures(featuresBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(4); // skip padding + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestMeterFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestMeterFeaturesTest.java new file mode 100644 index 0000000000..6c7030e4dc --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestMeterFeaturesTest.java @@ -0,0 +1,77 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.serialization.factories.MultipartRequestInputFactory; +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.MultipartRequestInputBuilder; +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.multipart.request.meter.features._case.MultipartRequestMeterFeaturesBuilder; + +/** + * @author michal.polkorab + * + */ +public class MultipartRequestMeterFeaturesTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link MultipartRequestInputFactory} - MeterFeatures case + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPMETERFEATURES); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestMeterFeaturesCaseBuilder caseBuilder = new MultipartRequestMeterFeaturesCaseBuilder(); + MultipartRequestMeterFeaturesBuilder featuresBuilder = new MultipartRequestMeterFeaturesBuilder(); + featuresBuilder.setEmpty(true); + caseBuilder.setMultipartRequestMeterFeatures(featuresBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", 11, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(4); // skip padding + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestPortDescTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestPortDescTest.java new file mode 100644 index 0000000000..5adda0a86c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestPortDescTest.java @@ -0,0 +1,77 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.serialization.factories.MultipartRequestInputFactory; +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.MultipartRequestInputBuilder; +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.multipart.request.port.desc._case.MultipartRequestPortDescBuilder; + +/** + * @author michal.polkorab + * + */ +public class MultipartRequestPortDescTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link MultipartRequestInputFactory} - PortDesc case + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPPORTDESC); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestPortDescCaseBuilder caseBuilder = new MultipartRequestPortDescCaseBuilder(); + MultipartRequestPortDescBuilder descBuilder = new MultipartRequestPortDescBuilder(); + descBuilder.setEmpty(true); + caseBuilder.setMultipartRequestPortDesc(descBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", 13, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(4); // skip padding + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableFeaturesTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableFeaturesTest.java new file mode 100644 index 0000000000..48695a8cb3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableFeaturesTest.java @@ -0,0 +1,467 @@ +/* + * 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.serialization.factories.multipart; + +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.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.MessageTypeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactory; +import org.opendaylight.openflowjava.protocol.impl.serialization.factories.MultipartRequestInputFactoryTest; +import org.opendaylight.openflowjava.protocol.impl.util.BufferHelper; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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.ExperimenterIdTableFeatureProperty; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.ExperimenterIdTableFeaturePropertyBuilder; +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.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.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.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.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.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.MultipartRequestInputBuilder; +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 michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class MultipartRequestTableFeaturesTest { + + private static final byte PADDING_IN_MULTIPART_REQUEST_MESSAGE = + MultipartRequestInputFactoryTest.PADDING_IN_MULTIPART_REQUEST_MESSAGE; + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + @Mock SerializerRegistry mockRegistry; + @Mock OFSerializer serializer; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + Mockito.when(mockRegistry.getSerializer((MessageTypeKey)Matchers.any())) + .thenReturn(serializer); + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestTableFeaturesMessageFactory() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(12)); + builder.setFlags(new MultipartRequestFlags(true)); + MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder(); + List tableFeaturesList = new ArrayList<>(); + TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01})); + tableFeaturesBuilder.setMetadataWrite(new BigInteger(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"); + tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01})); + tableFeaturesBuilder.setMetadataWrite(new BigInteger(new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01})); + 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.setMultipartRequestTableFeatures(featuresBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 296); + Assert.assertEquals("Wrong type", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong length", 120, out.readUnsignedShort()); + Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte()); + out.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(out, 32)); + byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataMatch); + Assert.assertArrayEquals("Wrong metadata-match", + new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch); + byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataWrite); + Assert.assertArrayEquals("Wrong metadata-write", + new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite); + Assert.assertEquals("Wrong config", 8, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong next-registry-id", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong next-registry-id", 2, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong property type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 24, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong length", 160, out.readUnsignedShort()); + Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte()); + out.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(out, 32)); + metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataMatch); + Assert.assertArrayEquals("Wrong metadata-match", + new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch); + metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataWrite); + Assert.assertArrayEquals("Wrong metadata-write", + new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite); + Assert.assertEquals("Wrong config", 8, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 67, out.readUnsignedInt()); + Assert.assertEquals("Wrong property type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong property type", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedByte()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 10, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 13, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 14, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 20, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match field&mask", 18, out.readUnsignedByte()); + Assert.assertEquals("Wrong match length", 1, out.readUnsignedByte()); + out.skipBytes(4); + Assert.assertEquals("Wrong property type", 15, out.readUnsignedShort()); + Assert.assertEquals("Wrong property length", 4, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * @throws Exception + * Testing of {@link MultipartRequestInputFactory} for correct translation from POJO + */ + @Test + public void testMultipartRequestTableFeaturesExperimenter() throws Exception { + MultipartRequestInputFactory factory = new MultipartRequestInputFactory(); + factory.injectSerializerRegistry(mockRegistry); + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.forValue(12)); + builder.setFlags(new MultipartRequestFlags(true)); + MultipartRequestTableFeaturesCaseBuilder caseBuilder = new MultipartRequestTableFeaturesCaseBuilder(); + MultipartRequestTableFeaturesBuilder featuresBuilder = new MultipartRequestTableFeaturesBuilder(); + List tableFeaturesList = new ArrayList<>(); + TableFeaturesBuilder tableFeaturesBuilder = new TableFeaturesBuilder(); + tableFeaturesBuilder.setTableId((short) 8); + tableFeaturesBuilder.setName("AAAABBBBCCCCDDDDEEEEFFFFGGGG"); + tableFeaturesBuilder.setMetadataMatch(new BigInteger(new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01})); + tableFeaturesBuilder.setMetadataWrite(new BigInteger(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.OFPTFPTEXPERIMENTER); + ExperimenterIdTableFeaturePropertyBuilder expBuilder = new ExperimenterIdTableFeaturePropertyBuilder(); + expBuilder.setExperimenter(new ExperimenterId(42L)); + propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build()); + properties.add(propBuilder.build()); + propBuilder = new TableFeaturePropertiesBuilder(); + propBuilder.setType(TableFeaturesPropType.OFPTFPTEXPERIMENTERMISS); + expBuilder = new ExperimenterIdTableFeaturePropertyBuilder(); + expBuilder.setExperimenter(new ExperimenterId(43L)); + propBuilder.addAugmentation(ExperimenterIdTableFeatureProperty.class, expBuilder.build()); + properties.add(propBuilder.build()); + tableFeaturesBuilder.setTableFeatureProperties(properties); + tableFeaturesList.add(tableFeaturesBuilder.build()); + featuresBuilder.setTableFeatures(tableFeaturesList); + caseBuilder.setMultipartRequestTableFeatures(featuresBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + factory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 80); + Assert.assertEquals("Wrong type", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 1, out.readUnsignedShort()); + out.skipBytes(PADDING_IN_MULTIPART_REQUEST_MESSAGE); + Assert.assertEquals("Wrong length", 64, out.readUnsignedShort()); + Assert.assertEquals("Wrong registry-id", 8, out.readUnsignedByte()); + out.skipBytes(5); + Assert.assertEquals("Wrong name", "AAAABBBBCCCCDDDDEEEEFFFFGGGG", + ByteBufUtils.decodeNullTerminatedString(out, 32)); + byte[] metadataMatch = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataMatch); + Assert.assertArrayEquals("Wrong metadata-match", + new byte[] {0x00, 0x01, 0x02, 0x03, 0x01, 0x04, 0x08, 0x01}, metadataMatch); + byte[] metadataWrite = new byte[EncodeConstants.SIZE_OF_LONG_IN_BYTES]; + out.readBytes(metadataWrite); + Assert.assertArrayEquals("Wrong metadata-write", + new byte[] {0x00, 0x07, 0x01, 0x05, 0x01, 0x00, 0x03, 0x01}, metadataWrite); + Assert.assertEquals("Wrong config", 8, out.readUnsignedInt()); + Assert.assertEquals("Wrong max-entries", 65, out.readUnsignedInt()); + Mockito.verify(serializer, Mockito.times(2)).serialize(Matchers.any(TableFeatureProperties.class), + Matchers.any(ByteBuf.class)); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableTest.java new file mode 100644 index 0000000000..8fe0896762 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/MultipartRequestTableTest.java @@ -0,0 +1,77 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.serialization.factories.MultipartRequestInputFactory; +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.MultipartRequestInputBuilder; +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 michal.polkorab + * + */ +public class MultipartRequestTableTest { + + private SerializerRegistry registry; + private OFSerializer multipartFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + multipartFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link MultipartRequestInputFactory} - Table case + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF13_VERSION_ID); + builder.setType(MultipartType.OFPMPTABLE); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestTableCaseBuilder caseBuilder = new MultipartRequestTableCaseBuilder(); + MultipartRequestTableBuilder tablesBuilder = new MultipartRequestTableBuilder(); + tablesBuilder.setEmpty(true); + caseBuilder.setMultipartRequestTable(tablesBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + BufferHelper.checkHeaderV13(out, (byte) 18, 16); + Assert.assertEquals("Wrong type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(4); // skip padding + Assert.assertTrue("Unexpected data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java new file mode 100644 index 0000000000..4810663478 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestAggregateTest.java @@ -0,0 +1,102 @@ +/* + * 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.impl.serialization.factories.multipart; + +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.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.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; +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.MultipartRequestInputBuilder; +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 michal.polkorab + * + */ +public class OF10StatsRequestAggregateTest { + + private SerializerRegistry registry; + private OFSerializer statsFactory; + + /** + * Initializes serializer registry and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + statsFactory = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, MultipartRequestInput.class)); + } + + /** + * Tests {@link OF10StatsRequestInputFactory} for correct serialization + * @throws Exception + */ + @Test + public void test() throws Exception { + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPAGGREGATE); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestAggregateCaseBuilder caseBuilder = new MultipartRequestAggregateCaseBuilder(); + MultipartRequestAggregateBuilder aggBuilder = new MultipartRequestAggregateBuilder(); + 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); + aggBuilder.setMatchV10(matchBuilder.build()); + aggBuilder.setTableId((short) 5); + aggBuilder.setOutPort(42L); + caseBuilder.setMultipartRequestAggregate(aggBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + statsFactory.serialize(message, out); + + BufferHelper.checkHeaderV10(out, (byte) 16, 56); + Assert.assertEquals("Wrong type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong flags", 0, out.readUnsignedShort()); + out.skipBytes(40); // skip match check + Assert.assertEquals("Wrong table-id", 5, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong out port", 42, out.readUnsignedShort()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java new file mode 100644 index 0000000000..15430aa6db --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories/multipart/OF10StatsRequestExperimenterTest.java @@ -0,0 +1,78 @@ +/* + * 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.impl.serialization.factories.multipart; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; +import org.junit.Assert; +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.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.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.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; + +/** + * @author michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class OF10StatsRequestExperimenterTest { + + @Mock SerializerRegistry mockRegistry; + @Mock OFSerializer serializer; + @Mock + private ExperimenterDataOfChoice vendorData; + + /** + * Testing OF10StatsRequestInputFactory (Experimenter) for correct serialization + * @throws Exception + */ + @Test + public void testExperimenter() throws Exception { + Mockito.when(mockRegistry.getSerializer(Matchers.>any())) + .thenReturn(serializer); + OF10StatsRequestInputFactory multipartFactory = new OF10StatsRequestInputFactory(); + multipartFactory.injectSerializerRegistry(mockRegistry); + MultipartRequestInputBuilder builder = new MultipartRequestInputBuilder(); + BufferHelper.setupHeader(builder, EncodeConstants.OF10_VERSION_ID); + builder.setType(MultipartType.OFPMPEXPERIMENTER); + builder.setFlags(new MultipartRequestFlags(false)); + MultipartRequestExperimenterCaseBuilder caseBuilder = new MultipartRequestExperimenterCaseBuilder(); + MultipartRequestExperimenterBuilder expBuilder = new MultipartRequestExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(42L)); + expBuilder.setExpType(21L); + expBuilder.setExperimenterDataOfChoice(vendorData); + caseBuilder.setMultipartRequestExperimenter(expBuilder.build()); + builder.setMultipartRequestBody(caseBuilder.build()); + MultipartRequestInput message = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + multipartFactory.serialize(message, out); + + 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(vendorData, out); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializerTest.java new file mode 100644 index 0000000000..322d17868f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpOpSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.ArpOp; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpOpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.op._case.ArpOpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpOpSerializerTest { + + OxmArpOpSerializer serializer = new OxmArpOpSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareArpOpMatchEntry(1402); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 1402, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareArpOpHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ARP_OP, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareArpOpMatchEntry(int value) { + MatchEntryBuilder builder = prepareArpOpHeader(false); + ArpOpCaseBuilder casebuilder = new ArpOpCaseBuilder(); + ArpOpBuilder valueBuilder = new ArpOpBuilder(); + valueBuilder.setOpCode(value); + casebuilder.setArpOp(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareArpOpHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(ArpOp.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ARP_OP, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java new file mode 100644 index 0000000000..a3100d65b8 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpShaSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpShaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.sha._case.ArpShaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpShaSerializerTest { + + OxmArpShaSerializer serializer = new OxmArpShaSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "00:01:02:03:04:0A"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 10}, address); + byte[] tmp = new byte[6]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0, 10, 10}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ARP_SHA, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + ArpShaCaseBuilder casebuilder = new ArpShaCaseBuilder(); + ArpShaBuilder valueBuilder = new ArpShaBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0, 10, 10}); + } + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setArpSha(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(ArpSha.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ARP_SHA, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java new file mode 100644 index 0000000000..5e5fcc4b7c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpSpaSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpSpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.spa._case.ArpSpaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpSpaSerializerTest { + + OxmArpSpaSerializer serializer = new OxmArpSpaSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "10.0.0.1"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{10, 0, 0, 1}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "120.121.122.0"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{120, 121, 122, 0}, address); + byte[] tmp = new byte[4]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ARP_SPA, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_INT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + ArpSpaCaseBuilder casebuilder = new ArpSpaCaseBuilder(); + ArpSpaBuilder valueBuilder = new ArpSpaBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0}); + } + valueBuilder.setIpv4Address(new Ipv4Address(value)); + casebuilder.setArpSpa(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(ArpSpa.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ARP_SPA, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java new file mode 100644 index 0000000000..062178cee5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpThaSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpThaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tha._case.ArpThaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpThaSerializerTest { + + OxmArpThaSerializer serializer = new OxmArpThaSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "00:01:02:03:04:0A"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 10}, address); + byte[] tmp = new byte[6]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0, 10, 10}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ARP_THA, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + ArpThaCaseBuilder casebuilder = new ArpThaCaseBuilder(); + ArpThaBuilder valueBuilder = new ArpThaBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0, 10, 10}); + } + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setArpTha(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(ArpTha.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ARP_THA, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java new file mode 100644 index 0000000000..11b64a33f3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmArpTpaSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpTpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tpa._case.ArpTpaBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmArpTpaSerializerTest { + + OxmArpTpaSerializer serializer = new OxmArpTpaSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "10.0.0.1"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{10, 0, 0, 1}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "120.121.122.0"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{120, 121, 122, 0}, address); + byte[] tmp = new byte[4]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ARP_TPA, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_INT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + ArpTpaCaseBuilder casebuilder = new ArpTpaCaseBuilder(); + ArpTpaBuilder valueBuilder = new ArpTpaBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0}); + } + valueBuilder.setIpv4Address(new Ipv4Address(value)); + casebuilder.setArpTpa(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(ArpTpa.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ARP_TPA, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java new file mode 100644 index 0000000000..137c47aa14 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthDstSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthDstSerializerTest { + + OxmEthDstSerializer serializer = new OxmEthDstSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "00:01:02:03:04:0A"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 10}, address); + byte[] tmp = new byte[6]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0, 10, 10}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ETH_DST, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + EthDstCaseBuilder casebuilder = new EthDstCaseBuilder(); + EthDstBuilder valueBuilder = new EthDstBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0, 10, 10}); + } + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setEthDst(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(EthDst.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ETH_DST, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java new file mode 100644 index 0000000000..f171505a03 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthSrcSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthSrcSerializerTest { + + OxmEthSrcSerializer serializer = new OxmEthSrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "00:01:02:03:04:0A"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 10}, address); + byte[] tmp = new byte[6]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0, 10, 10}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ETH_SRC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + EthSrcCaseBuilder casebuilder = new EthSrcCaseBuilder(); + EthSrcBuilder valueBuilder = new EthSrcBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0, 10, 10}); + } + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setEthSrc(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(EthSrc.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ETH_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializerTest.java new file mode 100644 index 0000000000..9bb5c9243d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmEthTypeSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.common.types.rev130731.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmEthTypeSerializerTest { + + OxmEthTypeSerializer serializer = new OxmEthTypeSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareEthTypeMatchEntry(65535); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 65535, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareEthTypeHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ETH_TYPE, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareEthTypeMatchEntry(int type) { + MatchEntryBuilder builder = prepareEthTypeHeader(false); + EthTypeCaseBuilder casebuilder = new EthTypeCaseBuilder(); + EthTypeBuilder valueBuilder = new EthTypeBuilder(); + valueBuilder.setEthType(new EtherType(type)); + casebuilder.setEthType(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareEthTypeHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(EthType.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ETH_TYPE, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializerTest.java new file mode 100644 index 0000000000..6004776e4e --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4CodeSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.Icmpv4Code; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.code._case.Icmpv4CodeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4CodeSerializerTest { + + OxmIcmpv4CodeSerializer serializer = new OxmIcmpv4CodeSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareIcmpv4CodeMatchEntry((short) 200); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 200, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareIcmpv4CodeHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ICMPV4_CODE, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIcmpv4CodeMatchEntry(short value) { + MatchEntryBuilder builder = prepareIcmpv4CodeHeader(false); + Icmpv4CodeCaseBuilder casebuilder = new Icmpv4CodeCaseBuilder(); + Icmpv4CodeBuilder valueBuilder = new Icmpv4CodeBuilder(); + valueBuilder.setIcmpv4Code(value); + casebuilder.setIcmpv4Code(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIcmpv4CodeHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Icmpv4Code.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ICMPV4_CODE, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializerTest.java new file mode 100644 index 0000000000..d62c45681b --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv4TypeSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.Icmpv4Type; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4TypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.type._case.Icmpv4TypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv4TypeSerializerTest { + + OxmIcmpv4TypeSerializer serializer = new OxmIcmpv4TypeSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareIcmpv4TypeMatchEntry((short) 128); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 128, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareIcmpv4TypeHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ICMPV4_TYPE, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIcmpv4TypeMatchEntry(short value) { + MatchEntryBuilder builder = prepareIcmpv4TypeHeader(false); + Icmpv4TypeCaseBuilder casebuilder = new Icmpv4TypeCaseBuilder(); + Icmpv4TypeBuilder valueBuilder = new Icmpv4TypeBuilder(); + valueBuilder.setIcmpv4Type(value); + casebuilder.setIcmpv4Type(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIcmpv4TypeHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Icmpv4Type.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ICMPV4_TYPE, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializerTest.java new file mode 100644 index 0000000000..6706a9d2a6 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6CodeSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.Icmpv6Code; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.code._case.Icmpv6CodeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6CodeSerializerTest { + + OxmIcmpv6CodeSerializer serializer = new OxmIcmpv6CodeSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareIcmpv6CodeMatchEntry((short) 101); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 101, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareIcmpv6CodeHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ICMPV6_CODE, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIcmpv6CodeMatchEntry(short value) { + MatchEntryBuilder builder = prepareIcmpv6CodeHeader(false); + Icmpv6CodeCaseBuilder casebuilder = new Icmpv6CodeCaseBuilder(); + Icmpv6CodeBuilder valueBuilder = new Icmpv6CodeBuilder(); + valueBuilder.setIcmpv6Code(value); + casebuilder.setIcmpv6Code(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIcmpv6CodeHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Icmpv6Code.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ICMPV6_CODE, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializerTest.java new file mode 100644 index 0000000000..7f0ad5fb89 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIcmpv6TypeSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.Icmpv6Type; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6TypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.type._case.Icmpv6TypeBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIcmpv6TypeSerializerTest { + + OxmIcmpv6TypeSerializer serializer = new OxmIcmpv6TypeSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareIcmpv6TypeMatchEntry((short) 123); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 123, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareIcmpv6TypeHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.ICMPV6_TYPE, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIcmpv6TypeMatchEntry(short value) { + MatchEntryBuilder builder = prepareIcmpv6TypeHeader(false); + Icmpv6TypeCaseBuilder casebuilder = new Icmpv6TypeCaseBuilder(); + Icmpv6TypeBuilder valueBuilder = new Icmpv6TypeBuilder(); + valueBuilder.setIcmpv6Type(value); + casebuilder.setIcmpv6Type(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIcmpv6TypeHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Icmpv6Type.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.ICMPV6_TYPE, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java new file mode 100644 index 0000000000..b7cc4aef1d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpDscpSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpDscpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.dscp._case.IpDscpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpDscpSerializerTest { + + OxmIpDscpSerializer serializer = new OxmIpDscpSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareIpDscpMatchEntry((short) 58); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 58, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareIpDscpHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IP_DSCP, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIpDscpMatchEntry(short value) { + MatchEntryBuilder builder = prepareIpDscpHeader(false); + IpDscpCaseBuilder casebuilder = new IpDscpCaseBuilder(); + IpDscpBuilder dscpBuilder = new IpDscpBuilder(); + dscpBuilder.setDscp(new Dscp(value)); + casebuilder.setIpDscp(dscpBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIpDscpHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(IpDscp.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IP_DSCP, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializerTest.java new file mode 100644 index 0000000000..6edde4deee --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpProtoSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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.match.entries.grouping.MatchEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpProtoCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.proto._case.IpProtoBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpProtoSerializerTest { + + OxmIpProtoSerializer serializer = new OxmIpProtoSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry((short) 123); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 123, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IP_PROTO, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(short value) { + MatchEntryBuilder builder = prepareHeader(false); + IpProtoCaseBuilder casebuilder = new IpProtoCaseBuilder(); + IpProtoBuilder protoBuilder = new IpProtoBuilder(); + protoBuilder.setProtocolNumber(value); + casebuilder.setIpProto(protoBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(IpProto.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IP_PROTO, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java new file mode 100644 index 0000000000..233a546988 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4DstSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4DstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4DstSerializerTest { + + OxmIpv4DstSerializer serializer = new OxmIpv4DstSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "10.0.0.1"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{10, 0, 0, 1}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "120.121.122.0"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{120, 121, 122, 0}, address); + byte[] tmp = new byte[4]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IPV4_DST, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_INT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + Ipv4DstCaseBuilder casebuilder = new Ipv4DstCaseBuilder(); + Ipv4DstBuilder valueBuilder = new Ipv4DstBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0}); + } + valueBuilder.setIpv4Address(new Ipv4Address(value)); + casebuilder.setIpv4Dst(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv4Dst.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV4_DST, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java new file mode 100644 index 0000000000..286cbab65f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv4SrcSerializerTest.java @@ -0,0 +1,157 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4SrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv4SrcSerializerTest { + + OxmIpv4SrcSerializer serializer = new OxmIpv4SrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "10.0.0.1"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{10, 0, 0, 1}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, "120.121.122.0"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[4]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{120, 121, 122, 0}, address); + byte[] tmp = new byte[4]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IPV4_SRC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_INT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + Ipv4SrcCaseBuilder casebuilder = new Ipv4SrcCaseBuilder(); + Ipv4SrcBuilder valueBuilder = new Ipv4SrcBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15, 0, 0}); + } + valueBuilder.setIpv4Address(new Ipv4Address(value)); + casebuilder.setIpv4Src(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv4Src.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV4_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializerTest.java new file mode 100644 index 0000000000..b775e516b7 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6ExtHdrSerializerTest.java @@ -0,0 +1,154 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6ExthdrCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.exthdr._case.Ipv6ExthdrBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6ExtHdrSerializerTest { + + OxmIpv6ExtHdrSerializer serializer = new OxmIpv6ExtHdrSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareIpv6ExtHdrMatchEntry(false, + new Ipv6ExthdrFlags(true, false, true, false, true, false, true, false, true)); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 358, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareIpv6ExtHdrMatchEntry(true, + new Ipv6ExthdrFlags(false, true, false, true, false, true, false, true, false)); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + assertEquals("Wrong value", 153, buffer.readUnsignedShort()); + byte[] tmp = new byte[2]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{0, 15}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareIpv6ExtHdrHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareIpv6ExtHdrHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IPV6_EXTHDR, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareIpv6ExtHdrMatchEntry(boolean hasMask, Ipv6ExthdrFlags flags) { + MatchEntryBuilder builder = prepareIpv6ExtHdrHeader(hasMask); + Ipv6ExthdrCaseBuilder casebuilder = new Ipv6ExthdrCaseBuilder(); + Ipv6ExthdrBuilder valueBuilder = new Ipv6ExthdrBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{0, 15}); + } + valueBuilder.setPseudoField(flags); + casebuilder.setIpv6Exthdr(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareIpv6ExtHdrHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv6Exthdr.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV6_EXTHDR, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java new file mode 100644 index 0000000000..5a1b6ca039 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdSllSerializerTest.java @@ -0,0 +1,115 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdSllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.sll._case.Ipv6NdSllBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdSllSerializerTest { + + OxmIpv6NdSllSerializer serializer = new OxmIpv6NdSllSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry("00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IPV6_ND_SLL, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(String value) { + MatchEntryBuilder builder = prepareHeader(false); + Ipv6NdSllCaseBuilder casebuilder = new Ipv6NdSllCaseBuilder(); + Ipv6NdSllBuilder valueBuilder = new Ipv6NdSllBuilder(); + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setIpv6NdSll(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv6NdSll.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV6_ND_SLL, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java new file mode 100644 index 0000000000..8d6d95ccfe --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6NdTllSerializerTest.java @@ -0,0 +1,115 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.tll._case.Ipv6NdTllBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6NdTllSerializerTest { + + OxmIpv6NdTllSerializer serializer = new OxmIpv6NdTllSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry("00:01:02:03:04:05"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[6]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.IPV6_ND_TLL, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.MAC_ADDRESS_LENGTH, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(String value) { + MatchEntryBuilder builder = prepareHeader(false); + Ipv6NdTllCaseBuilder casebuilder = new Ipv6NdTllCaseBuilder(); + Ipv6NdTllBuilder valueBuilder = new Ipv6NdTllBuilder(); + valueBuilder.setMacAddress(new MacAddress(value)); + casebuilder.setIpv6NdTll(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv6NdTll.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV6_ND_TLL, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.MAC_ADDRESS_LENGTH, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java new file mode 100644 index 0000000000..386d1cd451 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmIpv6SrcSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6SrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmIpv6SrcSerializerTest { + + OxmIpv6SrcSerializer serializer = new OxmIpv6SrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, "aaaa:bbbb:1111:2222::"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + Assert.assertEquals("Wrong ipv6 address", 43690, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 48059, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 4369, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 8738, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(false, "::aaaa:bbbb:1111:2222"); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 43690, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 48059, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 4369, buffer.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 8738, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, String value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + Ipv6SrcCaseBuilder caseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder srcBuilder = new Ipv6SrcBuilder(); + srcBuilder.setIpv6Address(new Ipv6Address(value)); + if (hasMask) { + srcBuilder.setMask(new byte[]{15, 15, 0, 0}); + } + caseBuilder.setIpv6Src(srcBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Ipv6Src.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.IPV6_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES, + buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_IPV6_ADDRESS_IN_BYTES, buffer.readUnsignedByte()); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializerTest.java new file mode 100644 index 0000000000..3540829a51 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMetadataSerializerTest.java @@ -0,0 +1,156 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.opendaylight.openflow.oxm.rev150225.Metadata; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.metadata._case.MetadataBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMetadataSerializerTest { + + OxmMetadataSerializer serializer = new OxmMetadataSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, new byte[]{0, 1, 2, 3, 4, 5, 6, 7}); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[8]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5, 6, 7}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, new byte[]{8, 9, 10, 11, 12, 13, 14, 15}); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[8]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{8, 9, 10, 11, 12, 13, 14, 15}, address); + byte[] tmp = new byte[8]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{30, 30, 25, 25, 15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.METADATA, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, byte[] value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + MetadataCaseBuilder casebuilder = new MetadataCaseBuilder(); + MetadataBuilder valueBuilder = new MetadataBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{30, 30, 25, 25, 15, 15, 0, 0}); + } + valueBuilder.setMetadata(value); + casebuilder.setMetadata(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(Metadata.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.METADATA, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializerTest.java new file mode 100644 index 0000000000..da0390e496 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsBosSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.MplsBos; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsBosCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.bos._case.MplsBosBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsBosSerializerTest { + + OxmMplsBosSerializer serializer = new OxmMplsBosSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMplsBosMatchEntry(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 1, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareMplsBosHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.MPLS_BOS, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMplsBosMatchEntry(boolean bos) { + MatchEntryBuilder builder = prepareMplsBosHeader(false); + MplsBosCaseBuilder casebuilder = new MplsBosCaseBuilder(); + MplsBosBuilder valueBuilder = new MplsBosBuilder(); + valueBuilder.setBos(bos); + casebuilder.setMplsBos(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareMplsBosHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(MplsBos.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.MPLS_BOS, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializerTest.java new file mode 100644 index 0000000000..4557be2fc5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsLabelSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.MplsLabel; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsLabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.label._case.MplsLabelBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsLabelSerializerTest { + + OxmMplsLabelSerializer serializer = new OxmMplsLabelSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMplsLabelMatchEntry(168535); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 168535, buffer.readUnsignedInt()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareMplsLabelHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.MPLS_LABEL, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_INT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMplsLabelMatchEntry(long label) { + MatchEntryBuilder builder = prepareMplsLabelHeader(false); + MplsLabelCaseBuilder casebuilder = new MplsLabelCaseBuilder(); + MplsLabelBuilder valueBuilder = new MplsLabelBuilder(); + valueBuilder.setMplsLabel(label); + casebuilder.setMplsLabel(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareMplsLabelHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(MplsLabel.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.MPLS_LABEL, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializerTest.java new file mode 100644 index 0000000000..273f7a06f5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmMplsTcSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.MplsTc; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsTcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.tc._case.MplsTcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmMplsTcSerializerTest { + + OxmMplsTcSerializer serializer = new OxmMplsTcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMplsTcMatchEntry((short) 16); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 16, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareMplsTcHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.MPLS_TC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMplsTcMatchEntry(short value) { + MatchEntryBuilder builder = prepareMplsTcHeader(false); + MplsTcCaseBuilder casebuilder = new MplsTcCaseBuilder(); + MplsTcBuilder valueBuilder = new MplsTcBuilder(); + valueBuilder.setTc(value); + casebuilder.setMplsTc(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareMplsTcHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(MplsTc.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.MPLS_TC, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializerTest.java new file mode 100644 index 0000000000..3d8db87f6d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmPbbIsidSerializerTest.java @@ -0,0 +1,151 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.PbbIsid; +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.PbbIsidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.pbb.isid._case.PbbIsidBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmPbbIsidSerializerTest { + + OxmPbbIsidSerializer serializer = new OxmPbbIsidSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = preparePbbIsidMatchEntry(false, 12345); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 12345, buffer.readUnsignedMedium()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = preparePbbIsidMatchEntry(true, 6789); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + assertEquals("Wrong value", 6789, buffer.readUnsignedMedium()); + byte[] tmp = new byte[3]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{0, 15, 10}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = preparePbbIsidHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = preparePbbIsidHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.PBB_ISID, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_3_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder preparePbbIsidMatchEntry(boolean hasMask, long value) { + MatchEntryBuilder builder = preparePbbIsidHeader(hasMask); + PbbIsidCaseBuilder casebuilder = new PbbIsidCaseBuilder(); + PbbIsidBuilder valueBuilder = new PbbIsidBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{0, 15, 10}); + } + valueBuilder.setIsid(value); + casebuilder.setPbbIsid(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder preparePbbIsidHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(PbbIsid.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.PBB_ISID, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.SIZE_OF_3_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_3_BYTES, buffer.readUnsignedByte()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java new file mode 100644 index 0000000000..b3a1fa900f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpDstSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.dst._case.SctpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpDstSerializerTest { + + OxmSctpDstSerializer serializer = new OxmSctpDstSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(4096); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 4096, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.SCTP_DST, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + SctpDstCaseBuilder casebuilder = new SctpDstCaseBuilder(); + SctpDstBuilder valueBuilder = new SctpDstBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setSctpDst(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(SctpDst.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.SCTP_DST, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java new file mode 100644 index 0000000000..3c6eb1fba1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmSctpSrcSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.src._case.SctpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmSctpSrcSerializerTest { + + OxmSctpSrcSerializer serializer = new OxmSctpSrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(4096); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 4096, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.SCTP_SRC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + SctpSrcCaseBuilder casebuilder = new SctpSrcCaseBuilder(); + SctpSrcBuilder valueBuilder = new SctpSrcBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setSctpSrc(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(SctpSrc.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.SCTP_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java new file mode 100644 index 0000000000..c603394644 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpDstSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.dst._case.TcpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpDstSerializerTest { + + OxmTcpDstSerializer serializer = new OxmTcpDstSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(4096); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 4096, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.TCP_DST, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + TcpDstCaseBuilder casebuilder = new TcpDstCaseBuilder(); + TcpDstBuilder valueBuilder = new TcpDstBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setTcpDst(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(TcpDst.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.TCP_DST, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java new file mode 100644 index 0000000000..a0be555f29 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTcpSrcSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.src._case.TcpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTcpSrcSerializerTest { + + OxmTcpSrcSerializer serializer = new OxmTcpSrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(512); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 512, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.TCP_SRC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + TcpSrcCaseBuilder casebuilder = new TcpSrcCaseBuilder(); + TcpSrcBuilder valueBuilder = new TcpSrcBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setTcpSrc(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(TcpSrc.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.TCP_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializerTest.java new file mode 100644 index 0000000000..193bf057fa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmTunnelIdSerializerTest.java @@ -0,0 +1,156 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TunnelId; +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.TunnelIdCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tunnel.id._case.TunnelIdBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmTunnelIdSerializerTest { + + OxmTunnelIdSerializer serializer = new OxmTunnelIdSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutMask() { + MatchEntryBuilder builder = prepareMatchEntry(false, new byte[]{0, 1, 2, 3, 4, 5, 6, 7}); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + byte[] address = new byte[8]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{0, 1, 2, 3, 4, 5, 6, 7}, address); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithMask() { + MatchEntryBuilder builder = prepareMatchEntry(true, new byte[]{8, 9, 10, 11, 12, 13, 14, 15}); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + + byte[] address = new byte[8]; + buffer.readBytes(address); + Assert.assertArrayEquals("Wrong address", new byte[]{8, 9, 10, 11, 12, 13, 14, 15}, address); + byte[] tmp = new byte[8]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{30, 30, 25, 25, 15, 15, 0, 0}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.TUNNEL_ID, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(boolean hasMask, byte[] value) { + MatchEntryBuilder builder = prepareHeader(hasMask); + TunnelIdCaseBuilder casebuilder = new TunnelIdCaseBuilder(); + TunnelIdBuilder valueBuilder = new TunnelIdBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{30, 30, 25, 25, 15, 15, 0, 0}); + } + valueBuilder.setTunnelId(value); + casebuilder.setTunnelId(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(TunnelId.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.TUNNEL_ID, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", 2 * EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_LONG_IN_BYTES, buffer.readUnsignedByte()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java new file mode 100644 index 0000000000..10166595af --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpDstSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.dst._case.UdpDstBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpDstSerializerTest { + + OxmUdpDstSerializer serializer = new OxmUdpDstSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(2048); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 2048, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.UDP_DST, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + UdpDstCaseBuilder casebuilder = new UdpDstCaseBuilder(); + UdpDstBuilder valueBuilder = new UdpDstBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setUdpDst(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(UdpDst.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.UDP_DST, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java new file mode 100644 index 0000000000..db7a60e06d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmUdpSrcSerializerTest.java @@ -0,0 +1,112 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.src._case.UdpSrcBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmUdpSrcSerializerTest { + + OxmUdpSrcSerializer serializer = new OxmUdpSrcSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareMatchEntry(1024); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 1024, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.UDP_SRC, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareMatchEntry(int value) { + MatchEntryBuilder builder = prepareHeader(false); + UdpSrcCaseBuilder casebuilder = new UdpSrcCaseBuilder(); + UdpSrcBuilder valueBuilder = new UdpSrcBuilder(); + valueBuilder.setPort(new PortNumber(value)); + casebuilder.setUdpSrc(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(UdpSrc.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.UDP_SRC, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializerTest.java new file mode 100644 index 0000000000..ecadb71cc6 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanPcpSerializerTest.java @@ -0,0 +1,111 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +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.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanPcp; +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.VlanPcpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.pcp._case.VlanPcpBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanPcpSerializerTest { + + OxmVlanPcpSerializer serializer = new OxmVlanPcpSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerialize() { + MatchEntryBuilder builder = prepareVlanPcpMatchEntry((short) 42); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 42, buffer.readUnsignedByte()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeader() { + MatchEntryBuilder builder = prepareVlanPcpHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.VLAN_PCP, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_BYTE_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareVlanPcpMatchEntry(short value) { + MatchEntryBuilder builder = prepareVlanPcpHeader(false); + VlanPcpCaseBuilder casebuilder = new VlanPcpCaseBuilder(); + VlanPcpBuilder valueBuilder = new VlanPcpBuilder(); + valueBuilder.setVlanPcp(value); + casebuilder.setVlanPcp(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareVlanPcpHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(VlanPcp.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.VLAN_PCP, fieldAndMask >>> 1); + 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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializerTest.java new file mode 100644 index 0000000000..effaccdbd3 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/serialization/match/OxmVlanVidSerializerTest.java @@ -0,0 +1,152 @@ +/* + * 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.impl.serialization.match; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +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.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; +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.VlanVidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder; + +/** + * @author michal.polkorab + * + */ +public class OxmVlanVidSerializerTest { + + OxmVlanVidSerializer serializer = new OxmVlanVidSerializer(); + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithCfiBitSet() { + MatchEntryBuilder builder = prepareVlanVidMatchEntry(false, true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, false); + assertEquals("Wrong value", 4596, buffer.readUnsignedShort()); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct serialization + */ + @Test + public void testSerializeWithoutCfiBitSet() { + MatchEntryBuilder builder = prepareVlanVidMatchEntry(true, false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serialize(builder.build(), buffer); + + checkHeader(buffer, true); + assertEquals("Wrong value", 500, buffer.readUnsignedShort()); + byte[] tmp = new byte[2]; + buffer.readBytes(tmp); + Assert.assertArrayEquals("Wrong mask", new byte[]{15, 15}, tmp); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithoutMask() { + MatchEntryBuilder builder = prepareVlanVidHeader(false); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, false); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct header serialization + */ + @Test + public void testSerializeHeaderWithMask() { + MatchEntryBuilder builder = prepareVlanVidHeader(true); + + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + serializer.serializeHeader(builder.build(), buffer); + + checkHeader(buffer, true); + assertTrue("Unexpected data", buffer.readableBytes() == 0); + } + + /** + * Test correct oxm-class return value + */ + @Test + public void testGetOxmClassCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, serializer.getOxmClassCode()); + } + + /** + * Test correct oxm-field return value + */ + @Test + public void getOxmFieldCode() { + assertEquals("Wrong oxm-class", OxmMatchConstants.VLAN_VID, serializer.getOxmFieldCode()); + } + + /** + * Test correct value length return value + */ + @Test + public void testGetValueLength() { + assertEquals("Wrong value length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, serializer.getValueLength()); + } + + private static MatchEntryBuilder prepareVlanVidMatchEntry(boolean hasMask, boolean cfiBit) { + MatchEntryBuilder builder = prepareVlanVidHeader(hasMask); + VlanVidCaseBuilder casebuilder = new VlanVidCaseBuilder(); + VlanVidBuilder valueBuilder = new VlanVidBuilder(); + if (hasMask) { + valueBuilder.setMask(new byte[]{15, 15}); + } + valueBuilder.setVlanVid(500); + valueBuilder.setCfiBit(cfiBit); + casebuilder.setVlanVid(valueBuilder.build()); + builder.setMatchEntryValue(casebuilder.build()); + return builder; + } + + private static MatchEntryBuilder prepareVlanVidHeader(boolean hasMask) { + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(VlanVid.class); + builder.setHasMask(hasMask); + return builder; + } + + private static void checkHeader(ByteBuf buffer, boolean hasMask) { + assertEquals("Wrong oxm-class", OxmMatchConstants.OPENFLOW_BASIC_CLASS, buffer.readUnsignedShort()); + short fieldAndMask = buffer.readUnsignedByte(); + assertEquals("Wrong oxm-field", OxmMatchConstants.VLAN_VID, fieldAndMask >>> 1); + assertEquals("Wrong hasMask", hasMask, (fieldAndMask & 1) != 0); + if (hasMask) { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_INT_IN_BYTES, buffer.readUnsignedByte()); + } else { + assertEquals("Wrong length", EncodeConstants.SIZE_OF_SHORT_IN_BYTES, buffer.readUnsignedByte()); + } + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java new file mode 100644 index 0000000000..b9d2b0f5ee --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ActionsDeserializerTest.java @@ -0,0 +1,166 @@ +/* + * 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.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.protocol.impl.deserialization.action.AbstractActionDeserializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlOutCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.GroupCase; +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.PopMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PopVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushMplsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushPbbCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetFieldCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetNwTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetQueueCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; +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.entry.value.grouping.match.entry.value.InPhyPortCase; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class ActionsDeserializerTest { + + private static final Logger LOG = LoggerFactory + .getLogger(ActionsDeserializerTest.class); + private DeserializerRegistry registry; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + registry = new DeserializerRegistryImpl(); + registry.init(); + } + + /** + * Testing actions deserialization + */ + @Test + public void test() { + ByteBuf message = BufferHelper.buildBuffer("00 00 00 10 00 00 00 01 00 02 00 00 00 00 00 00 " + + "00 0B 00 08 00 00 00 00 " + + "00 0C 00 08 00 00 00 00 " + + "00 0F 00 08 03 00 00 00 " + + "00 10 00 08 00 00 00 00 " + + "00 11 00 08 00 04 00 00 " + + "00 12 00 08 00 00 00 00 " + + "00 13 00 08 00 05 00 00 " + + "00 14 00 08 00 06 00 00 " + + "00 15 00 08 00 00 00 07 " + + "00 16 00 08 00 00 00 08 " + + "00 17 00 08 09 00 00 00 " + + "00 18 00 08 00 00 00 00 " + + "00 19 00 10 80 00 02 04 00 00 00 0B 00 00 00 00 " + + "00 1A 00 08 00 0A 00 00 " + + "00 1B 00 08 00 00 00 00"); + + message.skipBytes(4); // skip XID + LOG.info("bytes: {}", message.readableBytes()); + + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + message.readableBytes(), message, keyMaker, registry); + Assert.assertTrue("Wrong action type", actions.get(0).getActionChoice() instanceof OutputActionCase); + Assert.assertEquals("Wrong action port", 1, + ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction() + .getPort().getValue().intValue()); + Assert.assertEquals("Wrong action max-length", 2, + ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction() + .getMaxLength().intValue()); + Assert.assertTrue("Wrong action type", actions.get(1).getActionChoice() instanceof CopyTtlOutCase); + Assert.assertTrue("Wrong action type", actions.get(2).getActionChoice() instanceof CopyTtlInCase); + Assert.assertTrue("Wrong action type", actions.get(3).getActionChoice() instanceof SetMplsTtlCase); + Assert.assertEquals("Wrong action value", 3, + ((SetMplsTtlCase) actions.get(3).getActionChoice()).getSetMplsTtlAction() + .getMplsTtl().shortValue()); + Assert.assertTrue("Wrong action type", actions.get(4).getActionChoice() instanceof DecMplsTtlCase); + Assert.assertTrue("Wrong action type", actions.get(5).getActionChoice() instanceof PushVlanCase); + Assert.assertEquals("Wrong action value", 4, + ((PushVlanCase) actions.get(5).getActionChoice()).getPushVlanAction() + .getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong action type", actions.get(6).getActionChoice() instanceof PopVlanCase); + Assert.assertTrue("Wrong action type", actions.get(7).getActionChoice() instanceof PushMplsCase); + Assert.assertEquals("Wrong action value", 5, + ((PushMplsCase) actions.get(7).getActionChoice()).getPushMplsAction() + .getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong action type", actions.get(8).getActionChoice() instanceof PopMplsCase); + Assert.assertEquals("Wrong action value", 6, + ((PopMplsCase) actions.get(8).getActionChoice()).getPopMplsAction() + .getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong action type", actions.get(9).getActionChoice() instanceof SetQueueCase); + Assert.assertEquals("Wrong action value", 7, + ((SetQueueCase) actions.get(9).getActionChoice()).getSetQueueAction() + .getQueueId().intValue()); + Assert.assertTrue("Wrong action type", actions.get(10).getActionChoice() instanceof GroupCase); + Assert.assertEquals("Wrong action value", 8, + ((GroupCase) actions.get(10).getActionChoice()).getGroupAction().getGroupId().intValue()); + Assert.assertTrue("Wrong action type", actions.get(11).getActionChoice() instanceof SetNwTtlCase); + Assert.assertEquals("Wrong action value", 9, + ((SetNwTtlCase) actions.get(11).getActionChoice()).getSetNwTtlAction().getNwTtl().intValue()); + Assert.assertTrue("Wrong action type", actions.get(12).getActionChoice() instanceof DecNwTtlCase); + Assert.assertTrue("Wrong action type", actions.get(13).getActionChoice() instanceof SetFieldCase); + List entries = ((SetFieldCase) actions.get(13).getActionChoice()) + .getSetFieldAction().getMatchEntry(); + Assert.assertEquals("Wrong number of fields", 1, entries.size()); + Assert.assertEquals("Wrong match entry class", "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow." + + "oxm.rev150225.OpenflowBasicClass", entries.get(0).getOxmClass().getName()); + Assert.assertEquals("Wrong match entry field", "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow." + + "oxm.rev150225.InPhyPort", entries.get(0).getOxmMatchField().getName()); + Assert.assertEquals("Wrong match entry mask", false, entries.get(0).isHasMask()); + Assert.assertEquals("Wrong match entry value", 11, + ((InPhyPortCase) entries.get(0).getMatchEntryValue()).getInPhyPort().getPortNumber() + .getValue().intValue()); + Assert.assertTrue("Wrong action type", actions.get(14).getActionChoice() instanceof PushPbbCase); + Assert.assertEquals("Wrong action value", 10, + ((PushPbbCase) actions.get(14).getActionChoice()).getPushPbbAction() + .getEthertype().getValue().intValue()); + Assert.assertTrue("Wrong action type", actions.get(15).getActionChoice() instanceof PopPbbCase); + Assert.assertTrue("Unread data in message", message.readableBytes() == 0); + } + + /** + * Tests {@link AbstractActionDeserializer#deserializeHeader(ByteBuf)} + */ + @Test + public void testDeserializeHeader() { + ByteBuf message = BufferHelper.buildBuffer("00 00 00 04 00 19 00 04"); + + message.skipBytes(4); // skip XID + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List actions = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + message.readableBytes(), message, keyMaker, registry); + + Assert.assertTrue("Wrong action type", actions.get(0).getActionChoice() instanceof OutputActionCase); + Assert.assertNull("Wrong action port", ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction()); + Assert.assertNull("Wrong action max-length", ((OutputActionCase) actions.get(0).getActionChoice()).getOutputAction()); + Assert.assertTrue("Wrong action type", actions.get(1).getActionChoice() instanceof SetFieldCase); + Assert.assertNull("Wrong action oxm field", ((SetFieldCase) actions.get(1).getActionChoice()).getSetFieldAction()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java new file mode 100644 index 0000000000..29d0da2f94 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/BufferHelper.java @@ -0,0 +1,147 @@ +/* + * 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.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.UnpooledByteBufAllocator; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.junit.Assert; +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.protocol.rev130731.OfHeader; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author michal.polkorab + * + */ +public abstract class BufferHelper { + + /** + * + */ + public static final Long DEFAULT_XID = 0x01020304L; + private static final byte[] XID = new byte[] { 0x01, 0x02, 0x03, 0x04 }; + + /** + * @param payload + * @return ByteBuf filled with OpenFlow protocol message without first 4 + * bytes + */ + public static ByteBuf buildBuffer(byte[] payload) { + ByteBuf bb = UnpooledByteBufAllocator.DEFAULT.buffer(); + bb.writeBytes(XID); + bb.writeBytes(payload); + return bb; + } + + /** + * @param payload String in hex format + * @return ByteBuf filled with OpenFlow protocol message without first 4 + * bytes + */ + public static ByteBuf buildBuffer(String payload) { + return buildBuffer(ByteBufUtils.hexStringToBytes(payload)); + } + + /** + * @return ByteBuf filled with OpenFlow protocol header message without first 4 + * bytes + */ + public static ByteBuf buildBuffer() { + ByteBuf bb = UnpooledByteBufAllocator.DEFAULT.buffer(); + bb.writeBytes(XID); + bb.writeBytes(new byte[0]); + return bb; + } + + /** + * Use version 1.3 for encoded message + * @param input ByteBuf to be checked for correct OpenFlow Protocol header + * @param msgType type of received message + * @param length expected length of message in header + */ + public static void checkHeaderV13(ByteBuf input, byte msgType, int length) { + checkHeader(input, msgType, length, (short) EncodeConstants.OF13_VERSION_ID); + } + + /** + * Use version 1.0 for encoded message + * @param input ByteBuf to be checked for correct OpenFlow Protocol header + * @param msgType type of received message + * @param length expected length of message in header + */ + public static void checkHeaderV10(ByteBuf input, byte msgType, int length) { + checkHeader(input, msgType, length, (short) EncodeConstants.OF10_VERSION_ID); + } + + private static void checkHeader(ByteBuf input, byte msgType, int length, Short version) { + Assert.assertEquals("Wrong version", version, Short.valueOf(input.readByte())); + Assert.assertEquals("Wrong type", msgType, input.readByte()); + Assert.assertEquals("Wrong length", length, input.readUnsignedShort()); + Assert.assertEquals("Wrong Xid", DEFAULT_XID, Long.valueOf(input.readUnsignedInt())); + } + + + /** + * @param ofHeader OpenFlow protocol header + */ + public static void checkHeaderV13(OfHeader ofHeader) { + checkHeader(ofHeader, (short) EncodeConstants.OF13_VERSION_ID); + } + + /** + * @param ofHeader OpenFlow protocol header + */ + public static void checkHeaderV10(OfHeader ofHeader) { + checkHeader(ofHeader, (short) EncodeConstants.OF10_VERSION_ID); + } + + /** + * 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()); + } + + /** + * @param builder + * @param version wire protocol number used + * @throws NoSuchMethodException + * @throws SecurityException + * @throws IllegalAccessException + * @throws IllegalArgumentException + * @throws InvocationTargetException + */ + public static void setupHeader(Object builder, int version) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = builder.getClass().getMethod("setVersion", Short.class); + m.invoke(builder, (short) version); + Method m2 = builder.getClass().getMethod("setXid", Long.class); + m2.invoke(builder, BufferHelper.DEFAULT_XID); + } + + /** + * Decode message + * @param decoder decoder instance + * @param bb data input buffer + * @return message decoded pojo + */ + public static E deserialize(OFDeserializer decoder, ByteBuf bb) { + return decoder.deserialize(bb); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactoryTest.java new file mode 100644 index 0000000000..024dae0de1 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/CodeKeyMakerFactoryTest.java @@ -0,0 +1,135 @@ +/* + * 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.impl.util; + +import io.netty.buffer.ByteBuf; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.ActionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.InstructionDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; + +/** + * @author michal.polkorab + * + */ +public class CodeKeyMakerFactoryTest { + + /** + * Tests {@link CodeKeyMakerFactory#createMatchEntriesKeyMaker(short)} + */ + @Test + public void testMatchEntriesKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("80 00 00 04 00 00 00 01"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + Assert.assertEquals("Wrong key", new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 32768, 0), codeKey); + Assert.assertEquals("Buffer index modified", 8, buffer.readableBytes()); + } + + /** + * Tests {@link CodeKeyMakerFactory#createMatchEntriesKeyMaker(short)} + */ + @Test + public void testExperimenterMatchEntriesKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("FF FF 00 04 00 00 00 01"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + MatchEntryDeserializerKey comparationKey = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, 65535, 0); + comparationKey.setExperimenterId(1L); + Assert.assertEquals("Wrong key", comparationKey, codeKey); + Assert.assertEquals("Buffer index modified", 8, buffer.readableBytes()); + } + + /** + * Tests {@link CodeKeyMakerFactory#createActionsKeyMaker(short)} + */ + @Test + public void testActionKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("00 00 00 10 00 00 00 01 00 02 00 00 00 00 00 00"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + Assert.assertEquals("Wrong key", new ActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0, null), codeKey); + Assert.assertEquals("Buffer index modified", 16, buffer.readableBytes()); + } + + /** + * Tests {@link CodeKeyMakerFactory#createActionsKeyMaker(short)} + */ + @Test + public void testExperimenterActionKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("FF FF 00 08 00 00 00 01"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + Assert.assertEquals("Wrong key", new ActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 65535, 1L), codeKey); + Assert.assertEquals("Buffer index modified", 8, buffer.readableBytes()); + } + + /** + * Tests {@link CodeKeyMakerFactory#createInstructionsKeyMaker(short)} + */ + @Test + public void testInstructionKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("00 00 00 08"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + Assert.assertEquals("Wrong key", new InstructionDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0, null), codeKey); + Assert.assertEquals("Buffer index modified", 4, buffer.readableBytes()); + } + + /** + * Tests {@link CodeKeyMakerFactory#createInstructionsKeyMaker(short)} + */ + @Test + public void testExperimenterInstructionKeyMaker() { + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null key maker", keyMaker); + + ByteBuf buffer = BufferHelper.buildBuffer("FF FF 00 08 00 00 00 01"); + buffer.skipBytes(4); // skip XID + MessageCodeKey codeKey = keyMaker.make(buffer); + + Assert.assertNotNull("Null key", codeKey); + Assert.assertEquals("Wrong key", new InstructionDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 65535, 1L), codeKey); + Assert.assertEquals("Buffer index modified", 8, buffer.readableBytes()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/DefaultDeserializerFactoryTest.java new file mode 100644 index 0000000000..b5eead74b0 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsDeserializerTest.java new file mode 100644 index 0000000000..60f187618d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/InstructionsDeserializerTest.java @@ -0,0 +1,110 @@ +/* + * 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.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.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.GroupCase; +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.SetMplsTtlCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetQueueCase; +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.instruction.grouping.instruction.choice.ApplyActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.ClearActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.GotoTableCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.MeterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteActionsCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instruction.grouping.instruction.choice.WriteMetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.instruction.rev130731.instructions.grouping.Instruction; + +/** + * @author michal.polkorab + * + */ +public class InstructionsDeserializerTest { + + + private DeserializerRegistry registry; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + registry = new DeserializerRegistryImpl(); + registry.init(); + } + + /** + * Testing instructions translation + */ + @Test + public void test() { + ByteBuf message = BufferHelper.buildBuffer("00 01 00 08 0A 00 00 00 00 02 00 18 00 00 00 00 " + + "00 00 00 00 00 00 00 20 00 00 00 00 00 00 00 30 00 05 00 08 00 00 00 00 00 06 00 08 " + + "00 01 02 03 00 03 00 20 00 00 00 00 00 00 00 10 00 00 00 25 00 35 00 00 00 00 00 00 " + + "00 16 00 08 00 00 00 50 00 04 00 18 00 00 00 00 00 15 00 08 00 00 00 25 00 0F 00 08 05 00 00 00"); + + message.skipBytes(4); // skip XID + + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createInstructionsKeyMaker(EncodeConstants.OF13_VERSION_ID); + List instructions = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + message.readableBytes(), message, keyMaker, registry); + Instruction i1 = instructions.get(0); + Assert.assertTrue("Wrong type - i1", i1.getInstructionChoice() instanceof GotoTableCase); + Assert.assertEquals("Wrong table-id - i1", 10, ((GotoTableCase) i1.getInstructionChoice()) + .getGotoTable().getTableId().intValue()); + Instruction i2 = instructions.get(1); + Assert.assertTrue("Wrong type - i2", i2.getInstructionChoice() instanceof WriteMetadataCase); + Assert.assertArrayEquals("Wrong metadata - i2", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 20"), + ((WriteMetadataCase) i2.getInstructionChoice()).getWriteMetadata().getMetadata()); + Assert.assertArrayEquals("Wrong metadata-mask - i2", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 30"), + ((WriteMetadataCase) i2.getInstructionChoice()).getWriteMetadata().getMetadataMask()); + Instruction i3 = instructions.get(2); + Assert.assertTrue("Wrong type - i3", i3.getInstructionChoice() instanceof ClearActionsCase); + Instruction i4 = instructions.get(3); + Assert.assertTrue("Wrong type - i4", i4.getInstructionChoice() instanceof MeterCase); + Assert.assertEquals("Wrong meterId - i4", 66051, ((MeterCase) i4.getInstructionChoice()) + .getMeter().getMeterId().intValue()); + Instruction i5 = instructions.get(4); + Assert.assertTrue("Wrong type - i5", i5.getInstructionChoice() instanceof WriteActionsCase); + Assert.assertEquals("Wrong instructions - i5", 2, ((WriteActionsCase) i5.getInstructionChoice()) + .getWriteActions().getAction().size()); + Action action1 = ((WriteActionsCase) i5.getInstructionChoice()).getWriteActions().getAction().get(0); + Assert.assertTrue("Wrong action", action1.getActionChoice() instanceof OutputActionCase); + Assert.assertEquals("Wrong action", 37, ((OutputActionCase) action1.getActionChoice()).getOutputAction() + .getPort().getValue().intValue()); + Assert.assertEquals("Wrong action", 53, ((OutputActionCase) action1.getActionChoice()).getOutputAction() + .getMaxLength().intValue()); + Action action2 = ((WriteActionsCase) i5.getInstructionChoice()).getWriteActions().getAction().get(1); + Assert.assertTrue("Wrong action", action2.getActionChoice() instanceof GroupCase); + Assert.assertEquals("Wrong action", 80, ((GroupCase) action2.getActionChoice()).getGroupAction().getGroupId().intValue()); + Instruction i6 = instructions.get(5); + Assert.assertTrue("Wrong type - i6", i6.getInstructionChoice() instanceof ApplyActionsCase); + Assert.assertEquals("Wrong instructions - i6", 2, ((ApplyActionsCase) i6.getInstructionChoice()) + .getApplyActions().getAction().size()); + action1 = ((ApplyActionsCase) i6.getInstructionChoice()).getApplyActions().getAction().get(0); + Assert.assertTrue("Wrong action", action1.getActionChoice() instanceof SetQueueCase); + Assert.assertEquals("Wrong action", 37, ((SetQueueCase) action1.getActionChoice()).getSetQueueAction() + .getQueueId().intValue()); + action2 = ((ApplyActionsCase) i6.getInstructionChoice()).getApplyActions().getAction().get(1); + Assert.assertTrue("Wrong action", action2.getActionChoice() instanceof SetMplsTtlCase); + Assert.assertEquals("Wrong action", 5, ((SetMplsTtlCase) action2.getActionChoice()).getSetMplsTtlAction() + .getMplsTtl().shortValue()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializerTest.java new file mode 100644 index 0000000000..fb622cd858 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListDeserializerTest.java @@ -0,0 +1,58 @@ +/* + * 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.impl.util; + +import java.util.List; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.yangtools.yang.binding.DataObject; + +/** + * @author michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class ListDeserializerTest { + + @Mock CodeKeyMaker keyMaker; + @Mock DeserializerRegistry registry; + + /** + * Tests {@link ListDeserializer#deserializeList(short, int, ByteBuf, CodeKeyMaker, DeserializerRegistry)} + */ + @Test + public void test() { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + List list = ListDeserializer.deserializeList(EncodeConstants.OF13_VERSION_ID, + 42, buffer, keyMaker, registry); + + Assert.assertNull("List is not null", list); + } + + /** + * Tests {@link ListDeserializer#deserializeHeaders(short, int, ByteBuf, CodeKeyMaker, DeserializerRegistry)} + */ + @Test + public void test2() { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + List list = ListDeserializer.deserializeHeaders(EncodeConstants.OF13_VERSION_ID, + 42, buffer, keyMaker, registry); + + Assert.assertNull("List is not null", list); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializerTest.java new file mode 100644 index 0000000000..e1fdc44526 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/ListSerializerTest.java @@ -0,0 +1,45 @@ +/* + * 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.impl.util; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.PooledByteBufAllocator; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +@RunWith(MockitoJUnitRunner.class) +public class ListSerializerTest { + + @Mock TypeKeyMaker keyMaker; + @Mock SerializerRegistry registry; + + /** + * Tests {@link ListSerializer#serializeHeaderList(List, TypeKeyMaker, SerializerRegistry, ByteBuf)} + * with null List + */ + @Test + public void test() { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeHeaderList(null, keyMaker, registry, buffer); + + Assert.assertEquals("Data written to buffer", 0, buffer.readableBytes()); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java new file mode 100644 index 0000000000..792f1f9dc5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/MatchDeserializerTest.java @@ -0,0 +1,531 @@ +/* + * 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.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.extensibility.HeaderDeserializer; +import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer; +import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey; +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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSha; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpSpa; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTha; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTpa; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Type; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Type; +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.IpDscp; +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.Ipv4Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdSll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTarget; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsBos; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsLabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsTc; +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.PbbIsid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TunnelId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanPcp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; +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.entry.value.grouping.match.entry.value.ArpOpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpShaCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpSpaCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpThaCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpTpaCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4CodeCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4TypeCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6CodeCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6TypeCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPhyPortCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpDscpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpEcnCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpProtoCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4SrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6DstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6ExthdrCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6FlabelCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdSllCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTargetCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTllCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MetadataCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsBosCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsLabelCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsTcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.PbbIsidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TunnelIdCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanPcpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match; + +/** + * @author michal.polkorab + * + */ +public class MatchDeserializerTest { + + private OFDeserializer matchDeserializer; + private DeserializerRegistry registry; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + registry = new DeserializerRegistryImpl(); + registry.init(); + matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF13_VERSION_ID, + EncodeConstants.EMPTY_VALUE, Match.class)); + } + + /** + * Testing Ipv4 address deserialization + */ + @Test + public void testIpv4Address() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("80 00 18 04 00 01 02 03"); + + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0x8000, 12); + key.setExperimenterId(null); + OFDeserializer entryDeserializer = registry.getDeserializer(key); + MatchEntry entry = entryDeserializer.deserialize(buffer); + Assert.assertEquals("Wrong Ipv4 address format", new Ipv4Address("0.1.2.3"), + ((Ipv4DstCase) entry.getMatchEntryValue()).getIpv4Dst().getIpv4Address()); + } + + /** + * Testing Ipv6 address deserialization + */ + @Test + public void testIpv6Address() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("80 00 34 10 00 00 00 01 00 02 00 03 00 04 00 05 00 06 0F 07"); + + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0x8000, 26); + key.setExperimenterId(null); + OFDeserializer entryDeserializer = registry.getDeserializer(key); + MatchEntry entry = entryDeserializer.deserialize(buffer); + Assert.assertEquals("Wrong Ipv6 address format", new Ipv6Address("0:1:2:3:4:5:6:f07"), + ((Ipv6SrcCase) entry.getMatchEntryValue()).getIpv6Src().getIpv6Address()); + } + + /** + * Testing match deserialization + */ + @Test + public void testMatch() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 01 01 A8 " + + "80 00 00 04 00 00 00 01 " + + "80 00 02 04 00 00 00 02 " + + "80 00 05 10 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 04 " + + "80 00 07 0C 00 00 00 00 00 05 00 00 00 00 00 06 " + + "80 00 09 0C 00 00 00 00 00 07 00 00 00 00 00 08 " + + "80 00 0A 02 00 09 " + + "80 00 0D 04 00 0A 00 0B " + + "80 00 0E 01 0C " + + "80 00 10 01 0D " + + "80 00 12 01 0E " + + "80 00 14 01 0F " + + "80 00 17 08 0A 00 00 01 00 00 FF 00 " + + "80 00 19 08 0A 00 00 02 00 00 00 FF " + + "80 00 1A 02 00 03 " + + "80 00 1C 02 00 04 " + + "80 00 1E 02 00 05 " + + "80 00 20 02 00 06 " + + "80 00 22 02 00 07 " + + "80 00 24 02 00 08 " + + "80 00 26 01 05 " + + "80 00 28 01 07 " + + "80 00 2A 02 00 10 " + + "80 00 2D 08 0A 00 00 09 00 00 FF 00 " + + "80 00 2F 08 0A 00 00 0A 00 00 00 FF " + + "80 00 31 0C 00 00 00 00 00 01 00 00 00 00 00 03 " + + "80 00 33 0C 00 00 00 00 00 02 00 00 00 00 00 04 " + + "80 00 35 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 " + + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 16 " + + "80 00 37 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 " + + "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18 " + + "80 00 38 04 00 00 00 02 " + + "80 00 3A 01 15 " + + "80 00 3C 01 17 " + + "80 00 3E 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 " //ipv6ndtarget + + "80 00 40 06 00 05 00 00 00 01 " + + "80 00 42 06 00 05 00 00 00 02 " + + "80 00 44 04 00 00 02 03 " + + "80 00 46 01 03 " + + "80 00 48 01 01 " + + "80 00 4B 06 00 00 02 00 00 01 " + + "80 00 4D 10 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00 FF " + + "80 00 4F 04 00 00 03 04"); + + System.out.println(buffer.readableBytes()); + Match match = matchDeserializer.deserialize(buffer); + Assert.assertEquals("Wrong match type", OxmMatchType.class, match.getType()); + Assert.assertEquals("Wrong match entries size", 40, match.getMatchEntry().size()); + List entries = match.getMatchEntry(); + MatchEntry entry0 = entries.get(0); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry0.getOxmClass()); + Assert.assertEquals("Wrong entry field", InPort.class, entry0.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry0.isHasMask()); + Assert.assertEquals("Wrong entry value", 1, + ((InPortCase) entry0.getMatchEntryValue()).getInPort().getPortNumber().getValue().intValue()); + MatchEntry entry1 = entries.get(1); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry1.getOxmClass()); + Assert.assertEquals("Wrong entry field", InPhyPort.class, entry1.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry1.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + ((InPhyPortCase) entry1.getMatchEntryValue()).getInPhyPort().getPortNumber().getValue().intValue()); + MatchEntry entry2 = entries.get(2); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry2.getOxmClass()); + Assert.assertEquals("Wrong entry field", Metadata.class, entry2.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry2.isHasMask()); + Assert.assertArrayEquals("Wrong entry value", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 03"), + ((MetadataCase) entry2.getMatchEntryValue()).getMetadata().getMetadata()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 04"), + ((MetadataCase) entry2.getMatchEntryValue()).getMetadata().getMask()); + MatchEntry entry3 = entries.get(3); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry3.getOxmClass()); + Assert.assertEquals("Wrong entry field", EthDst.class, entry3.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry3.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:00:00:00:00:05"), + ((EthDstCase) entry3.getMatchEntryValue()).getEthDst().getMacAddress()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 06"), + ((EthDstCase) entry3.getMatchEntryValue()).getEthDst().getMask()); + MatchEntry entry4 = entries.get(4); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry4.getOxmClass()); + Assert.assertEquals("Wrong entry field", EthSrc.class, entry4.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry4.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:00:00:00:00:07"), + ((EthSrcCase) entry4.getMatchEntryValue()).getEthSrc().getMacAddress()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 08"), + ((EthSrcCase) entry4.getMatchEntryValue()).getEthSrc().getMask()); + MatchEntry entry5 = entries.get(5); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry5.getOxmClass()); + Assert.assertEquals("Wrong entry field", EthType.class, entry5.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry5.isHasMask()); + Assert.assertEquals("Wrong entry value", 9, + ((EthTypeCase) entry5.getMatchEntryValue()).getEthType().getEthType().getValue().intValue()); + MatchEntry entry6 = entries.get(6); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry6.getOxmClass()); + Assert.assertEquals("Wrong entry field", VlanVid.class, entry6.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry6.isHasMask()); + Assert.assertEquals("Wrong entry value", 10, + ((VlanVidCase) entry6.getMatchEntryValue()).getVlanVid().getVlanVid().intValue()); + Assert.assertEquals("Wrong entry value", false, + ((VlanVidCase) entry6.getMatchEntryValue()).getVlanVid().isCfiBit()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 0B"), + ((VlanVidCase) entry6.getMatchEntryValue()).getVlanVid().getMask()); + MatchEntry entry7 = entries.get(7); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry7.getOxmClass()); + Assert.assertEquals("Wrong entry field", VlanPcp.class, entry7.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry7.isHasMask()); + Assert.assertEquals("Wrong entry value", 12, + ((VlanPcpCase) entry7.getMatchEntryValue()).getVlanPcp().getVlanPcp().intValue()); + MatchEntry entry8 = entries.get(8); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry8.getOxmClass()); + Assert.assertEquals("Wrong entry field", IpDscp.class, entry8.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry8.isHasMask()); + Assert.assertEquals("Wrong entry value", 13, + ((IpDscpCase) entry8.getMatchEntryValue()).getIpDscp().getDscp().getValue().intValue()); + MatchEntry entry9 = entries.get(9); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry9.getOxmClass()); + Assert.assertEquals("Wrong entry field", IpEcn.class, entry9.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry9.isHasMask()); + Assert.assertEquals("Wrong entry value", 14, + ((IpEcnCase) entry9.getMatchEntryValue()).getIpEcn().getEcn().intValue()); + MatchEntry entry10 = entries.get(10); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry10.getOxmClass()); + Assert.assertEquals("Wrong entry field", IpProto.class, entry10.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry10.isHasMask()); + Assert.assertEquals("Wrong entry value", 15, + ((IpProtoCase) entry10.getMatchEntryValue()).getIpProto().getProtocolNumber().intValue()); + MatchEntry entry11 = entries.get(11); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry11.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv4Src.class, entry11.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry11.isHasMask()); + Assert.assertEquals("Wrong entry value", new Ipv4Address("10.0.0.1"), + ((Ipv4SrcCase) entry11.getMatchEntryValue()).getIpv4Src().getIpv4Address()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 FF 00"), + ((Ipv4SrcCase) entry11.getMatchEntryValue()).getIpv4Src().getMask()); + MatchEntry entry12 = entries.get(12); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry12.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv4Dst.class, entry12.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry12.isHasMask()); + Assert.assertEquals("Wrong entry value", new Ipv4Address("10.0.0.2"), + ((Ipv4DstCase) entry12.getMatchEntryValue()).getIpv4Dst().getIpv4Address()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 FF"), + ((Ipv4DstCase) entry12.getMatchEntryValue()).getIpv4Dst().getMask()); + MatchEntry entry13 = entries.get(13); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry13.getOxmClass()); + Assert.assertEquals("Wrong entry field", TcpSrc.class, entry13.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry13.isHasMask()); + Assert.assertEquals("Wrong entry value", 3, + ((TcpSrcCase) entry13.getMatchEntryValue()).getTcpSrc().getPort().getValue().intValue()); + MatchEntry entry14 = entries.get(14); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry14.getOxmClass()); + Assert.assertEquals("Wrong entry field", TcpDst.class, entry14.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry14.isHasMask()); + Assert.assertEquals("Wrong entry value", 4, + ((TcpDstCase) entry14.getMatchEntryValue()).getTcpDst().getPort().getValue().intValue()); + MatchEntry entry15 = entries.get(15); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry15.getOxmClass()); + Assert.assertEquals("Wrong entry field", UdpSrc.class, entry15.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry15.isHasMask()); + Assert.assertEquals("Wrong entry value", 5, + ((UdpSrcCase) entry15.getMatchEntryValue()).getUdpSrc().getPort().getValue().intValue()); + MatchEntry entry16 = entries.get(16); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry16.getOxmClass()); + Assert.assertEquals("Wrong entry field", UdpDst.class, entry16.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry16.isHasMask()); + Assert.assertEquals("Wrong entry value", 6, + ((UdpDstCase) entry16.getMatchEntryValue()).getUdpDst().getPort().getValue().intValue()); + MatchEntry entry17 = entries.get(17); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry17.getOxmClass()); + Assert.assertEquals("Wrong entry field", SctpSrc.class, entry17.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry17.isHasMask()); + Assert.assertEquals("Wrong entry value", 7, + ((SctpSrcCase) entry17.getMatchEntryValue()).getSctpSrc().getPort().getValue().intValue()); + MatchEntry entry18 = entries.get(18); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry18.getOxmClass()); + Assert.assertEquals("Wrong entry field", SctpDst.class, entry18.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry18.isHasMask()); + Assert.assertEquals("Wrong entry value", 8, + ((SctpDstCase) entry18.getMatchEntryValue()).getSctpDst().getPort().getValue().intValue()); + MatchEntry entry19 = entries.get(19); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry19.getOxmClass()); + Assert.assertEquals("Wrong entry field", Icmpv4Type.class, entry19.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry19.isHasMask()); + Assert.assertEquals("Wrong entry value", 5, + ((Icmpv4TypeCase) entry19.getMatchEntryValue()).getIcmpv4Type().getIcmpv4Type().intValue()); + MatchEntry entry20 = entries.get(20); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry20.getOxmClass()); + Assert.assertEquals("Wrong entry field", Icmpv4Code.class, entry20.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry20.isHasMask()); + Assert.assertEquals("Wrong entry value", 7, + ((Icmpv4CodeCase) entry20.getMatchEntryValue()).getIcmpv4Code().getIcmpv4Code().intValue()); + MatchEntry entry21 = entries.get(21); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry21.getOxmClass()); + Assert.assertEquals("Wrong entry field", ArpOp.class, entry21.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry21.isHasMask()); + Assert.assertEquals("Wrong entry value", 16, + ((ArpOpCase) entry21.getMatchEntryValue()).getArpOp().getOpCode().intValue()); + MatchEntry entry22 = entries.get(22); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry22.getOxmClass()); + Assert.assertEquals("Wrong entry field", ArpSpa.class, entry22.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry22.isHasMask()); + Assert.assertEquals("Wrong entry value", new Ipv4Address("10.0.0.9"), + ((ArpSpaCase) entry22.getMatchEntryValue()).getArpSpa().getIpv4Address()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 FF 00"), + ((ArpSpaCase) entry22.getMatchEntryValue()).getArpSpa().getMask()); + MatchEntry entry23 = entries.get(23); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry23.getOxmClass()); + Assert.assertEquals("Wrong entry field", ArpTpa.class, entry23.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry23.isHasMask()); + Assert.assertEquals("Wrong entry value", new Ipv4Address("10.0.0.10"), + ((ArpTpaCase) entry23.getMatchEntryValue()).getArpTpa().getIpv4Address()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 FF"), + ((ArpTpaCase) entry23.getMatchEntryValue()).getArpTpa().getMask()); + MatchEntry entry24 = entries.get(24); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry24.getOxmClass()); + Assert.assertEquals("Wrong entry field", ArpSha.class, entry24.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry24.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:00:00:00:00:01"), + ((ArpShaCase) entry24.getMatchEntryValue()).getArpSha().getMacAddress()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 03"), + ((ArpShaCase) entry24.getMatchEntryValue()).getArpSha().getMask()); + MatchEntry entry25 = entries.get(25); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry25.getOxmClass()); + Assert.assertEquals("Wrong entry field", ArpTha.class, entry25.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry25.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:00:00:00:00:02"), + ((ArpThaCase) entry25.getMatchEntryValue()).getArpTha().getMacAddress()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 04"), + ((ArpThaCase) entry25.getMatchEntryValue()).getArpTha().getMask()); + MatchEntry entry26 = entries.get(26); + 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("::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"), + ((Ipv6SrcCase) entry26.getMatchEntryValue()).getIpv6Src().getMask()); + MatchEntry entry27 = entries.get(27); + 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("::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"), + ((Ipv6DstCase) entry27.getMatchEntryValue()).getIpv6Dst().getMask()); + MatchEntry entry28 = entries.get(28); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry28.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Flabel.class, entry28.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry28.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + ((Ipv6FlabelCase) entry28.getMatchEntryValue()).getIpv6Flabel().getIpv6Flabel() + .getValue().intValue()); + MatchEntry entry29 = entries.get(29); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry29.getOxmClass()); + Assert.assertEquals("Wrong entry field", Icmpv6Type.class, entry29.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry29.isHasMask()); + Assert.assertEquals("Wrong entry value", 21, + ((Icmpv6TypeCase) entry29.getMatchEntryValue()).getIcmpv6Type().getIcmpv6Type().intValue()); + MatchEntry entry30 = entries.get(30); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry30.getOxmClass()); + Assert.assertEquals("Wrong entry field", Icmpv6Code.class, entry30.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry30.isHasMask()); + Assert.assertEquals("Wrong entry value", 23, + ((Icmpv6CodeCase) entry30.getMatchEntryValue()).getIcmpv6Code().getIcmpv6Code().intValue()); + MatchEntry entry31 = entries.get(31); + 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("::20"), + ((Ipv6NdTargetCase) entry31.getMatchEntryValue()).getIpv6NdTarget().getIpv6Address()); + MatchEntry entry32 = entries.get(32); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry32.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6NdSll.class, entry32.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry32.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:05:00:00:00:01"), + ((Ipv6NdSllCase) entry32.getMatchEntryValue()).getIpv6NdSll().getMacAddress()); + MatchEntry entry33 = entries.get(33); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry33.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6NdTll.class, entry33.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry33.isHasMask()); + Assert.assertEquals("Wrong entry value", new MacAddress("00:05:00:00:00:02"), + ((Ipv6NdTllCase) entry33.getMatchEntryValue()).getIpv6NdTll().getMacAddress()); + MatchEntry entry34 = entries.get(34); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry34.getOxmClass()); + Assert.assertEquals("Wrong entry field", MplsLabel.class, entry34.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry34.isHasMask()); + Assert.assertEquals("Wrong entry value", 515, + ((MplsLabelCase) entry34.getMatchEntryValue()).getMplsLabel().getMplsLabel().intValue()); + MatchEntry entry35 = entries.get(35); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry35.getOxmClass()); + Assert.assertEquals("Wrong entry field", MplsTc.class, entry35.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry35.isHasMask()); + Assert.assertEquals("Wrong entry value", 3, + ((MplsTcCase) entry35.getMatchEntryValue()).getMplsTc().getTc().intValue()); + MatchEntry entry36 = entries.get(36); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry36.getOxmClass()); + Assert.assertEquals("Wrong entry field", MplsBos.class, entry36.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry36.isHasMask()); + Assert.assertEquals("Wrong entry value", true, + ((MplsBosCase) entry36.getMatchEntryValue()).getMplsBos().isBos()); + MatchEntry entry37 = entries.get(37); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry37.getOxmClass()); + Assert.assertEquals("Wrong entry field", PbbIsid.class, entry37.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry37.isHasMask()); + Assert.assertEquals("Wrong entry value", 2, + ((PbbIsidCase) entry37.getMatchEntryValue()).getPbbIsid().getIsid().intValue()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 01"), + ((PbbIsidCase) entry37.getMatchEntryValue()).getPbbIsid().getMask()); + MatchEntry entry38 = entries.get(38); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry38.getOxmClass()); + Assert.assertEquals("Wrong entry field", TunnelId.class, entry38.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry38.isHasMask()); + Assert.assertArrayEquals("Wrong entry value", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 07"), + ((TunnelIdCase) entry38.getMatchEntryValue()).getTunnelId().getTunnelId()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("00 00 00 00 00 00 00 FF"), + ((TunnelIdCase) entry38.getMatchEntryValue()).getTunnelId().getMask()); + MatchEntry entry39 = entries.get(39); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry39.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv6Exthdr.class, entry39.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", true, entry39.isHasMask()); + Assert.assertEquals("Wrong entry value", + new Ipv6ExthdrFlags(false, false, false, false, false, false, false, false, false), + ((Ipv6ExthdrCase) entry39.getMatchEntryValue()).getIpv6Exthdr().getPseudoField()); + Assert.assertArrayEquals("Wrong entry mask", ByteBufUtils.hexStringToBytes("03 04"), + ((Ipv6ExthdrCase) entry39.getMatchEntryValue()).getIpv6Exthdr().getMask()); + Assert.assertTrue("Unread data", buffer.readableBytes() == 0); + } + + /** + * Testing header deserialization + */ + @Test + public void testHeaders() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("80 00 18 04 00 01 02 03"); + + MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(EncodeConstants.OF13_VERSION_ID, + 0x8000, 12); + key.setExperimenterId(null); + HeaderDeserializer entryDeserializer = registry.getDeserializer(key); + MatchEntry entry = entryDeserializer.deserializeHeader(buffer); + Assert.assertEquals("Wrong entry class", OpenflowBasicClass.class, entry.getOxmClass()); + Assert.assertEquals("Wrong entry field", Ipv4Dst.class, entry.getOxmMatchField()); + Assert.assertEquals("Wrong entry hasMask", false, entry.isHasMask()); + Assert.assertNull("Wrong Ipv4 address", entry.getMatchEntryValue()); + } + + /** + * Testing standard match type + */ + @Test + public void testStandardMatch() { + ByteBuf buffer = ByteBufUtils.hexStringToByteBuf("00 00 00 10 80 00 04 08 00 00 00 00 00 00 00 01"); + + Match match = matchDeserializer.deserialize(buffer); + + Assert.assertEquals("Wrong match type", StandardMatchType.class, match.getType()); + Assert.assertEquals("Wrong match entries size", 1, match.getMatchEntry().size()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java new file mode 100644 index 0000000000..8c0d4eaadd --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsDeserializerTest.java @@ -0,0 +1,125 @@ +/* + * 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.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.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; +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.action.grouping.action.choice.SetNwDstCase; +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.action.grouping.action.choice.SetNwTosCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpDstCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpSrcCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanPcpCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanVidCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.StripVlanCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action; + +/** + * @author michal.polkorab + * + */ +public class OF10ActionsDeserializerTest { + + private DeserializerRegistry registry; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + registry = new DeserializerRegistryImpl(); + registry.init(); + } + + /** + * Testing correct deserialization of actions (OF v1.0) + */ + @Test + public void test() { + ByteBuf message = BufferHelper.buildBuffer("00 00 00 08 00 10 20 00 " + + "00 01 00 08 10 10 00 00 " + + "00 02 00 08 25 00 00 00 " + + "00 03 00 08 00 00 00 00 " + + "00 04 00 10 01 02 03 04 05 06 00 00 00 00 00 00 " + + "00 05 00 10 02 03 04 05 06 07 00 00 00 00 00 00 " + + "00 06 00 08 0A 00 00 01 " + + "00 07 00 08 0B 00 00 02 " + + "00 08 00 08 01 00 00 00 " + + "00 09 00 08 00 02 00 00 " + + "00 0A 00 08 00 03 00 00 " + + "00 0B 00 10 00 04 00 00 00 00 00 00 00 00 00 30"); + + message.skipBytes(4); // skip XID + CodeKeyMaker keyMaker = CodeKeyMakerFactory.createActionsKeyMaker(EncodeConstants.OF10_VERSION_ID); + List actions = ListDeserializer.deserializeList(EncodeConstants.OF10_VERSION_ID, + message.readableBytes(), message, keyMaker, registry); + Assert.assertEquals("Wrong number of actions", 12, actions.size()); + Action action1 = actions.get(0); + Assert.assertTrue("Wrong action type", action1.getActionChoice() instanceof OutputActionCase); + Assert.assertEquals("Wrong port", 16, + ((OutputActionCase) action1.getActionChoice()).getOutputAction().getPort().getValue().intValue()); + Assert.assertEquals("Wrong max-length", 8192, + ((OutputActionCase) action1.getActionChoice()).getOutputAction().getMaxLength().intValue()); + Action action2 = actions.get(1); + Assert.assertTrue("Wrong action type", action2.getActionChoice() instanceof SetVlanVidCase); + Assert.assertEquals("Wrong vlan-vid", 4112, + ((SetVlanVidCase) action2.getActionChoice()).getSetVlanVidAction().getVlanVid().intValue()); + Action action3 = actions.get(2); + Assert.assertTrue("Wrong action type", action3.getActionChoice() instanceof SetVlanPcpCase); + Assert.assertEquals("Wrong vlan-pcp", 37, + ((SetVlanPcpCase) action3.getActionChoice()).getSetVlanPcpAction().getVlanPcp().intValue()); + Action action4 = actions.get(3); + Assert.assertTrue("Wrong action type", action4.getActionChoice() instanceof StripVlanCase); + Action action5 = actions.get(4); + Assert.assertTrue("Wrong action type", action5.getActionChoice() instanceof SetDlSrcCase); + 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.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"), + ((SetNwSrcCase) action7.getActionChoice()).getSetNwSrcAction().getIpAddress()); + Action action8 = actions.get(7); + Assert.assertTrue("Wrong action type", action8.getActionChoice() instanceof SetNwDstCase); + Assert.assertEquals("Wrong nw-dst", new Ipv4Address("11.0.0.2"), + ((SetNwDstCase) action8.getActionChoice()).getSetNwDstAction().getIpAddress()); + Action action9 = actions.get(8); + Assert.assertTrue("Wrong action type", action9.getActionChoice() instanceof SetNwTosCase); + Assert.assertEquals("Wrong nw-tos", 1, ((SetNwTosCase) action9.getActionChoice()) + .getSetNwTosAction().getNwTos().intValue()); + Action action10 = actions.get(9); + Assert.assertTrue("Wrong action type", action10.getActionChoice() instanceof SetTpSrcCase); + Assert.assertEquals("Wrong port", 2, ((SetTpSrcCase) action10.getActionChoice()) + .getSetTpSrcAction().getPort().getValue().intValue()); + Action action11 = actions.get(10); + Assert.assertTrue("Wrong action type", action11.getActionChoice() instanceof SetTpDstCase); + Assert.assertEquals("Wrong port", 3, ((SetTpDstCase) action11.getActionChoice()) + .getSetTpDstAction().getPort().getValue().intValue()); + Action action12 = actions.get(11); + Assert.assertTrue("Wrong action type", action12.getActionChoice() instanceof EnqueueCase); + Assert.assertEquals("Wrong port", 4, ((EnqueueCase) action12.getActionChoice()) + .getEnqueueAction().getPort().getValue().intValue()); + Assert.assertEquals("Wrong queue-id", 48, ((EnqueueCase) action12.getActionChoice()) + .getEnqueueAction().getQueueId().getValue().intValue()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java new file mode 100644 index 0000000000..07f11eba1c --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10ActionsSerializerTest.java @@ -0,0 +1,222 @@ +/* + * 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.util; + +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.SerializerRegistry; +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.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; +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.SetNwDstCaseBuilder; +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.SetNwTosCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetTpDstCaseBuilder; +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.SetVlanPcpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetVlanVidCaseBuilder; +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.enqueue._case.EnqueueActionBuilder; +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.set.dl.dst._case.SetDlDstActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.dl.src._case.SetDlSrcActionBuilder; +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.nw.src._case.SetNwSrcActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.nw.tos._case.SetNwTosActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.tp.dst._case.SetTpDstActionBuilder; +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.action.grouping.action.choice.set.vlan.pcp._case.SetVlanPcpActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.vlan.vid._case.SetVlanVidActionBuilder; +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.common.types.rev130731.QueueId; + +/** + * @author michal.polkorab + * + */ +public class OF10ActionsSerializerTest { + + private SerializerRegistry registry; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + } + + /** + * Testing correct serialization of actions (OF v1.0) + */ + @Test + public void test() { + List actions = new ArrayList<>(); + ActionBuilder actionBuilder = new ActionBuilder(); + OutputActionCaseBuilder caseBuilder = new OutputActionCaseBuilder(); + OutputActionBuilder outputBuilder = new OutputActionBuilder(); + outputBuilder.setPort(new PortNumber(42L)); + outputBuilder.setMaxLength(32); + caseBuilder.setOutputAction(outputBuilder.build()); + actionBuilder.setActionChoice(caseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetVlanVidCaseBuilder vlanVidCaseBuilder = new SetVlanVidCaseBuilder(); + SetVlanVidActionBuilder vlanVidBuilder = new SetVlanVidActionBuilder(); + vlanVidBuilder.setVlanVid(15); + vlanVidCaseBuilder.setSetVlanVidAction(vlanVidBuilder.build()); + actionBuilder.setActionChoice(vlanVidCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetVlanPcpCaseBuilder vlanPcpCaseBuilder = new SetVlanPcpCaseBuilder(); + SetVlanPcpActionBuilder vlanPcpBuilder = new SetVlanPcpActionBuilder(); + vlanPcpBuilder.setVlanPcp((short) 16); + vlanPcpCaseBuilder.setSetVlanPcpAction(vlanPcpBuilder.build()); + actionBuilder.setActionChoice(vlanPcpCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new StripVlanCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetDlSrcCaseBuilder dlSrcCaseBuilder = new SetDlSrcCaseBuilder(); + SetDlSrcActionBuilder dlSrcBuilder = new SetDlSrcActionBuilder(); + dlSrcBuilder.setDlSrcAddress(new MacAddress("00:00:00:02:03:04")); + dlSrcCaseBuilder.setSetDlSrcAction(dlSrcBuilder.build()); + actionBuilder.setActionChoice(dlSrcCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetDlDstCaseBuilder dlDstCaseBuilder = new SetDlDstCaseBuilder(); + SetDlDstActionBuilder dlDstBuilder = new SetDlDstActionBuilder(); + dlDstBuilder.setDlDstAddress(new MacAddress("00:00:00:01:02:03")); + dlDstCaseBuilder.setSetDlDstAction(dlDstBuilder.build()); + actionBuilder.setActionChoice(dlDstCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwSrcCaseBuilder nwSrcCaseBuilder = new SetNwSrcCaseBuilder(); + SetNwSrcActionBuilder nwSrcBuilder = new SetNwSrcActionBuilder(); + nwSrcBuilder.setIpAddress(new Ipv4Address("10.0.0.1")); + nwSrcCaseBuilder.setSetNwSrcAction(nwSrcBuilder.build()); + actionBuilder.setActionChoice(nwSrcCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwDstCaseBuilder nwDstCaseBuilder = new SetNwDstCaseBuilder(); + SetNwDstActionBuilder nwDstBuilder = new SetNwDstActionBuilder(); + nwDstBuilder.setIpAddress(new Ipv4Address("10.0.0.3")); + nwDstCaseBuilder.setSetNwDstAction(nwDstBuilder.build()); + actionBuilder.setActionChoice(nwDstCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwTosCaseBuilder tosCaseBuilder = new SetNwTosCaseBuilder(); + SetNwTosActionBuilder tosBuilder = new SetNwTosActionBuilder(); + tosBuilder.setNwTos((short) 204); + tosCaseBuilder.setSetNwTosAction(tosBuilder.build()); + actionBuilder.setActionChoice(tosCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetTpSrcCaseBuilder tpSrcCaseBuilder = new SetTpSrcCaseBuilder(); + SetTpSrcActionBuilder tpSrcBuilder = new SetTpSrcActionBuilder(); + tpSrcBuilder.setPort(new PortNumber(6653L)); + tpSrcCaseBuilder.setSetTpSrcAction(tpSrcBuilder.build()); + actionBuilder.setActionChoice(tpSrcCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetTpDstCaseBuilder tpDstCaseBuilder = new SetTpDstCaseBuilder(); + SetTpDstActionBuilder tpDstBuilder = new SetTpDstActionBuilder(); + tpDstBuilder.setPort(new PortNumber(6633L)); + tpDstCaseBuilder.setSetTpDstAction(tpDstBuilder.build()); + actionBuilder.setActionChoice(tpDstCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + EnqueueCaseBuilder enqueueCaseBuilder = new EnqueueCaseBuilder(); + EnqueueActionBuilder enqueueBuilder = new EnqueueActionBuilder(); + enqueueBuilder.setPort(new PortNumber(6613L)); + enqueueBuilder.setQueueId(new QueueId(400L)); + enqueueCaseBuilder.setEnqueueAction(enqueueBuilder.build()); + actionBuilder.setActionChoice(enqueueCaseBuilder.build()); + actions.add(actionBuilder.build()); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeList(actions, TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF10_VERSION_ID), registry, out); + + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 42, out.readUnsignedShort()); + Assert.assertEquals("Wrong max-length", 32, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong vlan-vid", 15, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong vlan-pcp", 16, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong action type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + byte[] data = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + out.readBytes(data); + Assert.assertArrayEquals("Wrong dl-address", ByteBufUtils.macAddressToBytes("00:00:00:02:03:04"), data); + out.skipBytes(6); + Assert.assertEquals("Wrong action type", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + data = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + out.readBytes(data); + Assert.assertArrayEquals("Wrong dl-address", ByteBufUtils.macAddressToBytes("00:00:00:01:02:03"), data); + out.skipBytes(6); + Assert.assertEquals("Wrong action type", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong ip-address(1)", 10, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(2)", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(3)", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(4)", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong action type", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong ip-address(1)", 10, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(2)", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(3)", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip-address(4)", 3, out.readUnsignedByte()); + Assert.assertEquals("Wrong action type", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong nw-tos", 204, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong action type", 9, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 6653, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 10, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 6633, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 11, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong port", 6613, out.readUnsignedShort()); + out.skipBytes(6); + Assert.assertEquals("Wrong queue-id", 400, out.readUnsignedInt()); + Assert.assertTrue("Written more bytes than needed", out.readableBytes() == 0); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java new file mode 100644 index 0000000000..d4f7b9be4f --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchDeserializerTest.java @@ -0,0 +1,101 @@ +/* + * 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.util; + +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.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; + +/** + * @author michal.polkorab + * + */ +public class OF10MatchDeserializerTest { + + private OFDeserializer matchDeserializer; + + /** + * Initializes deserializer registry and lookups correct deserializer + */ + @Before + public void startUp() { + DeserializerRegistry registry = new DeserializerRegistryImpl(); + registry.init(); + matchDeserializer = registry.getDeserializer( + new MessageCodeKey(EncodeConstants.OF10_VERSION_ID, EncodeConstants.EMPTY_VALUE, MatchV10.class)); + } + + /** + * Testing correct deserialization of ofp_match + */ + @Test + public void test() { + ByteBuf message = BufferHelper.buildBuffer("00 24 08 91 00 20 AA BB CC DD EE FF " + + "AA BB CC DD EE FF 00 05 10 00 00 08 07 06 00 00 10 11 12 13 01 02 03 04 " + + "50 50 20 20"); + message.skipBytes(4); // skip XID + MatchV10 match = matchDeserializer.deserialize(message); + Assert.assertEquals("Wrong wildcards", new FlowWildcardsV10(false, false, true, false, + false, true, false, true, true, false), match.getWildcards()); + 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-vlan", 5, match.getDlVlan().intValue()); + Assert.assertEquals("Wrong dl-vlan-pcp", 16, match.getDlVlanPcp().shortValue()); + Assert.assertEquals("Wrong dl-type", 8, match.getDlType().intValue()); + Assert.assertEquals("Wrong nw-tos", 7, match.getNwTos().shortValue()); + Assert.assertEquals("Wrong nw-proto", 6, match.getNwProto().shortValue()); + Assert.assertEquals("Wrong nw-src", new Ipv4Address("16.17.18.19"), match.getNwSrc()); + Assert.assertEquals("Wrong nw-dst", new Ipv4Address("1.2.3.4"), match.getNwDst()); + Assert.assertEquals("Wrong tp-src", 20560, match.getTpSrc().shortValue()); + Assert.assertEquals("Wrong tp-dst", 8224, match.getTpDst().shortValue()); + } + + /** + * Testing correct deserialization of ofp_match + */ + @Test + public void test2() { + ByteBuf message = BufferHelper.buildBuffer("00 3F FF FF 00 20 AA BB CC DD EE FF " + + "AA BB CC DD EE FF 00 05 10 00 00 08 07 06 00 00 10 11 12 13 01 02 03 04 " + + "50 50 20 20"); + message.skipBytes(4); // skip XID + MatchV10 match = matchDeserializer.deserialize(message); + Assert.assertEquals("Wrong wildcards", new FlowWildcardsV10(true, true, true, true, + true, true, true, true, true, true), match.getWildcards()); + 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-vlan", 5, match.getDlVlan().intValue()); + Assert.assertEquals("Wrong dl-vlan-pcp", 16, match.getDlVlanPcp().shortValue()); + Assert.assertEquals("Wrong dl-type", 8, match.getDlType().intValue()); + Assert.assertEquals("Wrong nw-tos", 7, match.getNwTos().shortValue()); + Assert.assertEquals("Wrong nw-proto", 6, match.getNwProto().shortValue()); + Assert.assertEquals("Wrong nw-src", new Ipv4Address("16.17.18.19"), match.getNwSrc()); + Assert.assertEquals("Wrong nw-dst", new Ipv4Address("1.2.3.4"), match.getNwDst()); + Assert.assertEquals("Wrong tp-src", 20560, match.getTpSrc().shortValue()); + Assert.assertEquals("Wrong tp-dst", 8224, match.getTpDst().shortValue()); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java new file mode 100644 index 0000000000..4e27095eb9 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF10MatchSerializerTest.java @@ -0,0 +1,142 @@ +/* + * 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.util; + +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.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.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; + +/** + * @author michal.polkorab + * + */ +public class OF10MatchSerializerTest { + + private SerializerRegistry registry; + private OFSerializer matchSerializer; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + matchSerializer = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF10_VERSION_ID, MatchV10.class)); + } + + /** + * Testing correct serialization of ofp_match + */ + @Test + public void test() { + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + MatchV10Builder builder = new MatchV10Builder(); + builder.setWildcards(new FlowWildcardsV10(false, false, true, false, + false, true, false, true, true, true)); + builder.setNwSrcMask((short) 24); + builder.setNwDstMask((short) 16); + builder.setInPort(6653); + builder.setDlSrc(new MacAddress("01:01:01:01:01:01")); + builder.setDlDst(new MacAddress("02:02:02:02:02:02")); + builder.setDlVlan(128); + builder.setDlVlanPcp((short) 2); + builder.setDlType(15); + builder.setNwTos((short) 14); + builder.setNwProto((short) 85); + builder.setNwSrc(new Ipv4Address("1.1.1.2")); + builder.setNwDst(new Ipv4Address("32.16.8.1")); + builder.setTpSrc(2048); + builder.setTpDst(4096); + MatchV10 match = builder.build(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong wildcards", 2361553, out.readUnsignedInt()); + Assert.assertEquals("Wrong in-port", 6653, out.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + out.readBytes(dlSrc); + Assert.assertEquals("Wrong dl-src", "01:01:01:01:01:01", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + out.readBytes(dlDst); + Assert.assertEquals("Wrong dl-dst", "02:02:02:02:02:02", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dl-vlan", 128, out.readUnsignedShort()); + Assert.assertEquals("Wrong dl-vlan-pcp", 2, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong dl-type", 15, out.readUnsignedShort()); + Assert.assertEquals("Wrong nw-tos", 14, out.readUnsignedByte()); + Assert.assertEquals("Wrong nw-proto", 85, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong nw-src", 16843010, out.readUnsignedInt()); + Assert.assertEquals("Wrong nw-dst", 537921537, out.readUnsignedInt()); + Assert.assertEquals("Wrong tp-src", 2048, out.readUnsignedShort()); + Assert.assertEquals("Wrong tp-dst", 4096, out.readUnsignedShort()); + } + + /** + * Testing correct serialization of ofp_match + */ + @Test + public void test2() { + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + MatchV10Builder builder = new MatchV10Builder(); + builder.setWildcards(new FlowWildcardsV10(true, true, true, true, + true, true, true, true, true, true)); + builder.setNwSrcMask((short) 0); + builder.setNwDstMask((short) 0); + builder.setInPort(6653); + builder.setDlSrc(new MacAddress("01:01:01:01:01:01")); + builder.setDlDst(new MacAddress("02:02:02:02:02:02")); + builder.setDlVlan(128); + builder.setDlVlanPcp((short) 2); + builder.setDlType(15); + builder.setNwTos((short) 14); + builder.setNwProto((short) 85); + builder.setNwSrc(new Ipv4Address("1.1.1.2")); + builder.setNwDst(new Ipv4Address("32.16.8.1")); + builder.setTpSrc(2048); + builder.setTpDst(4096); + MatchV10 match = builder.build(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong wildcards", 3678463, out.readUnsignedInt()); + Assert.assertEquals("Wrong in-port", 6653, out.readUnsignedShort()); + byte[] dlSrc = new byte[6]; + out.readBytes(dlSrc); + Assert.assertEquals("Wrong dl-src", "01:01:01:01:01:01", ByteBufUtils.macAddressToString(dlSrc)); + byte[] dlDst = new byte[6]; + out.readBytes(dlDst); + Assert.assertEquals("Wrong dl-dst", "02:02:02:02:02:02", ByteBufUtils.macAddressToString(dlDst)); + Assert.assertEquals("Wrong dl-vlan", 128, out.readUnsignedShort()); + Assert.assertEquals("Wrong dl-vlan-pcp", 2, out.readUnsignedByte()); + out.skipBytes(1); + Assert.assertEquals("Wrong dl-type", 15, out.readUnsignedShort()); + Assert.assertEquals("Wrong nw-tos", 14, out.readUnsignedByte()); + Assert.assertEquals("Wrong nw-proto", 85, out.readUnsignedByte()); + out.skipBytes(2); + Assert.assertEquals("Wrong nw-src", 16843010, out.readUnsignedInt()); + Assert.assertEquals("Wrong nw-dst", 537921537, out.readUnsignedInt()); + Assert.assertEquals("Wrong tp-src", 2048, out.readUnsignedShort()); + Assert.assertEquals("Wrong tp-dst", 4096, out.readUnsignedShort()); + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java new file mode 100644 index 0000000000..66462d8ba4 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13ActionsSerializerTest.java @@ -0,0 +1,293 @@ +/* + * 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.util; + +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.SerializerRegistry; +import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; +import org.opendaylight.openflowjava.protocol.impl.serialization.SerializerRegistryImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlOutCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecMplsTtlCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.DecNwTtlCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.GroupCaseBuilder; +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.PopMplsCaseBuilder; +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.PopVlanCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushMplsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.PushPbbCaseBuilder; +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.SetFieldCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.SetMplsTtlCaseBuilder; +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.SetQueueCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.group._case.GroupActionBuilder; +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.pop.mpls._case.PopMplsActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.mpls._case.PushMplsActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.push.pbb._case.PushPbbActionBuilder; +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.field._case.SetFieldActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.set.mpls.ttl._case.SetMplsTtlActionBuilder; +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.action.grouping.action.choice.set.queue._case.SetQueueActionBuilder; +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.oxm.rev150225.InPort; +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.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.port._case.InPortBuilder; + +/** + * @author michal.polkorab + * + */ +public class OF13ActionsSerializerTest { + + private SerializerRegistry registry; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + } + + /** + * Testing correct serialization of actions + */ + @Test + public void test() { + 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()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new CopyTtlOutCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new CopyTtlInCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetMplsTtlCaseBuilder setMplsTtlCaseBuilder = new SetMplsTtlCaseBuilder(); + SetMplsTtlActionBuilder setMplsTtlBuilder = new SetMplsTtlActionBuilder(); + setMplsTtlBuilder.setMplsTtl((short) 4); + setMplsTtlCaseBuilder.setSetMplsTtlAction(setMplsTtlBuilder.build()); + actionBuilder.setActionChoice(setMplsTtlCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new DecMplsTtlCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + PushVlanCaseBuilder pushVlanCaseBuilder = new PushVlanCaseBuilder(); + PushVlanActionBuilder pushVlanBuilder = new PushVlanActionBuilder(); + pushVlanBuilder.setEthertype(new EtherType(new EtherType(16))); + 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(); + PushMplsCaseBuilder pushMplsCaseBuilder = new PushMplsCaseBuilder(); + PushMplsActionBuilder pushMplsBuilder = new PushMplsActionBuilder(); + pushMplsBuilder.setEthertype(new EtherType(new EtherType(17))); + pushMplsCaseBuilder.setPushMplsAction(pushMplsBuilder.build()); + actionBuilder.setActionChoice(pushMplsCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + PopMplsCaseBuilder popMplsCaseBuilder = new PopMplsCaseBuilder(); + PopMplsActionBuilder popMplsBuilder = new PopMplsActionBuilder(); + popMplsBuilder.setEthertype(new EtherType(new EtherType(18))); + popMplsCaseBuilder.setPopMplsAction(popMplsBuilder.build()); + actionBuilder.setActionChoice(popMplsCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetQueueCaseBuilder setQueueCaseBuilder = new SetQueueCaseBuilder(); + SetQueueActionBuilder setQueueBuilder = new SetQueueActionBuilder(); + setQueueBuilder.setQueueId(1234L); + setQueueCaseBuilder.setSetQueueAction(setQueueBuilder.build()); + actionBuilder.setActionChoice(setQueueCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + GroupCaseBuilder groupCaseBuilder = new GroupCaseBuilder(); + GroupActionBuilder groupActionBuilder = new GroupActionBuilder(); + groupActionBuilder.setGroupId(555L); + groupCaseBuilder.setGroupAction(groupActionBuilder.build()); + actionBuilder.setActionChoice(groupCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetNwTtlCaseBuilder nwTtlCaseBuilder = new SetNwTtlCaseBuilder(); + SetNwTtlActionBuilder nwTtlBuilder = new SetNwTtlActionBuilder(); + nwTtlBuilder.setNwTtl((short) 8); + nwTtlCaseBuilder.setSetNwTtlAction(nwTtlBuilder.build()); + actionBuilder.setActionChoice(nwTtlCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new DecNwTtlCaseBuilder().build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + SetFieldCaseBuilder setFieldCaseBuilder = new SetFieldCaseBuilder(); + SetFieldActionBuilder setFieldBuilder = new SetFieldActionBuilder(); + List entries = new ArrayList<>(); + MatchEntryBuilder matchBuilder = new MatchEntryBuilder(); + matchBuilder.setOxmClass(OpenflowBasicClass.class); + matchBuilder.setOxmMatchField(InPort.class); + matchBuilder.setHasMask(false); + InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder(); + InPortBuilder inPortBuilder = new InPortBuilder(); + inPortBuilder.setPortNumber(new PortNumber(1L)); + inPortCaseBuilder.setInPort(inPortBuilder.build()); + matchBuilder.setMatchEntryValue(inPortCaseBuilder.build()); + entries.add(matchBuilder.build()); + setFieldBuilder.setMatchEntry(entries); + setFieldCaseBuilder.setSetFieldAction(setFieldBuilder.build()); + actionBuilder.setActionChoice(setFieldCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + PushPbbCaseBuilder pushPbbCaseBuilder = new PushPbbCaseBuilder(); + PushPbbActionBuilder pushPbbBuilder = new PushPbbActionBuilder(); + pushPbbBuilder.setEthertype(new EtherType(new EtherType(19))); + pushPbbCaseBuilder.setPushPbbAction(pushPbbBuilder.build()); + actionBuilder.setActionChoice(pushPbbCaseBuilder.build()); + actions.add(actionBuilder.build()); + actionBuilder = new ActionBuilder(); + actionBuilder.setActionChoice(new PopPbbCaseBuilder().build()); + actions.add(actionBuilder.build()); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeList(actions, TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, out); + + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong action port", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong action max-length", 52, out.readUnsignedShort()); + out.skipBytes(6); + Assert.assertEquals("Wrong action type", 11, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 12, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 15, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action mpls-ttl", 4, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong action type", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 17, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 16, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 18, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 19, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 17, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 20, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 18, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 21, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action queue-id", 1234, out.readUnsignedInt()); + Assert.assertEquals("Wrong action type", 22, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action group", 555, out.readUnsignedInt()); + Assert.assertEquals("Wrong action type", 23, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action nw-ttl", 8, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong action type", 24, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 25, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & mask", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 1, out.readUnsignedInt()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 26, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 19, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 27, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } + + /** + * Testing correct serialization of actions + */ + @Test + public void testHeaders() { + 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()); + actionBuilder = new ActionBuilder(); + SetFieldCaseBuilder setFieldCaseBuilder = new SetFieldCaseBuilder(); + SetFieldActionBuilder setFieldBuilder = new SetFieldActionBuilder(); + List entries = new ArrayList<>(); + MatchEntryBuilder matchBuilder = new MatchEntryBuilder(); + matchBuilder.setOxmClass(OpenflowBasicClass.class); + matchBuilder.setOxmMatchField(InPort.class); + matchBuilder.setHasMask(false); + InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder(); + InPortBuilder inPortBuilder = new InPortBuilder(); + inPortBuilder.setPortNumber(new PortNumber(1L)); + inPortCaseBuilder.setInPort(inPortBuilder.build()); + matchBuilder.setMatchEntryValue(inPortCaseBuilder.build()); + entries.add(matchBuilder.build()); + setFieldBuilder.setMatchEntry(entries); + setFieldCaseBuilder.setSetFieldAction(setFieldBuilder.build()); + actionBuilder.setActionChoice(setFieldCaseBuilder.build()); + actions.add(actionBuilder.build()); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeHeaderList(actions, TypeKeyMakerFactory + .createActionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, out); + + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 25, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 4, out.readUnsignedShort()); + Assert.assertTrue("Unread data", out.readableBytes() == 0); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13InstructionsSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13InstructionsSerializerTest.java new file mode 100644 index 0000000000..251c4c945d --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13InstructionsSerializerTest.java @@ -0,0 +1,194 @@ +/* + * 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.util; + +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.SerializerRegistry; +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.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.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber; + +/** + * @author michal.polkorab + * + */ +public class OF13InstructionsSerializerTest { + + private SerializerRegistry registry; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + } + + /** + * Testing instructions translation + */ + @Test + public void test() { + List instructions = new ArrayList<>(); + // Goto_table instruction + InstructionBuilder builder = new InstructionBuilder(); + GotoTableCaseBuilder gotoCaseBuilder = new GotoTableCaseBuilder(); + GotoTableBuilder instructionBuilder = new GotoTableBuilder(); + instructionBuilder.setTableId((short) 5); + gotoCaseBuilder.setGotoTable(instructionBuilder.build()); + builder.setInstructionChoice(gotoCaseBuilder.build()); + instructions.add(builder.build()); + // Write_metadata instruction + builder = 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()); + builder.setInstructionChoice(metadataCaseBuilder.build()); + instructions.add(builder.build()); + // Clear_actions instruction + builder = new InstructionBuilder(); + builder.setInstructionChoice(new ClearActionsCaseBuilder().build()); + instructions.add(builder.build()); + // Meter instruction + builder = new InstructionBuilder(); + MeterCaseBuilder meterCaseBuilder = new MeterCaseBuilder(); + MeterBuilder meterBuilder = new MeterBuilder(); + meterBuilder.setMeterId(42L); + meterCaseBuilder.setMeter(meterBuilder.build()); + builder.setInstructionChoice(meterCaseBuilder.build()); + instructions.add(builder.build()); + // Write_actions instruction + builder = 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()); + builder.setInstructionChoice(writeActionsCaseBuilder.build()); + instructions.add(builder.build()); + // Apply_actions instruction + builder = 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()); + builder.setInstructionChoice(applyActionsCaseBuilder.build()); + instructions.add(builder.build()); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + ListSerializer.serializeList(instructions, TypeKeyMakerFactory + .createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID), registry, out); + + Assert.assertEquals("Wrong instruction type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction table-id", 5, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 24, out.readUnsignedShort()); + out.skipBytes(4); + byte[] actual = new byte[8]; + out.readBytes(actual); + Assert.assertEquals("Wrong instruction metadata", "00 01 02 03 04 05 06 07", + ByteBufUtils.bytesToHexString(actual)); + actual = new byte[8]; + out.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, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong instruction type", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction meter-id", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong instruction type", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 32, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 16, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 45, out.readUnsignedInt()); + Assert.assertEquals("Wrong action type", 55, out.readUnsignedShort()); + out.skipBytes(6); + Assert.assertEquals("Wrong action type", 23, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action type", 64, out.readUnsignedByte()); + out.skipBytes(3); + Assert.assertEquals("Wrong instruction type", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong instruction length", 24, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertEquals("Wrong action type", 17, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong action ethertype", 14, out.readUnsignedShort()); + out.skipBytes(2); + Assert.assertEquals("Wrong action type", 27, out.readUnsignedShort()); + Assert.assertEquals("Wrong action length", 8, out.readUnsignedShort()); + out.skipBytes(4); + Assert.assertTrue("Not all data were read", out.readableBytes() == 0); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java new file mode 100644 index 0000000000..e27c049aaa --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializer02Test.java @@ -0,0 +1,866 @@ +/* + * 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.util; + +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.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; +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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTha; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ArpTpa; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv4Type; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Code; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Icmpv6Type; +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.IpDscp; +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.Ipv4Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Exthdr; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdSll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTarget; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTll; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Metadata; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsBos; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsLabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MplsTc; +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.PbbIsid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.SctpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TcpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.TunnelId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpDst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.UdpSrc; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanPcp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid; +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.ArpOpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpShaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpSpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpThaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ArpTpaCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv4TypeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6CodeCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Icmpv6TypeCaseBuilder; +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.InPortCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.IpDscpCaseBuilder; +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.IpProtoCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv4SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6ExthdrCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6FlabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdSllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTargetCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTllCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MetadataCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsBosCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsLabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.MplsTcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.PbbIsidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.SctpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TcpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.TunnelIdCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpDstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.UdpSrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanPcpCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.op._case.ArpOpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.sha._case.ArpShaBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.spa._case.ArpSpaBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tha._case.ArpThaBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.arp.tpa._case.ArpTpaBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.code._case.Icmpv4CodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv4.type._case.Icmpv4TypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.code._case.Icmpv6CodeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.icmpv6.type._case.Icmpv6TypeBuilder; +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.in.port._case.InPortBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ip.dscp._case.IpDscpBuilder; +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.entry.value.grouping.match.entry.value.ip.proto._case.IpProtoBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.dst._case.Ipv4DstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4SrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.dst._case.Ipv6DstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.exthdr._case.Ipv6ExthdrBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.flabel._case.Ipv6FlabelBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.sll._case.Ipv6NdSllBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.target._case.Ipv6NdTargetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.tll._case.Ipv6NdTllBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6SrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.metadata._case.MetadataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.bos._case.MplsBosBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.label._case.MplsLabelBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.mpls.tc._case.MplsTcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.pbb.isid._case.PbbIsidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.dst._case.SctpDstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.sctp.src._case.SctpSrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.dst._case.TcpDstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tcp.src._case.TcpSrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.tunnel.id._case.TunnelIdBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.dst._case.UdpDstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.udp.src._case.UdpSrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.pcp._case.VlanPcpBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder; +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; + +/** + * @author michal.polkorab + * + */ +public class OF13MatchSerializer02Test { + + private SerializerRegistry registry; + private OFSerializer matchSerializer; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + matchSerializer = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Match.class)); + } + + /** + * Testing serialization of match + */ + @Test + public void testEmptyMatch() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + Match match = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong match type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedShort()); + Assert.assertTrue("Wrong padding", out.readableBytes() == 4); + } + + /** + * Testing serialization of match + */ + @Test + public void test() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(InPort.class); + entryBuilder.setHasMask(false); + InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder(); + InPortBuilder inPortBuilder = new InPortBuilder(); + inPortBuilder.setPortNumber(new PortNumber(42L)); + inPortCaseBuilder.setInPort(inPortBuilder.build()); + entryBuilder.setMatchEntryValue(inPortCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(InPhyPort.class); + entryBuilder.setHasMask(false); + InPhyPortCaseBuilder inPhyPortCaseBuilder = new InPhyPortCaseBuilder(); + InPhyPortBuilder inPhyPortBuilder = new InPhyPortBuilder(); + inPhyPortBuilder.setPortNumber(new PortNumber(43L)); + inPhyPortCaseBuilder.setInPhyPort(inPhyPortBuilder.build()); + entryBuilder.setMatchEntryValue(inPhyPortCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Metadata.class); + entryBuilder.setHasMask(true); + MetadataCaseBuilder metaCaseBuilder = new MetadataCaseBuilder(); + MetadataBuilder metadataBuilder = new MetadataBuilder(); + metadataBuilder.setMetadata(new byte[]{0,0,0,0,0,0,0,1}); + metadataBuilder.setMask(new byte[]{0,0,0,0,0,0,0,2}); + metaCaseBuilder.setMetadata(metadataBuilder.build()); + entryBuilder.setMatchEntryValue(metaCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(EthDst.class); + entryBuilder.setHasMask(true); + EthDstCaseBuilder ethDstCaseBuilder = new EthDstCaseBuilder(); + EthDstBuilder ethDstBuilder = new EthDstBuilder(); + ethDstBuilder.setMacAddress(new MacAddress("01:00:03:00:00:06")); + ethDstBuilder.setMask(new byte[]{0,0,0,0,0,5}); + ethDstCaseBuilder.setEthDst(ethDstBuilder.build()); + entryBuilder.setMatchEntryValue(ethDstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(EthSrc.class); + entryBuilder.setHasMask(true); + EthSrcCaseBuilder ethSrcCaseBuilder = new EthSrcCaseBuilder(); + EthSrcBuilder ethSrcBuilder = new EthSrcBuilder(); + ethSrcBuilder.setMacAddress(new MacAddress("04:00:02:00:00:08")); + ethSrcBuilder.setMask(new byte[]{0,0,0,0,0,2}); + ethSrcCaseBuilder.setEthSrc(ethSrcBuilder.build()); + entryBuilder.setMatchEntryValue(ethSrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(EthType.class); + entryBuilder.setHasMask(false); + EthTypeCaseBuilder ethTypeCaseBuilder = new EthTypeCaseBuilder(); + EthTypeBuilder ethTypeBuilder = new EthTypeBuilder(); + ethTypeBuilder.setEthType(new EtherType(46)); + ethTypeCaseBuilder.setEthType(ethTypeBuilder.build()); + entryBuilder.setMatchEntryValue(ethTypeCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(VlanVid.class); + entryBuilder.setHasMask(true); + VlanVidCaseBuilder vlanVidCaseBuilder = new VlanVidCaseBuilder(); + VlanVidBuilder vlanVidBuilder = new VlanVidBuilder(); + vlanVidBuilder.setVlanVid(45); + vlanVidBuilder.setCfiBit(true); + vlanVidBuilder.setMask(new byte[]{0,9}); + vlanVidCaseBuilder.setVlanVid(vlanVidBuilder.build()); + entryBuilder.setMatchEntryValue(vlanVidCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(VlanPcp.class); + entryBuilder.setHasMask(false); + VlanPcpCaseBuilder vlanPcpCaseBuilder = new VlanPcpCaseBuilder(); + VlanPcpBuilder vlanPcpBuilder = new VlanPcpBuilder(); + vlanPcpBuilder.setVlanPcp((short) 14); + vlanPcpCaseBuilder.setVlanPcp(vlanPcpBuilder.build()); + entryBuilder.setMatchEntryValue(vlanPcpCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(IpDscp.class); + entryBuilder.setHasMask(false); + IpDscpCaseBuilder ipDscpCaseBuilder = new IpDscpCaseBuilder(); + IpDscpBuilder ipDscpBuilder = new IpDscpBuilder(); + ipDscpBuilder.setDscp(new Dscp((short) 48)); + ipDscpCaseBuilder.setIpDscp(ipDscpBuilder.build()); + entryBuilder.setMatchEntryValue(ipDscpCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(IpEcn.class); + entryBuilder.setHasMask(false); + IpEcnCaseBuilder ipEcnCaseBuilder = new IpEcnCaseBuilder(); + IpEcnBuilder ipEcnBuilder = new IpEcnBuilder(); + ipEcnBuilder.setEcn((short) 49); + ipEcnCaseBuilder.setIpEcn(ipEcnBuilder.build()); + entryBuilder.setMatchEntryValue(ipEcnCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(IpProto.class); + entryBuilder.setHasMask(false); + IpProtoCaseBuilder ipProtoCaseBuilder = new IpProtoCaseBuilder(); + IpProtoBuilder ipProtoBuilder = new IpProtoBuilder(); + ipProtoBuilder.setProtocolNumber((short) 50); + ipProtoCaseBuilder.setIpProto(ipProtoBuilder.build()); + entryBuilder.setMatchEntryValue(ipProtoCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv4Src.class); + entryBuilder.setHasMask(true); + Ipv4SrcCaseBuilder ipv4SrcCaseBuilder = new Ipv4SrcCaseBuilder(); + Ipv4SrcBuilder ipv4SrcBuilder = new Ipv4SrcBuilder(); + ipv4SrcBuilder.setIpv4Address(new Ipv4Address("10.0.0.1")); + ipv4SrcBuilder.setMask(new byte[]{0,0,0,14}); + ipv4SrcCaseBuilder.setIpv4Src(ipv4SrcBuilder.build()); + entryBuilder.setMatchEntryValue(ipv4SrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv4Dst.class); + entryBuilder.setHasMask(true); + Ipv4DstCaseBuilder ipv4DstCaseBuilder = new Ipv4DstCaseBuilder(); + Ipv4DstBuilder ipv4DstBuilder = new Ipv4DstBuilder(); + ipv4DstBuilder.setIpv4Address(new Ipv4Address("10.0.0.2")); + ipv4DstBuilder.setMask(new byte[]{0,0,0,15}); + ipv4DstCaseBuilder.setIpv4Dst(ipv4DstBuilder.build()); + entryBuilder.setMatchEntryValue(ipv4DstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(TcpSrc.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6653)); + tcpSrcCaseBuilder.setTcpSrc(tcpSrcBuilder.build()); + entryBuilder.setMatchEntryValue(tcpSrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(TcpDst.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6654)); + tcpDstCaseBuilder.setTcpDst(tcpDstBuilder.build()); + entryBuilder.setMatchEntryValue(tcpDstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(UdpSrc.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6655)); + udpSrcCaseBuilder.setUdpSrc(udpSrcBuilder.build()); + entryBuilder.setMatchEntryValue(udpSrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(UdpDst.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6656)); + udpDstCaseBuilder.setUdpDst(udpDstBuilder.build()); + entryBuilder.setMatchEntryValue(udpDstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(SctpSrc.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6657)); + sctpSrcCaseBuilder.setSctpSrc(sctpSrcBuilder.build()); + entryBuilder.setMatchEntryValue(sctpSrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(SctpDst.class); + entryBuilder.setHasMask(false); + 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.rev130715.PortNumber(6658)); + sctpDstCaseBuilder.setSctpDst(sctpDstBuilder.build()); + entryBuilder.setMatchEntryValue(sctpDstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Icmpv4Type.class); + entryBuilder.setHasMask(false); + Icmpv4TypeCaseBuilder icmpv4TypeCaseBuilder = new Icmpv4TypeCaseBuilder(); + Icmpv4TypeBuilder icmpv4TypeBuilder = new Icmpv4TypeBuilder(); + icmpv4TypeBuilder.setIcmpv4Type((short) 51); + icmpv4TypeCaseBuilder.setIcmpv4Type(icmpv4TypeBuilder.build()); + entryBuilder.setMatchEntryValue(icmpv4TypeCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Icmpv4Code.class); + entryBuilder.setHasMask(false); + Icmpv4CodeCaseBuilder icmpv4CodeCaseBuilder = new Icmpv4CodeCaseBuilder(); + Icmpv4CodeBuilder icmpv4CodeBuilder = new Icmpv4CodeBuilder(); + icmpv4CodeBuilder.setIcmpv4Code((short) 52); + icmpv4CodeCaseBuilder.setIcmpv4Code(icmpv4CodeBuilder.build()); + entryBuilder.setMatchEntryValue(icmpv4CodeCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(ArpOp.class); + entryBuilder.setHasMask(false); + ArpOpCaseBuilder arpOpCaseBuilder = new ArpOpCaseBuilder(); + ArpOpBuilder arpOpBuilder = new ArpOpBuilder(); + arpOpBuilder.setOpCode(53); + arpOpCaseBuilder.setArpOp(arpOpBuilder.build()); + entryBuilder.setMatchEntryValue(arpOpCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(ArpSpa.class); + entryBuilder.setHasMask(true); + ArpSpaCaseBuilder arpSpaCaseBuilder = new ArpSpaCaseBuilder(); + ArpSpaBuilder arpSpaBuilder = new ArpSpaBuilder(); + arpSpaBuilder.setIpv4Address(new Ipv4Address("10.0.0.4")); + arpSpaBuilder.setMask(new byte[]{0,0,0,16}); + arpSpaCaseBuilder.setArpSpa(arpSpaBuilder.build()); + entryBuilder.setMatchEntryValue(arpSpaCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(ArpTpa.class); + entryBuilder.setHasMask(true); + ArpTpaCaseBuilder arpTpaCaseBuilder = new ArpTpaCaseBuilder(); + ArpTpaBuilder arpTpaBuilder = new ArpTpaBuilder(); + arpTpaBuilder.setIpv4Address(new Ipv4Address("10.0.0.5")); + arpTpaBuilder.setMask(new byte[]{0,0,0,17}); + arpTpaCaseBuilder.setArpTpa(arpTpaBuilder.build()); + entryBuilder.setMatchEntryValue(arpTpaCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(ArpSha.class); + entryBuilder.setHasMask(true); + ArpShaCaseBuilder arpShaCaseBuilder = new ArpShaCaseBuilder(); + ArpShaBuilder arpShaBuilder = new ArpShaBuilder(); + arpShaBuilder.setMacAddress(new MacAddress("00:01:02:03:04:05")); + arpShaBuilder.setMask(new byte[]{0,0,4,0,0,6}); + arpShaCaseBuilder.setArpSha(arpShaBuilder.build()); + entryBuilder.setMatchEntryValue(arpShaCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(ArpTha.class); + entryBuilder.setHasMask(true); + ArpThaCaseBuilder arpThaCaseBuilder = new ArpThaCaseBuilder(); + ArpThaBuilder arpThaBuilder = new ArpThaBuilder(); + arpThaBuilder.setMacAddress(new MacAddress("00:00:00:00:00:03")); + arpThaBuilder.setMask(new byte[]{0,0,6,0,0,4}); + arpThaCaseBuilder.setArpTha(arpThaBuilder.build()); + entryBuilder.setMatchEntryValue(arpThaCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6Src.class); + entryBuilder.setHasMask(true); + Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("0:0:0:0:0:0:0:1")); + ipv6SrcBuilder.setMask(new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6Dst.class); + entryBuilder.setHasMask(true); + Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + Ipv6DstBuilder ipv6DstBuilder = new Ipv6DstBuilder(); + ipv6DstBuilder.setIpv6Address(new Ipv6Address("0:0:1:0:1:0:0:1")); + ipv6DstBuilder.setMask(new byte[]{0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1}); + ipv6DstCaseBuilder.setIpv6Dst(ipv6DstBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6Flabel.class); + entryBuilder.setHasMask(false); + Ipv6FlabelCaseBuilder ipv6FlabelCaseBuilder = new Ipv6FlabelCaseBuilder(); + Ipv6FlabelBuilder ipv6FlabelBuilder = new Ipv6FlabelBuilder(); + ipv6FlabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(58L)); + ipv6FlabelCaseBuilder.setIpv6Flabel(ipv6FlabelBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6FlabelCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Icmpv6Type.class); + entryBuilder.setHasMask(false); + Icmpv6TypeCaseBuilder icmpv6TypeCaseBuilder = new Icmpv6TypeCaseBuilder(); + Icmpv6TypeBuilder icmpv6TypeBuilder = new Icmpv6TypeBuilder(); + icmpv6TypeBuilder.setIcmpv6Type((short) 59); + icmpv6TypeCaseBuilder.setIcmpv6Type(icmpv6TypeBuilder.build()); + entryBuilder.setMatchEntryValue(icmpv6TypeCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Icmpv6Code.class); + entryBuilder.setHasMask(false); + Icmpv6CodeCaseBuilder Icmpv6CodeCaseBuilder = new Icmpv6CodeCaseBuilder(); + Icmpv6CodeBuilder Icmpv6CodeBuilder = new Icmpv6CodeBuilder(); + Icmpv6CodeBuilder.setIcmpv6Code((short) 60); + Icmpv6CodeCaseBuilder.setIcmpv6Code(Icmpv6CodeBuilder.build()); + entryBuilder.setMatchEntryValue(Icmpv6CodeCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6NdTarget.class); + entryBuilder.setHasMask(false); + Ipv6NdTargetCaseBuilder ipv6NdTargetCaseBuilder = new Ipv6NdTargetCaseBuilder(); + Ipv6NdTargetBuilder ipv6NdTargetBuilder = new Ipv6NdTargetBuilder(); + ipv6NdTargetBuilder.setIpv6Address(new Ipv6Address("F:0:0::0:0:0:1")); + ipv6NdTargetCaseBuilder.setIpv6NdTarget(ipv6NdTargetBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6NdTargetCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6NdSll.class); + entryBuilder.setHasMask(false); + Ipv6NdSllCaseBuilder ipv6NdSllCaseBuilder = new Ipv6NdSllCaseBuilder(); + Ipv6NdSllBuilder ipv6NdSllBuilder = new Ipv6NdSllBuilder(); + ipv6NdSllBuilder.setMacAddress(new MacAddress("01:00:03:00:00:06")); + ipv6NdSllCaseBuilder.setIpv6NdSll(ipv6NdSllBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6NdSllCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6NdTll.class); + entryBuilder.setHasMask(false); + Ipv6NdTllCaseBuilder ipv6NdTllCaseBuilder = new Ipv6NdTllCaseBuilder(); + Ipv6NdTllBuilder ipv6NdTllBuilder = new Ipv6NdTllBuilder(); + ipv6NdTllBuilder.setMacAddress(new MacAddress("04:00:02:00:00:08")); + ipv6NdTllCaseBuilder.setIpv6NdTll(ipv6NdTllBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6NdTllCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(MplsLabel.class); + entryBuilder.setHasMask(false); + MplsLabelCaseBuilder mplsLabelCaseBuilder = new MplsLabelCaseBuilder(); + MplsLabelBuilder mplsLabelBuilder = new MplsLabelBuilder(); + mplsLabelBuilder.setMplsLabel(61L); + mplsLabelCaseBuilder.setMplsLabel(mplsLabelBuilder.build()); + entryBuilder.setMatchEntryValue(mplsLabelCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(MplsTc.class); + entryBuilder.setHasMask(false); + MplsTcCaseBuilder MplsTcCaseBuilder = new MplsTcCaseBuilder(); + MplsTcBuilder MplsTcBuilder = new MplsTcBuilder(); + MplsTcBuilder.setTc((short) 62); + MplsTcCaseBuilder.setMplsTc(MplsTcBuilder.build()); + entryBuilder.setMatchEntryValue(MplsTcCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(MplsBos.class); + entryBuilder.setHasMask(false); + MplsBosCaseBuilder MplsBosCaseBuilder = new MplsBosCaseBuilder(); + MplsBosBuilder MplsBosBuilder = new MplsBosBuilder(); + MplsBosBuilder.setBos(true); + MplsBosCaseBuilder.setMplsBos(MplsBosBuilder.build()); + entryBuilder.setMatchEntryValue(MplsBosCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(PbbIsid.class); + entryBuilder.setHasMask(true); + PbbIsidCaseBuilder pbbIsidCaseBuilder = new PbbIsidCaseBuilder(); + PbbIsidBuilder pbbIsidBuilder = new PbbIsidBuilder(); + pbbIsidBuilder.setIsid(64L); + pbbIsidBuilder.setMask(new byte[]{0,1,2}); + pbbIsidCaseBuilder.setPbbIsid(pbbIsidBuilder.build()); + entryBuilder.setMatchEntryValue(pbbIsidCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(TunnelId.class); + entryBuilder.setHasMask(true); + TunnelIdCaseBuilder tunnelIdCaseBuilder = new TunnelIdCaseBuilder(); + TunnelIdBuilder tunnelIdBuilder = new TunnelIdBuilder(); + tunnelIdBuilder.setTunnelId(new byte[]{0,0,0,0,0,0,0,1}); + tunnelIdBuilder.setMask(new byte[]{0,0,0,0,0,0,0,2}); + tunnelIdCaseBuilder.setTunnelId(tunnelIdBuilder.build()); + entryBuilder.setMatchEntryValue(tunnelIdCaseBuilder.build()); + entries.add(entryBuilder.build()); + entryBuilder = new MatchEntryBuilder(); + entryBuilder.setOxmClass(OpenflowBasicClass.class); + entryBuilder.setOxmMatchField(Ipv6Exthdr.class); + entryBuilder.setHasMask(true); + Ipv6ExthdrCaseBuilder ipv6ExthdrCaseBuilder = new Ipv6ExthdrCaseBuilder(); + Ipv6ExthdrBuilder ipv6ExthdrBuilder = new Ipv6ExthdrBuilder(); + ipv6ExthdrBuilder.setPseudoField(new Ipv6ExthdrFlags(true, false, true, + false, true, false, true, false, true)); + ipv6ExthdrBuilder.setMask(new byte[]{0,2}); + ipv6ExthdrCaseBuilder.setIpv6Exthdr(ipv6ExthdrBuilder.build()); + entryBuilder.setMatchEntryValue(ipv6ExthdrCaseBuilder.build()); + entries.add(entryBuilder.build()); + + + builder.setMatchEntry(entries); + Match match = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong match type", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong match length", 424, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 0, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 42, out.readUnsignedInt()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 43, out.readUnsignedInt()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 5, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 1L, out.readLong()); + Assert.assertEquals("Wrong match entry mask", 2L, out.readLong()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 7, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 12, out.readUnsignedByte()); + byte[] array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{1,0,3,0,0,6}, array); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,0,0,5}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 9, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 12, out.readUnsignedByte()); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{4,0,2,0,0,8}, array); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,0,0,2}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 10, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 46, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 13, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 4141, out.readUnsignedShort()); + array = new byte[2]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,9}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 14, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 14, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 48, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 18, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 49, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 20, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 50, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 23, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 8, out.readUnsignedByte()); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{10,0,0,1}, array); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,14}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 25, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 8, out.readUnsignedByte()); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{10,0,0,2}, array); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,15}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 26, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6653, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 28, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6654, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 30, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6655, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 32, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6656, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 34, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6657, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 36, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 6658, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 38, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 51, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 40, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 52, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 42, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 53, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 45, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 8, out.readUnsignedByte()); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{10,0,0,4}, array); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,16}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 47, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 8, out.readUnsignedByte()); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{10,0,0,5}, array); + array = new byte[4]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,17}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 49, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 12, out.readUnsignedByte()); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,1,2,3,4,5}, array); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,4,0,0,6}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 51, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 12, out.readUnsignedByte()); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,0,0,0,0,3}, array); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,6,0,0,4}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 53, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 32, out.readUnsignedByte()); + array = new byte[16]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, array); + array = new byte[16]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 55, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 32, out.readUnsignedByte()); + array = new byte[16]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1}, array); + array = new byte[16]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 56, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); //8, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 58, out.readUnsignedInt()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 58, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 59, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 60, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 60, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 62, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 16, out.readUnsignedByte()); + array = new byte[16]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 64, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 6, out.readUnsignedByte()); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{1,0,3,0,0,6}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 66, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 6, out.readUnsignedByte()); + array = new byte[6]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{4,0,2,0,0,8}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 68, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 61, out.readUnsignedInt()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 70, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 62, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 72, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 75, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 6, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 64, out.readUnsignedMedium()); + array = new byte[3]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry mask", new byte[]{0,1,2}, array); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 77, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 1L, out.readLong()); + Assert.assertEquals("Wrong match entry mask", 2L, out.readLong()); + Assert.assertEquals("Wrong match entry class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong match entry field & hasMask", 79, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry length", 4, out.readUnsignedByte()); + Assert.assertEquals("Wrong match entry value", 358, out.readUnsignedShort()); + array = new byte[2]; + out.readBytes(array); + Assert.assertArrayEquals("Wrong match entry value", new byte[]{0,2}, array); + Assert.assertTrue("Wrong padding", out.readableBytes() == 0); + } + +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java new file mode 100644 index 0000000000..0c2a6aa0dd --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OF13MatchSerializerTest.java @@ -0,0 +1,400 @@ +/* + * 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.util; + +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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.StandardMatchType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv4Src; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Dst; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6Flabel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.Ipv6NdTarget; +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; +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.Ipv4SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6DstCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6FlabelCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6NdTargetCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.Ipv6SrcCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv4.src._case.Ipv4SrcBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.dst._case.Ipv6DstBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.flabel._case.Ipv6FlabelBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.nd.target._case.Ipv6NdTargetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.ipv6.src._case.Ipv6SrcBuilder; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * + */ +public class OF13MatchSerializerTest { + + private static final Logger LOG = LoggerFactory + .getLogger(OF13MatchSerializerTest.class); + private SerializerRegistry registry; + private OFSerializer matchSerializer; + + /** + * Initializes serializer table and stores correct factory in field + */ + @Before + public void startUp() { + registry = new SerializerRegistryImpl(); + registry.init(); + matchSerializer = registry.getSerializer( + new MessageTypeKey<>(EncodeConstants.OF13_VERSION_ID, Match.class)); + } + + /** + * Test for correct serialization of Ipv4Address match entry + */ + @Test + public void testIpv4Src() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv4Src.class); + entriesBuilder.setHasMask(false); + Ipv4SrcCaseBuilder ipv4SrcCaseBuilder = new Ipv4SrcCaseBuilder(); + Ipv4SrcBuilder ipv4SrcBuilder = new Ipv4SrcBuilder(); + ipv4SrcBuilder.setIpv4Address(new Ipv4Address("1.2.3.4")); + ipv4SrcCaseBuilder.setIpv4Src(ipv4SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv4SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + builder.setMatchEntry(entries); + Match match = builder.build(); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 22, out.readUnsignedByte()); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + Assert.assertEquals("Wrong ip address (first number)", 1, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip address (second number)", 2, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip address (third number)", 3, out.readUnsignedByte()); + Assert.assertEquals("Wrong ip address (fourth number)", 4, out.readUnsignedByte()); + } + + /** + * Test for correct serialization of Ipv6Address match entry + */ + @Test + public void testIpv6Various() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + // ipv6 match entry with correct Ipv6 address + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(false); + Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("1:2:3:4:5:6:7:8")); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + // ipv6 match entry with abbreviated Ipv6 address + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6NdTarget.class); + entriesBuilder.setHasMask(false); + Ipv6NdTargetCaseBuilder ipv6NdTargetCaseBuilder = new Ipv6NdTargetCaseBuilder(); + Ipv6NdTargetBuilder ipv6NdTargetBuilder = new Ipv6NdTargetBuilder(); + ipv6NdTargetBuilder.setIpv6Address(new Ipv6Address("1:2::6:7:8")); + ipv6NdTargetCaseBuilder.setIpv6NdTarget(ipv6NdTargetBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6NdTargetCaseBuilder.build()); + entries.add(entriesBuilder.build()); + // ipv6 match entry with abbreviated Ipv6 address + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(false); + Ipv6DstCaseBuilder ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + Ipv6DstBuilder ipv6DstBuilder = new Ipv6DstBuilder(); + ipv6DstBuilder.setIpv6Address(new Ipv6Address("1::8")); + ipv6DstCaseBuilder.setIpv6Dst(ipv6DstBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + // ipv6 match entry with abbreviated Ipv6 address + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(false); + ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + ipv6DstBuilder = new Ipv6DstBuilder(); + ipv6DstBuilder.setIpv6Address(new Ipv6Address("::1")); + ipv6DstCaseBuilder.setIpv6Dst(ipv6DstBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + // ipv6 match entry with abbreviated Ipv6 address + entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Dst.class); + entriesBuilder.setHasMask(false); + ipv6DstCaseBuilder = new Ipv6DstCaseBuilder(); + ipv6DstBuilder = new Ipv6DstBuilder(); + ipv6DstBuilder.setIpv6Address(new Ipv6Address("::")); + ipv6DstCaseBuilder.setIpv6Dst(ipv6DstBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6DstCaseBuilder.build()); + entries.add(entriesBuilder.build()); + builder.setMatchEntry(entries); + Match match = builder.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 52, out.readUnsignedByte()); + Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 3, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 5, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 62, out.readUnsignedByte()); + Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 2, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 6, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 7, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte()); + Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 8, out.readUnsignedShort()); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte()); + Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 1, out.readUnsignedShort()); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 54, out.readUnsignedByte()); + Assert.assertEquals("Wrong entry length", 16, out.readUnsignedByte()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong ipv6 address", 0, out.readUnsignedShort()); + } + + /** + * Test for correct serialization of incorrect Ipv6Address match entry + */ + @Test(expected=IllegalArgumentException.class) + public void testIpv6Incorrect() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + // ipv6 match entry with incorrect Ipv6 address + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Src.class); + entriesBuilder.setHasMask(false); + Ipv6SrcCaseBuilder ipv6SrcCaseBuilder = new Ipv6SrcCaseBuilder(); + Ipv6SrcBuilder ipv6SrcBuilder = new Ipv6SrcBuilder(); + ipv6SrcBuilder.setIpv6Address(new Ipv6Address("1:2::::8")); + ipv6SrcCaseBuilder.setIpv6Src(ipv6SrcBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6SrcCaseBuilder.build()); + entries.add(entriesBuilder.build()); + builder.setMatchEntry(entries); + Match match = builder.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + } + + /** + * Test for correct serialization of Ipv4Address match entry + */ + @Test + public void testIpv6Flabel() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, false, null); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 56, out.readUnsignedByte()); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + byte[] label = new byte[4]; + out.readBytes(label); + + LOG.debug("label: {}", ByteBufUtils.bytesToHexString(label)); + Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label); + } + + /** + * Test for correct serialization of Ipv4Address match entry + */ + @Test + public void testIpv6FlabelWithMask() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0, 1, 2, 3}); + + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong type", 1, out.readUnsignedShort()); + out.skipBytes(EncodeConstants.SIZE_OF_SHORT_IN_BYTES); + Assert.assertEquals("Wrong class", 0x8000, out.readUnsignedShort()); + Assert.assertEquals("Wrong field and mask", 57, out.readUnsignedByte()); + out.skipBytes(EncodeConstants.SIZE_OF_BYTE_IN_BYTES); + byte[] label = new byte[4]; + out.readBytes(label); + Assert.assertArrayEquals("Wrong ipv6FLabel", new byte[]{0, 0x0f, (byte) 0x9e, (byte) 0x8d}, label); + byte[] mask = new byte[4]; + out.readBytes(mask); + Assert.assertArrayEquals("Wrong ipv6FLabel mask", new byte[]{0, 1, 2, 3}, mask); + } + + /** + * Test for correct serialization of Ipv4Address match entry with wrong mask + */ + @Test + public void testIpv6FlabelWithMaskBad() { + Match match = buildIpv6FLabelMatch(0x0f9e8dL, true, new byte[]{0x0c, 0x7b, 0x6a}); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + try { + matchSerializer.serialize(match, out); + Assert.fail("incorrect length of mask ignored"); + } catch (IllegalArgumentException e) { + //expected + } + } + + /** + * @param labelValue ipv6 flow label + * @param hasMask + * @param mask ipv6 flow label mask + * @return + */ + private static Match buildIpv6FLabelMatch(long labelValue, boolean hasMask, byte[] mask) { + MatchBuilder builder = new MatchBuilder(); + builder.setType(OxmMatchType.class); + List entries = new ArrayList<>(); + MatchEntryBuilder entriesBuilder = new MatchEntryBuilder(); + entriesBuilder.setOxmClass(OpenflowBasicClass.class); + entriesBuilder.setOxmMatchField(Ipv6Flabel.class); + entriesBuilder.setHasMask(hasMask); + Ipv6FlabelCaseBuilder ipv6FlabelCaseBuilder = new Ipv6FlabelCaseBuilder(); + Ipv6FlabelBuilder ipv6FlabelBuilder = new Ipv6FlabelBuilder(); + ipv6FlabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(labelValue)); + ipv6FlabelBuilder.setMask(mask); + ipv6FlabelCaseBuilder.setIpv6Flabel(ipv6FlabelBuilder.build()); + entriesBuilder.setMatchEntryValue(ipv6FlabelCaseBuilder.build()); + entries.add(entriesBuilder.build()); + builder.setMatchEntry(entries); + Match match = builder.build(); + return match; + } + + /** + * Test Standard match type + */ + @Test + public void testStandardMatchType() { + MatchBuilder builder = new MatchBuilder(); + builder.setType(StandardMatchType.class); + Match match = builder.build(); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + matchSerializer.serialize(match, out); + + Assert.assertEquals("Wrong match type", 0, out.readUnsignedShort()); + Assert.assertEquals("Wrong match length", 4, out.readUnsignedShort()); + Assert.assertEquals("Wrong padding", 0, out.readUnsignedInt()); + Assert.assertEquals("Unexpected data", 0, out.readableBytes()); + } + + /** + * Test serialize experimenter match entry - with no experimenter + * match entry serializer registered + */ + @Test(expected=IllegalStateException.class) + public void testSerializeExperimenterMatchEntry() { + List entries = new ArrayList<>(); + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(ExperimenterClass.class); + builder.setOxmMatchField(OxmMatchFieldClass.class); + builder.setHasMask(true); + ExperimenterIdCaseBuilder caseBuilder = new ExperimenterIdCaseBuilder(); + ExperimenterBuilder expBuilder = new ExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(42L)); + caseBuilder.setExperimenter(expBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + entries.add(builder.build()); + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + + ((OF13MatchSerializer) matchSerializer).serializeMatchEntries(entries, out); + } + + private class OxmMatchFieldClass extends MatchField { + // only for testing purposes + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtilsTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtilsTest.java new file mode 100644 index 0000000000..4a1ceb7858 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/OpenflowUtilsTest.java @@ -0,0 +1,68 @@ +/* + * 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.impl.util; + +import org.junit.Assert; +import org.junit.Test; +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; + +/** + * @author michal.polkorab + * + */ +public class OpenflowUtilsTest { + + /** + * Tests {@link OpenflowUtils#createPortState(long)} + */ + @Test + public void testPortState() { + PortStateV10 state = OpenflowUtils.createPortState(512L); + Assert.assertEquals("Wrong port state", + new PortStateV10(false, false, false, false, true, false, true, false), state); + + state = OpenflowUtils.createPortState(1793L); + Assert.assertEquals("Wrong port state", + new PortStateV10(false, true, false, true, true, true, false, true), state); + + state = OpenflowUtils.createPortState(1L); + Assert.assertEquals("Wrong port state", + new PortStateV10(false, true, false, false, false, false, true, false), state); + } + + /** + * Tests {@link OpenflowUtils#createPortConfig(long)} + */ + @Test + public void testPortConfig() { + PortConfigV10 config = OpenflowUtils.createPortConfig(127L); + Assert.assertEquals("Wrong port config", + new PortConfigV10(true, true, true, true, true, true, true), config); + + config = OpenflowUtils.createPortConfig(0L); + Assert.assertEquals("Wrong port config", + new PortConfigV10(false, false, false, false, false, false, false), config); + } + + /** + * Tests {@link OpenflowUtils#createPortFeatures(long)} + */ + @Test + public void testPortFeatures() { + PortFeaturesV10 features = OpenflowUtils.createPortFeatures(4095L); + Assert.assertEquals("Wrong port features", new PortFeaturesV10(true, true, true, true, true, true, true, + true, true, true, true, true), features); + + features = OpenflowUtils.createPortFeatures(0L); + Assert.assertEquals("Wrong port features", new PortFeaturesV10(false, false, false, false, false, false, + false, false, false, false, false, false), features); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactoryTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactoryTest.java new file mode 100644 index 0000000000..c95541c9c5 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/util/TypeKeyMakerFactoryTest.java @@ -0,0 +1,176 @@ +/* + * 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.impl.util; + +import org.junit.Assert; +import org.junit.Test; +import org.opendaylight.openflowjava.protocol.api.keys.ActionSerializerKey; +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.openflowjava.protocol.api.util.EncodeConstants; +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.action.rev150203.ExperimenterActionSubType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.action.grouping.action.choice.CopyTtlInCaseBuilder; +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.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.ClearActionsCase; +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.GotoTableCase; +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.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.ExperimenterId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.ExperimenterClass; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort; +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.match.entries.grouping.MatchEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder; + +/** + * @author michal.polkorab + * + */ +public class TypeKeyMakerFactoryTest { + + /** + * Tests {@link TypeKeyMakerFactory#createActionKeyMaker(short)} + */ + @Test + public void testActionKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + ActionBuilder builder = new ActionBuilder(); + builder.setActionChoice(new OutputActionCaseBuilder().build()); + Action action = builder.build(); + MessageTypeKey key = keyMaker.make(action); + + Assert.assertNotNull("Null key", key); + Assert.assertEquals("Wrong key", new ActionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, + OutputActionCase.class, null), key); + } + + /** + * Tests {@link TypeKeyMakerFactory#createActionKeyMaker(short)} + */ + @Test + public void testExperimenterActionKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createActionKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder builder = new ActionBuilder(); + builder.setExperimenterId(new ExperimenterId(42L)); + builder.setActionChoice(new CopyTtlInCaseBuilder().build()); + Action action = builder.build(); + MessageTypeKey key = keyMaker.make(action); + + Assert.assertNotNull("Null key", key); + Assert.assertEquals("Wrong key", new ActionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, + CopyTtlInCase.class, 42L), key); + } + + /** + * Tests {@link TypeKeyMakerFactory#createInstructionKeyMaker(short)} + */ + @Test + public void testInstructionKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + InstructionBuilder builder = new InstructionBuilder(); + builder.setInstructionChoice(new GotoTableCaseBuilder().build()); + Instruction instruction = builder.build(); + MessageTypeKey key = keyMaker.make(instruction); + + Assert.assertNotNull("Null key", key); + Assert.assertEquals("Wrong key", new InstructionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, + GotoTableCase.class, null), key); + } + + /** + * Tests {@link TypeKeyMakerFactory#createInstructionKeyMaker(short)} + */ + @Test + public void testExperimenterInstructionKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createInstructionKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + InstructionBuilder builder = new InstructionBuilder(); + builder.setExperimenterId(new ExperimenterId(42L)); + builder.setInstructionChoice(new ClearActionsCaseBuilder().build()); + Instruction instruction = builder.build(); + MessageTypeKey key = keyMaker.make(instruction); + + Assert.assertNotNull("Null key", key); + Assert.assertEquals("Wrong key", new InstructionSerializerKey<>(EncodeConstants.OF13_VERSION_ID, + ClearActionsCase.class, 42L), key); + } + + /** + * Tests {@link TypeKeyMakerFactory#createMatchEntriesKeyMaker(short)} + */ + @Test + public void testMatchEntriesKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(OpenflowBasicClass.class); + builder.setOxmMatchField(InPort.class); + builder.setHasMask(true); + MatchEntry entry = builder.build(); + MessageTypeKey key = keyMaker.make(entry); + + Assert.assertNotNull("Null key", key); + MatchEntrySerializerKey comparationKey = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + OpenflowBasicClass.class, InPort.class); + Assert.assertEquals("Wrong key", comparationKey, key); + } + + /** + * Tests {@link TypeKeyMakerFactory#createMatchEntriesKeyMaker(short)} + */ + @Test + public void testExperimenterMatchEntriesKeyMaker() { + TypeKeyMaker keyMaker = TypeKeyMakerFactory.createMatchEntriesKeyMaker(EncodeConstants.OF13_VERSION_ID); + Assert.assertNotNull("Null keyMaker", keyMaker); + + MatchEntryBuilder builder = new MatchEntryBuilder(); + builder.setOxmClass(ExperimenterClass.class); + builder.setOxmMatchField(OxmMatchFieldClass.class); + builder.setHasMask(true); + ExperimenterIdCaseBuilder caseBuilder = new ExperimenterIdCaseBuilder(); + ExperimenterBuilder expBuilder = new ExperimenterBuilder(); + expBuilder.setExperimenter(new ExperimenterId(42L)); + caseBuilder.setExperimenter(expBuilder.build()); + builder.setMatchEntryValue(caseBuilder.build()); + MatchEntry entry = builder.build(); + MessageTypeKey key = keyMaker.make(entry); + + Assert.assertNotNull("Null key", key); + MatchEntrySerializerKey comparationKey = new MatchEntrySerializerKey<>(EncodeConstants.OF13_VERSION_ID, + ExperimenterClass.class, OxmMatchFieldClass.class); + comparationKey.setExperimenterId(42L); + Assert.assertEquals("Wrong key", comparationKey, key); + } + + private class ActionSubtypeClass extends ExperimenterActionSubType { + // only for testing purposes + } + + private class OxmMatchFieldClass extends MatchField { + // only for testing purposes + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java new file mode 100644 index 0000000000..6f2f772cbb --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/statistics/StatisticsCountersTest.java @@ -0,0 +1,137 @@ +/* + * 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.statistics; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * General tests for StatisticsCounters class + * @author madamjak + * + */ +public class StatisticsCountersTest { + + private static final Logger LOG = LoggerFactory.getLogger(StatisticsCountersTest.class); + private StatisticsCounters statCounters; + + /** + * Initialize StatisticsCounters before each test, reset counters + */ + @Before + public void initTest(){ + statCounters = StatisticsCounters.getInstance(); + statCounters.startCounting(false, 0); + } + + /** + * Stop counting after each test + */ + @After + public void tierDown(){ + statCounters.stopCounting(); + } + + /** + * Basic test of increment and reset counters + */ + @Test + public void testCounterAll() { + int testCount = 4; + for(CounterEventTypes cet : CounterEventTypes.values()){ + if(statCounters.isCounterEnabled(cet)){ + incrementCounter(cet,testCount); + Assert.assertEquals("Wrong - bad counter value " + cet, testCount, statCounters.getCounter(cet).getCounterValue()); + } else { + Assert.assertNull("Wrong - not enabled counter give not null value", statCounters.getCounter(cet)); + } + + } + statCounters.resetCounters(); + for(CounterEventTypes cet : CounterEventTypes.values()){ + if(statCounters.isCounterEnabled(cet)){ + Assert.assertEquals("Wrong - bad counter value after reset " + cet, 0, statCounters.getCounter(cet).getCounterValue()); + } + } + } + + /** + * Test to store current and last read value of counter (at least one counter has to be enabled) + */ + @Test + public void testCounterLastRead() { + int testCount = 4; + CounterEventTypes firstEnabledCET = null; + for(CounterEventTypes cet : CounterEventTypes.values()){ + if(statCounters.isCounterEnabled(cet)){ + firstEnabledCET = cet; + break; + } + } + if(firstEnabledCET == null){ + Assert.fail("No counter is enabled"); + } + incrementCounter(firstEnabledCET,testCount); + 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()); + Assert.assertEquals("Wrong - bad last read value.", testCount,statCounters.getCounter(firstEnabledCET).getCounterValue()); + Assert.assertEquals("Wrong - bad last read value.", testCount,statCounters.getCounter(firstEnabledCET).getCounterLastReadValue()); + incrementCounter(firstEnabledCET,testCount); + Assert.assertEquals("Wrong - bad last read value.", testCount,statCounters.getCounter(firstEnabledCET).getCounterLastReadValue()); + Assert.assertEquals("Wrong - bad last read value.", 2*testCount,statCounters.getCounter(firstEnabledCET).getCounterValue()); + } + + /** + * Test start and stop log reporter + */ + @Test + public void testStartStopLogReporter(){ + int testDelay = 10000; + statCounters.startLogReport(testDelay); + Assert.assertTrue("Wrong - logRepoter is not running", statCounters.isRunLogReport()); + Assert.assertEquals("Wrong - bad logReportPeriod", testDelay, statCounters.getLogReportPeriod()); + statCounters.stopLogReport(); + Assert.assertFalse("Wrong - logRepoter is running", statCounters.isRunLogReport()); + statCounters.startLogReport(StatisticsCounters.MINIMAL_LOG_REPORT_PERIOD / 2); + Assert.assertTrue("Wrong - logRepoter is not running", statCounters.isRunLogReport()); + Assert.assertEquals("Wrong - bad logReportPeriod", StatisticsCounters.MINIMAL_LOG_REPORT_PERIOD, statCounters.getLogReportPeriod()); + statCounters.stopCounting(); + Assert.assertFalse("Wrong - logRepoter is running", statCounters.isRunLogReport()); + } + + /** + * Test start log report with bad logReportDealy + */ + @Test(expected = IllegalArgumentException.class) + public void testLogReportBadPeriod(){ + statCounters.startLogReport(0); + } + + /** + * Test to get counter with null key + */ + @Test(expected = IllegalArgumentException.class) + public void testGetCounterbyNull(){ + statCounters.getCounter(null); + } + + private void incrementCounter(CounterEventTypes cet, int count){ + if(!statCounters.isCounterEnabled(cet)){ + return; + } + for(int i = 0; i< count; i++){ + statCounters.incrementCounter(cet); + } + } +} diff --git a/openflowjava/openflow-protocol-impl/src/test/resources/key.bin b/openflowjava/openflow-protocol-impl/src/test/resources/key.bin new file mode 100644 index 0000000000000000000000000000000000000000..439ef0da4626fcf3bbbe2aa8e59b633293c70778 GIT binary patch literal 2063 zcmezO_TO6u1_mZ5W@KPbtw_u*$Vp{jV3e94zEmAZ&oXFYoMyns#-+{1$ik?_B*@6f z%D~dZ*yNFWUTkZ?RI~l=>H!hFi-PJ@SBprg#p!k_Pe`a2QV6@~yeQi}_U+s&Pn$J5 z4~hAdv90av(Uh9ae>cHX~xL{MV!YStcQD16IKO{>D84E?+T$G%h+~k;AVD3GWW&YhbcE+jm&0ZW%(^AaL zaCo+7cWa}f@Utc7FQ-5LTl(RC^Mj*ioNJ`7eAiMAmxbIuY2cY&Zw|bee$3XaAt7BDk0GBL4uM1GuPz{|#|)#lOmofjButPBQ?3kxy z#2uCP+iZkbC+p3M%n&KJIuW26zQj`^+3|y}#v8WZTjuX)VrFDuL^c~3smzWHsW}FW zhx+VJZ!Y(EnU*-qp>6#)=GVKjKK*^P-Yl+ql@iNc9fc!*?p|n8kg>f!FD_6B>Tc1j`XIz}% zt!emf!k)Rs3+!KVFL`e;+icdRkn%=$?^R37XFPnpwZ_lmD#srkvq!1SYo30dw*A6Z z>q$>USgW!oh5hqeeVNaQMM&6$ap|EjoiKMh_RU=Vik*BtW|2hV-umRMD@dawNbCk;E6KUiBEQ1Wp`#h!?r zhl2K9if)|J+`rT39iw*K$-LQLlQW;(;C8?9_r`;_E7X}wS55YZmM!=Bw@%agpg_&la`DRe(`)5#Ec`p+VfLo? zI~~=QaQh!?X3hVQ;_%Sr$WI4tYlqwGO_$7`f24%{sYJrjf1-R=s#=2YD)e_;%=5G1 z+Pc%BO+B|icze0oo7lHT4$e)7gCdToS$^KUHe&Vm?|po``YPt`k1*L=Uc4+Ilp#TF zf9{qUT@uZmKhE-cvaJiuTfg@ayYP*aGy739z6mhn8vx_#7ChsBYC%gQ290xRlJP|i zgdrK9$2mW*q$o3~w1o0pZ)#$I$o0m+Tn`c$^gh6q<)?0T7oW->em<>;t1dd^RZo89 zy(w$Bqpn<&ju4U(v;B8}sdn3*lq(H#_CFu7Fjvk#81v!d=Z}x~+aHj>d;37NB91K2 zbp7sLo<2o|_w)Sazj}UL7cqN^m3)EmhuOPd9{5~z`rfv%qBAldu0?6>Sy-ps{POwv qc}stuIh6S2w!>uE`5C)Rg4>ypp2)oSf7mprl*D`44}9biY9pW48ex z8<#d4BMYMzlOQ7_D+5atW4Yvn%f|g`Cp1&TuWyQzzMQcv^XY+v%}dX%-6&Vdy42}Y zW&Md6=BGC+9-G9G-f{T*-v=}9R>p2pd60GZRFmngy_`j5xr*LNt4#OT)!F5VskSSe zdwe>u_~8G80l5sbjm7epvc_L;@i-Iw+^oUKvF`Kp-8T|FC(dQu?)x$?N}qQz--BbB zp09UpJ!5X-v_RzW*XC;t(I)m87b{L(`qp-Q|KDp@r>L;9zAgZA?x_I z9~(bO`MEFQVIThZiZQ_-Kd;Z$Hmz)N^9l zLmRQG?vR>ZjR%X@$!Tw1Ryr|naXt4hMbo5@zmuvMRjkh}`M7UI;DpW<&G#QhJ)O@s zsXHyMp*mDGh0(|Q-+50h=EfEVrp5*#kEWuH-;QN$_%rE%an3c{^`%DKGD@no-cR2x zX;KoCZg-e-@8r?{{SLNVFH{$#8NIn~*cY&fgDZWf;ntrHj~qBBW^9@D=Bz~iz*@?WHo-ph3UQE;v?Vjnn^Z3&ao!}p~`kPp`aVbeTkog-jGV z=kq^seAlyVjs?S^)VkbSU|_fHyj-E(HaWk5Kkjds!bbBM9(xy7N3467aZAQq?4-8b MR!6VGPUY390E5dNe*gdg literal 0 HcmV?d00001 diff --git a/openflowjava/openflow-protocol-impl/src/test/resources/selfSignedSwitch b/openflowjava/openflow-protocol-impl/src/test/resources/selfSignedSwitch new file mode 100644 index 0000000000000000000000000000000000000000..645ac44243d3a8af51fa012f7879d245d05c1054 GIT binary patch literal 1348 zcmezO_TO6u1_mY|W&~q_;?$h9;>`5C)Rf}#%#!2`poCk&^&f|T^aO(@#vTJcHZE;8 zMixdbCP79z z{vL2FH)cr72==#S)LUgc(PHjlri(wOALuim?f*=E<7+PNT*lcA@mu-6lmw(yh4<-L}h-Y&+z{I!>H?Z#{ZQ!{7(h^Pn5o=`((rK^)eF|8BY8l9%L)92pnUq z5qhQumJAHc$p%f#@jxuQfSHMriHXIvf&YmCHygWFo5wi|7G_okgT@9!ZUas>=1>+k zVWwbjLs0`^5QjsUC%+&yFD0=uCo?^x1SZUmU6>2IFgJE#W>jGVIdNV?69Y2?GebiI zBO`+-FxS$+1j-!@PHbY_0ZiyRuz+I(a^#sB8yWuA2RF)=3TX!2_nM>k=E?JKg4=^^ z-n%dyma}iz7O0l#8tb4G_&d_JH{#d+qhEI!d^66fYKrV-7ByE+kQ;?hjsY#V=I=4^0WMI{&xAO++ilu5aB4XiALW_Kd;kHysq{B zlM=J!+>0KJ$C*SKrY8jSiz;)U*)(Zq)1ucc+#e!jzJi?g{o#VvYqM?do!+xL#%xFU z&dMq4cmJ|_)$}vmhufCDDLpVUyl>Z)NdISr>;jDqTRg=Im0$R1hzV~$&uP?iV%b9* zv8wKnnqG|ui`U6%Z(de9F>i4__b)}$q>sOosu)$Q&n)@4Z$;pQ&K1q~A4WZ$&o-$$ zEv}(DR5gXs$NJxSPc7!gRtAtewrlO0Rieb17@)L6(p79twcpl?#C@I554~EPbX71u zXj7qobZC$7{mwmB+n?xVA1pbf{Ih^p{C3LK>~A|SvX(1(l`mOPwn4?{^H!~D%kwuU zp6UMdurtVJ$FDU{j@`=9tc{kvCOd)GtJS)vX7~U1e-GbY{(AC#)8lfpCs;3g|8BYJ zVnqXa16g32mgQp+V-fki@~qY6YpgvUy*{(v?mKM|ZLgw$k|UV)84ProL@H7mGR;I& zb1vSVr#Pp#c-;qWu?I{dz73Wqi_+Zp9Q~<%o^R5#J)YMMmR^YWQ7f+gl<8W)zE1Om KmC%%2<4FL78zvqA literal 0 HcmV?d00001 diff --git a/openflowjava/openflow-protocol-it/pom.xml b/openflowjava/openflow-protocol-it/pom.xml new file mode 100644 index 0000000000..58628b300b --- /dev/null +++ b/openflowjava/openflow-protocol-it/pom.xml @@ -0,0 +1,46 @@ + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + openflow-protocol-it + bundle + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + ${project.groupId} + openflow-protocol-impl + test + + + ${project.groupId} + openflow-protocol-impl + test-jar + test + + + ${project.groupId} + simple-client + test + + + junit + junit + test + + + org.slf4j + slf4j-log4j12 + + + diff --git a/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java b/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java new file mode 100644 index 0000000000..77e747a962 --- /dev/null +++ b/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/IntegrationTest.java @@ -0,0 +1,279 @@ +/* + * 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.it.integration; + +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.Deque; +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; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfigurationImpl; +import org.opendaylight.openflowjava.protocol.impl.clients.ClientEvent; +import org.opendaylight.openflowjava.protocol.impl.clients.ListeningSimpleClient; +import org.opendaylight.openflowjava.protocol.impl.clients.OFClient; +import org.opendaylight.openflowjava.protocol.impl.clients.ScenarioFactory; +import org.opendaylight.openflowjava.protocol.impl.clients.ScenarioHandler; +import org.opendaylight.openflowjava.protocol.impl.clients.SendEvent; +import org.opendaylight.openflowjava.protocol.impl.clients.SimpleClient; +import org.opendaylight.openflowjava.protocol.impl.clients.SleepEvent; +import org.opendaylight.openflowjava.protocol.impl.clients.UdpSimpleClient; +import org.opendaylight.openflowjava.protocol.impl.clients.WaitForMessageEvent; +import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; +import org.opendaylight.openflowjava.protocol.impl.core.TcpHandler; +import org.opendaylight.openflowjava.protocol.impl.core.UdpHandler; +import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionConfigurationImpl; +import org.opendaylight.openflowjava.util.ByteBufUtils; +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 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author michal.polkorab + * @author timotej.kubas + */ +public class IntegrationTest { + + private static final Logger LOGGER = LoggerFactory + .getLogger(IntegrationTest.class); + + private static int port; + private TlsConfiguration tlsConfiguration; + private static final int SWITCH_IDLE_TIMEOUT = 2000; + private static final long CONNECTION_TIMEOUT = 2000; + private InetAddress startupAddress; + private MockPlugin mockPlugin; + private SwitchConnectionProviderImpl switchConnectionProvider; + private ConnectionConfigurationImpl connConfig; + + private Thread t; + + private enum ClientType {SIMPLE, LISTENING} + /** + * @param protocol communication protocol to be used during test + * @throws Exception + */ + public void setUp(final TransportProtocol protocol) throws Exception { + LOGGER.debug("\n starting test -------------------------------"); + + 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, + new ArrayList()); + } + connConfig = new ConnectionConfigurationImpl(startupAddress, 0, tlsConfiguration, SWITCH_IDLE_TIMEOUT, true); + connConfig.setTransferProtocol(protocol); + mockPlugin = new MockPlugin(); + + switchConnectionProvider = new SwitchConnectionProviderImpl(); + switchConnectionProvider.setSwitchConnectionHandler(mockPlugin); + switchConnectionProvider.setConfiguration(connConfig); + switchConnectionProvider.startup().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); + if (protocol.equals(TransportProtocol.TCP) || protocol.equals(TransportProtocol.TLS)) { + final TcpHandler tcpHandler = (TcpHandler) switchConnectionProvider.getServerFacade(); + port = tcpHandler.getPort(); + } else { + final UdpHandler udpHandler = (UdpHandler) switchConnectionProvider.getServerFacade(); + port = udpHandler.getPort(); + } + } + + /** + * @throws Exception + */ + @After + public void tearDown() throws Exception { + switchConnectionProvider.close(); + LOGGER.debug("\n ending test -------------------------------"); + } + + /** + * Library integration and communication test with handshake + * @throws Exception + */ + @Test + public void testHandshake() throws Exception { + setUp(TransportProtocol.TCP); + 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); + + LOGGER.debug("testHandshake() Finished") ; + } + + /** + * Library integration and secured communication test with handshake + * @throws Exception + */ + @Test + public void testTlsHandshake() throws Exception { + setUp(TransportProtocol.TLS); + 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); + + LOGGER.debug("testTlsHandshake() Finished") ; + } + + /** + * Library integration and communication test with handshake + echo exchange + * @throws Exception + */ + @Test + public void testHandshakeAndEcho() throws Exception { + setUp(TransportProtocol.TCP); + 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"))); + 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") ; + } + + /** + * Library integration and secured communication test with handshake + echo exchange + * @throws Exception + */ + @Test + public void testTlsHandshakeAndEcho() throws Exception { + setUp(TransportProtocol.TLS); + 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"))); + 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") ; + } + + /** + * Library udp integration and communication test with handshake + echo exchange + * @throws Exception + */ + @Test + public void testUdpHandshakeAndEcho() throws Exception { + setUp(TransportProtocol.UDP); + 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"))); + 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") ; + } + + /** + * Library integration and communication test (with virtual machine) + * @throws Exception + */ + //@Test + public void testCommunicationWithVM() throws Exception { + mockPlugin.getFinishedFuture().get(); + } + + /** + * @param amountOfCLients + * @param protocol true if encrypted connection should be used + * @return new clients up and running + * @throws ExecutionException if some client could not start + */ + 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; + if (clientType == ClientType.SIMPLE) { + if (protocol.equals(TransportProtocol.TCP)) { + sc = new SimpleClient(startupAddress.getHostAddress(), port); + sc.setSecuredClient(false); + } else if (protocol.equals(TransportProtocol.TLS)) { + sc = new SimpleClient(startupAddress.getHostAddress(), port); + sc.setSecuredClient(true); + } else { + sc = new UdpSimpleClient(startupAddress.getHostAddress(), port); + } + } else if (clientType == ClientType.LISTENING) { + sc = new ListeningSimpleClient(0); + sc.setScenarioHandler(scenarioHandler); + sc.setSecuredClient(false); + } else { + LOGGER.error("Unknown type of client."); + throw new IllegalStateException("Unknown type of client."); + } + + sc.setScenarioHandler(scenarioHandler); + clientsHorde.add(sc); + //sc.run(); + t = new Thread(sc); + t.start(); + } + for (final OFClient sc : clientsHorde) { + try { + sc.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (final Exception e) { + LOGGER.error("createAndStartClient: Something borked ... ", e.getMessage(), e); + throw new ExecutionException(e); + } + } + return clientsHorde; + } + + /** + * @throws Exception + */ + @Test + public void testInitiateConnection() throws Exception { + setUp(TransportProtocol.TCP); + + 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); + final int listeningClientPort = ((ListeningSimpleClient) ofClient).getPort(); + mockPlugin.initiateConnection(switchConnectionProvider, "localhost", listeningClientPort); + ofClient.getScenarioDone().get(); + LOGGER.debug("testInitiateConnection() Finished") ; + } +} diff --git a/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/MockPlugin.java b/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/MockPlugin.java new file mode 100644 index 0000000000..dadfa73c19 --- /dev/null +++ b/openflowjava/openflow-protocol-it/src/test/java/org/opendaylight/openflowjava/protocol/it/integration/MockPlugin.java @@ -0,0 +1,244 @@ +/* + * 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.it.integration; + +import java.net.InetAddress; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; +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.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.GetFeaturesInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; +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.OpenflowProtocolListener; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage; +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.common.RpcError; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * @author michal.polkorab + * + */ +public class MockPlugin implements OpenflowProtocolListener, SwitchConnectionHandler, + SystemNotificationsListener, ConnectionReadyListener { + + protected static final Logger LOGGER = LoggerFactory.getLogger(MockPlugin.class); + protected volatile ConnectionAdapter adapter; + private SettableFuture finishedFuture; + private int idleCounter = 0; + + /** Creates MockPlugin */ + public MockPlugin() { + LOGGER.trace("Creating MockPlugin"); + finishedFuture = SettableFuture.create(); + LOGGER.debug("mockPlugin: {}", System.identityHashCode(this)); + } + + @Override + public void onSwitchConnected(ConnectionAdapter connection) { + LOGGER.debug("onSwitchConnected: {}", connection); + this.adapter = connection; + connection.setMessageListener(this); + connection.setSystemListener(this); + connection.setConnectionReadyListener(this); + } + + @Override + public boolean accept(InetAddress switchAddress) { + LOGGER.debug("MockPlugin.accept(): {}", switchAddress.toString()); + + return true; + } + + @Override + public void onEchoRequestMessage(final EchoRequestMessage notification) { + LOGGER.debug("MockPlugin.onEchoRequestMessage() adapter: {}", adapter); + new Thread(new Runnable() { + @Override + public void run() { + LOGGER.debug("MockPlugin.onEchoRequestMessage().run() started adapter: {}", adapter); + EchoReplyInputBuilder replyBuilder = new EchoReplyInputBuilder(); + replyBuilder.setVersion((short) 4); + replyBuilder.setXid(notification.getXid()); + EchoReplyInput echoReplyInput = replyBuilder.build(); + adapter.echoReply(echoReplyInput); + LOGGER.debug("adapter.EchoReply(Input) sent : ", echoReplyInput.toString()); + LOGGER.debug("MockPlugin.onEchoRequestMessage().run() finished adapter: {}", adapter); + } + }).start(); + } + + @Override + public void onErrorMessage(ErrorMessage notification) { + LOGGER.debug("Error message received"); + + } + + @Override + public void onExperimenterMessage(ExperimenterMessage notification) { + LOGGER.debug("Experimenter message received"); + + } + + @Override + public void onFlowRemovedMessage(FlowRemovedMessage notification) { + LOGGER.debug("FlowRemoved message received"); + + } + + @Override + public void onHelloMessage(HelloMessage notification) { + new Thread(new Runnable() { + @Override + public void run() { + LOGGER.debug("MockPlugin.onHelloMessage().run() Hello message received"); + HelloInputBuilder hib = new HelloInputBuilder(); + hib.setVersion((short) 4); + hib.setXid(2L); + HelloInput hi = hib.build(); + adapter.hello(hi); + LOGGER.debug("hello msg sent"); + new Thread(new Runnable() { + @Override + public void run() { + getSwitchFeatures(); + } + }).start(); + } + }).start(); + + } + + protected void getSwitchFeatures() { + GetFeaturesInputBuilder featuresBuilder = new GetFeaturesInputBuilder(); + featuresBuilder.setVersion((short) 4); + featuresBuilder.setXid(3L); + GetFeaturesInput featuresInput = featuresBuilder.build(); + try { + LOGGER.debug("Requesting features "); + RpcResult rpcResult = adapter.getFeatures( + featuresInput).get(2500, TimeUnit.MILLISECONDS); + if (rpcResult.isSuccessful()) { + byte[] byteArray = rpcResult.getResult().getDatapathId() + .toByteArray(); + LOGGER.debug("DatapathId: {}", Arrays.toString(byteArray)); + } else { + RpcError rpcError = rpcResult.getErrors().iterator().next(); + LOGGER.warn("rpcResult failed", rpcError.getCause()); + } + } catch (InterruptedException | ExecutionException | TimeoutException e) { + LOGGER.error("getSwitchFeatures() exception caught: ", e.getMessage(), e); + } + } + + protected void shutdown() { + try { + LOGGER.debug("MockPlugin.shutdown() sleeping 5... : {}", System.identityHashCode(this)); + Thread.sleep(500); + if (adapter != null) { + Future disconnect = adapter.disconnect(); + disconnect.get(); + LOGGER.debug("MockPlugin.shutdown() Disconnected"); + } + } catch (Exception e) { + LOGGER.error("MockPlugin.shutdown() exception caught: ", e.getMessage(), e); + } + finishedFuture.set(null); + } + + @Override + public void onMultipartReplyMessage(MultipartReplyMessage notification) { + LOGGER.debug("MultipartReply message received"); + + } + + @Override + public void onPacketInMessage(PacketInMessage notification) { + LOGGER.debug("PacketIn message received"); + LOGGER.debug("BufferId: {}", notification.getBufferId()); + LOGGER.debug("TotalLength: {}", notification.getTotalLen()); + LOGGER.debug("Reason: {}", notification.getReason()); + LOGGER.debug("TableId: {}", notification.getTableId()); + LOGGER.debug("Cookie: {}", notification.getCookie()); + LOGGER.debug("Class: {}", notification.getMatch().getMatchEntry().get(0).getOxmClass()); + LOGGER.debug("Field: {}", notification.getMatch().getMatchEntry().get(0).getOxmMatchField()); + LOGGER.debug("Datasize: {}", notification.getData().length); + } + + @Override + public void onPortStatusMessage(PortStatusMessage notification) { + LOGGER.debug("MockPlugin.onPortStatusMessage() message received"); + + } + + @Override + public void onDisconnectEvent(DisconnectEvent notification) { + LOGGER.debug("disconnection occured: {}", notification.getInfo()); + } + + /** + * @return finishedFuture object + */ + public SettableFuture getFinishedFuture() { + return finishedFuture; + } + + @Override + public void onSwitchIdleEvent(SwitchIdleEvent notification) { + LOGGER.debug("MockPlugin.onSwitchIdleEvent() switch status: {}", notification.getInfo()); + idleCounter ++; + } + + /** + * @return number of occured idleEvents + */ + public int getIdleCounter() { + return idleCounter; + } + + @Override + public void onConnectionReady() { + LOGGER.trace("MockPlugin().onConnectionReady()"); + } + + /** + * Initiates connection to device + * @param switchConnectionProvider + * @param host - host IP + * @param port - port number + */ + public void initiateConnection(SwitchConnectionProviderImpl switchConnectionProvider, String host, int port) { + LOGGER.trace("MockPlugin().initiateConnection()"); + switchConnectionProvider.initiateConnection(host, port); + } +} diff --git a/openflowjava/openflow-protocol-it/src/test/resources/log4j.xml b/openflowjava/openflow-protocol-it/src/test/resources/log4j.xml new file mode 100644 index 0000000000..34512d5182 --- /dev/null +++ b/openflowjava/openflow-protocol-it/src/test/resources/log4j.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/openflowjava/openflow-protocol-spi/pom.xml b/openflowjava/openflow-protocol-spi/pom.xml new file mode 100644 index 0000000000..67a9aa90e3 --- /dev/null +++ b/openflowjava/openflow-protocol-spi/pom.xml @@ -0,0 +1,95 @@ + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + openflow-protocol-spi + bundle + + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.opendaylight.openflowjava.protocol.api.keys,* + + + + + org.opendaylight.yangtools + yang-maven-plugin + + + + generate-sources + + + + + + org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator + + ${jmxGeneratorPath} + + + urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang + + + + + + org.opendaylight.mdsal.binding.maven.api.gen.plugin.CodeGeneratorImpl + + ${salGeneratorPath} + + + org.opendaylight.mdsal.binding.yang.unified.doc.generator.maven.DocumentationGeneratorImpl + ${project.build.directory}/site/models + + + true + + + + + + org.opendaylight.controller + yang-jmx-generator-plugin + ${config.version} + + + org.opendaylight.mdsal + maven-sal-api-gen-plugin + ${mdsal.model.version} + jar + + + + + + + + + ${project.groupId} + openflow-protocol-api + + + org.opendaylight.controller + config-api + + + diff --git a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java new file mode 100644 index 0000000000..b013471f3b --- /dev/null +++ b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java @@ -0,0 +1,55 @@ +/* + * 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.spi.connection; + +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler; +import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerExtensionProvider; +import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerExtensionProvider; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * @author mirehak + * @author michal.polkorab + * + */ +public interface SwitchConnectionProvider extends AutoCloseable, + SerializerExtensionProvider, DeserializerExtensionProvider { + + /** + * @param configuration [protocol, port, address and supported features] + */ + 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 + * @return future, triggered to true, when listening channel is up and running + */ + ListenableFuture startup(); + + /** + * stop listening to switches + * @return future, triggered to true, when all listening channels are down + */ + ListenableFuture shutdown(); + + /** + * @param switchConHandler instance being informed when new switch connects + */ + void setSwitchConnectionHandler(SwitchConnectionHandler switchConHandler); +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderFactory.java new file mode 100644 index 0000000000..9ef8c4dda6 --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/statistics/StatisticsHandler.java b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/statistics/StatisticsHandler.java new file mode 100644 index 0000000000..3779a5ebe3 --- /dev/null +++ b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/statistics/StatisticsHandler.java @@ -0,0 +1,28 @@ +/* + * 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.spi.statistics; + +/** + * Used for JConsole service + * + * @author michal.polkorab + */ +public interface StatisticsHandler { + + /** + * Resets all counters + */ + public void resetCounters(); + + /** + * Prints statistics + * @return statistics + */ + public String printStatistics(); +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang b/openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-config.yang new file mode 100644 index 0000000000..1ab7ae851b --- /dev/null +++ b/openflowjava/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/openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang b/openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang new file mode 100644 index 0000000000..25b38d19aa --- /dev/null +++ b/openflowjava/openflow-protocol-spi/src/main/yang/openflow-switch-connection-provider.yang @@ -0,0 +1,29 @@ +module openflow-switch-connection-provider { + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider"; + prefix "openflow-switch-connection-provider"; + + import config {prefix config; revision-date 2013-04-05; } + + description + "openflow-switch-connection-provider service definitions"; + + revision "2014-03-28" { + description + "Initial revision"; + } + + 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 { + description + "StatisticsHandlerService interface as a StatisticsCollection interface identity"; + base config:service-type; + config:java-class "org.opendaylight.openflowjava.protocol.spi.statistics.StatisticsHandler"; + } +} \ No newline at end of file diff --git a/openflowjava/openflowjava-blueprint-config/pom.xml b/openflowjava/openflowjava-blueprint-config/pom.xml new file mode 100644 index 0000000000..71efa0d2d6 --- /dev/null +++ b/openflowjava/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/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml b/openflowjava/openflowjava-blueprint-config/src/main/resources/initial/default-openflow-connection-config.xml new file mode 100644 index 0000000000..08b8a52ed5 --- /dev/null +++ b/openflowjava/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/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml b/openflowjava/openflowjava-blueprint-config/src/main/resources/initial/legacy-openflow-connection-config.xml new file mode 100644 index 0000000000..13860139be --- /dev/null +++ b/openflowjava/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/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml b/openflowjava/openflowjava-blueprint-config/src/main/resources/org/opendaylight/blueprint/openflowjava.xml new file mode 100644 index 0000000000..e1d3c000e3 --- /dev/null +++ b/openflowjava/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/openflowjava-config/pom.xml b/openflowjava/openflowjava-config/pom.xml new file mode 100644 index 0000000000..419a060996 --- /dev/null +++ b/openflowjava/openflowjava-config/pom.xml @@ -0,0 +1,56 @@ + + + + + 4.0.0 + + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + openflowjava-config + Configuration files for openflowjava statistics + jar + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + 45-openflowjava-stats.xml + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-artifacts + + attach-artifact + + package + + + + ${project.build.directory}/classes/${configfile} + xml + configstats + + + + + + + + + diff --git a/openflowjava/openflowjava-config/src/main/resources/45-openflowjava-stats.xml b/openflowjava/openflowjava-config/src/main/resources/45-openflowjava-stats.xml new file mode 100644 index 0000000000..d3b96e51a6 --- /dev/null +++ b/openflowjava/openflowjava-config/src/main/resources/45-openflowjava-stats.xml @@ -0,0 +1,33 @@ + + + + + + + urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider:impl?module=openflow-switch-connection-provider-impl&revision=2014-03-28 + urn:opendaylight:params:xml:ns:yang:openflow:switch:connection:provider?module=openflow-switch-connection-provider&revision=2014-03-28 + + + + + + + + stats:statistics-collection-service-impl + statistics-collection-service-impl + + true + 10000 + + + + + + + \ No newline at end of file diff --git a/openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java b/openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConfigurationType.java new file mode 100644 index 0000000000..42cf45c4de --- /dev/null +++ b/openflowjava/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/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java b/openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/Configurations.java new file mode 100644 index 0000000000..74071ff682 --- /dev/null +++ b/openflowjava/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/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java b/openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationService.java new file mode 100644 index 0000000000..6733afd764 --- /dev/null +++ b/openflowjava/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/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java b/openflowjava/openflowjava-tools/src/main/java/org/opendaylight/openflowjava/tools/ConnectionToolConfigurationServiceImpl.java new file mode 100644 index 0000000000..f309a7dd81 --- /dev/null +++ b/openflowjava/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/openflowjava-tools/src/main/resources/configuration.xml b/openflowjava/openflowjava-tools/src/main/resources/configuration.xml new file mode 100644 index 0000000000..55ecd9b827 --- /dev/null +++ b/openflowjava/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/openflowjava-tools/src/main/resources/configuration.xsd b/openflowjava/openflowjava-tools/src/main/resources/configuration.xsd new file mode 100644 index 0000000000..dcbb49f191 --- /dev/null +++ b/openflowjava/openflowjava-tools/src/main/resources/configuration.xsd @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openflowjava/openflowjava-util/pom.xml b/openflowjava/openflowjava-util/pom.xml new file mode 100644 index 0000000000..c296e5a705 --- /dev/null +++ b/openflowjava/openflowjava-util/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + bundle + openflowjava-util + + ODL :: openflowjava :: ${project.artifactId} + + + + junit + junit + test + + + org.opendaylight.openflowjava + openflow-protocol-api + + + diff --git a/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java new file mode 100644 index 0000000000..e3923c6935 --- /dev/null +++ b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ByteBufUtils.java @@ -0,0 +1,388 @@ +/* + * 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.util; + +import com.google.common.base.Preconditions; +import com.google.common.base.Splitter; +import com.google.common.collect.Lists; +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 + * @author michal.polkorab + * @author timotej.kubas + */ +public abstract class ByteBufUtils { + public static final Splitter DOT_SPLITTER = Splitter.on('.'); + public static final Splitter COLON_SPLITTER = Splitter.on(':'); + private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray(); + private static final Splitter HEXSTRING_SPLITTER = Splitter.onPattern("\\s+").omitEmptyStrings(); + private static final Splitter HEXSTRING_NOSPACE_SPLITTER = Splitter.onPattern("(?<=\\G.{2})").omitEmptyStrings(); + + private ByteBufUtils() { + //not called + } + + /** + * Converts ByteBuf into String + * @param bb input ByteBuf + * @return String + */ + public static String byteBufToHexString(final ByteBuf bb) { + StringBuilder sb = new StringBuilder(); + for (int i = bb.readerIndex(); i < (bb.readerIndex() + bb.readableBytes()); i++) { + sb.append(String.format(" %02x", bb.getUnsignedByte(i))); + } + return sb.toString().trim(); + } + + /** + * Converts String into byte[] + * @param hexSrc input String + * @return byte[] filled with input data + */ + public static byte[] hexStringToBytes(final String hexSrc) { + return hexStringToBytes(hexSrc, true); + } + + /** + * Converts String into byte[] + * @param hexSrc input String + * @param withSpaces if there are spaces in string + * @return byte[] filled with input data + */ + public static byte[] hexStringToBytes(final String hexSrc, final boolean withSpaces) { + final Splitter splitter = withSpaces ? HEXSTRING_SPLITTER : HEXSTRING_NOSPACE_SPLITTER; + List byteChips = Lists.newArrayList(splitter.split(hexSrc)); + byte[] result = new byte[byteChips.size()]; + int i = 0; + for (String chip : byteChips) { + result[i] = (byte) Short.parseShort(chip, 16); + i++; + } + return result; + } + + /** + * Creates ByteBuf filled with specified data + * @param hexSrc input String of bytes in hex format + * @return ByteBuf with specified hexString converted + */ + public static ByteBuf hexStringToByteBuf(final String hexSrc) { + ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer(); + hexStringToByteBuf(hexSrc, out); + return out; + } + + /** + * Creates ByteBuf filled with specified data + * @param hexSrc input String of bytes in hex format + * @param out ByteBuf with specified hexString converted + */ + public static void hexStringToByteBuf(final String hexSrc, final ByteBuf out) { + out.writeBytes(hexStringToBytes(hexSrc)); + } + + /** + * Fills specified ByteBuf with 0 (zeros) of desired length, used for padding + * @param length + * @param out ByteBuf to be padded + * @deprecated Use {@link ByteBuf#writeZero(int)} directly. + */ + @Deprecated + public static void padBuffer(final int length, final ByteBuf out) { + out.writeZero(length); + } + + /** + * Create standard OF header + * @param msgType message code + * @param message POJO + * @param out writing buffer + * @param length ofheader length + */ + public static void writeOFHeader(final byte msgType, final E message, final ByteBuf out, final int length) { + out.writeByte(message.getVersion()); + out.writeByte(msgType); + out.writeShort(length); + out.writeInt(message.getXid().intValue()); + } + + /** + * Write length standard OF header + * @param out writing buffer + */ + 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 + * @return bit mask + */ + public static int fillBitMaskFromMap(final Map booleanMap) { + int bitmask = 0; + + for (Entry iterator : booleanMap.entrySet()) { + if (iterator.getValue() != null && iterator.getValue().booleanValue()) { + bitmask |= 1 << iterator.getKey(); + } + } + return bitmask; + } + + /** + * Fills the bitmask from a set of bit values, starting at specified offset. + * + * @param offset Bit offset to start at + * @param values boolean bit values to fill + * @return Filled-in bitmask + */ + public static int fillBitMask(final int offset, final boolean... values) { + int bitmask = 0; + + int i = offset; + for (boolean v : values) { + if (v) { + bitmask |= 1 << i; + } + ++i; + } + + return bitmask; + } + + /** + * Fills the bitmask from boolean list where key is bit position + * @param booleanList bit to boolean mapping + * @return bit mask + */ + public static int[] fillBitMaskFromList(final List booleanList) { + int[] bitmask; + int index = 0; + int arrayIndex = 0; + if ((booleanList.size() % Integer.SIZE) != 0) { + bitmask = new int[booleanList.size() / Integer.SIZE + 1]; + } else { + bitmask = new int[booleanList.size() / Integer.SIZE]; + } + for (Boolean currElement : booleanList) { + if (currElement != null && currElement.booleanValue()) { + bitmask[arrayIndex] |= 1 << index; + } + index++; + arrayIndex = index / Integer.SIZE; + } + return bitmask; + } + + /** + * Converts byte array into String + * @param array input byte array + * @return String + */ + public static String bytesToHexString(final byte[] array) { + StringBuilder sb = new StringBuilder(); + for (byte element : array) { + sb.append(String.format(" %02x", element)); + } + return sb.toString().trim(); + } + + private static int hexValue(final char c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + + throw new IllegalArgumentException(String.format("Invalid character '%s' encountered", c)); + } + + /** + * Converts macAddress to byte array. + * 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 + */ + public static byte[] macAddressToBytes(final String macAddress) { + final byte[] result = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + final char[] mac = macAddress.toCharArray(); + + try { + int offset = 0; + for (int i = 0; i < EncodeConstants.MAC_ADDRESS_LENGTH - 1; ++i) { + if (mac[offset + EncodeConstants.SIZE_OF_BYTE_IN_BYTES] == ':') { + result[i] = UnsignedBytes.checkedCast(hexValue(mac[offset])); + offset++; + } else { + result[i] = UnsignedBytes.checkedCast( + (hexValue(mac[offset]) << 4) | hexValue(mac[offset +1])); + offset += 2; + } + Preconditions.checkArgument(mac[offset] == ':', "Invalid value: %s", macAddress); + offset++; + } + + if (offset == (mac.length - 1)) { + result[EncodeConstants.MAC_ADDRESS_LENGTH - 1] = UnsignedBytes.checkedCast(hexValue(mac[offset])); + } else { + result[EncodeConstants.MAC_ADDRESS_LENGTH - 1] = + UnsignedBytes.checkedCast(hexValue(mac[offset]) << 4 | hexValue(mac[offset +1])); + offset++; + } + if (offset != (mac.length -1)) { + throw new IllegalArgumentException("Incorrect MAC address length"); + } + } catch (Exception e) { + throw new IllegalArgumentException("Unable to serialize MAC address for input: " + macAddress + + ". \n" + e); + } + return result; + } + + private static final void appendHexByte(final StringBuilder sb, final byte b) { + final int v = UnsignedBytes.toInt(b); + sb.append(HEX_CHARS[v >>> 4]); + sb.append(HEX_CHARS[v & 15]); + } + + private static void appendHexUnsignedShort(final StringBuilder sb, final int val) { + sb.append(ByteBufUtils.HEX_CHARS[(val >>> 12) & 15]); + sb.append(ByteBufUtils.HEX_CHARS[(val >>> 8) & 15]); + sb.append(ByteBufUtils.HEX_CHARS[(val >>> 4) & 15]); + sb.append(ByteBufUtils.HEX_CHARS[ val & 15]); + } + + /** + * 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.rev130715.MacAddress}. + * + * @param address + * @return String representation of a MAC address + */ + public static String macAddressToString(final byte[] address) { + Preconditions.checkArgument(address.length == EncodeConstants.MAC_ADDRESS_LENGTH); + + final StringBuilder sb = new StringBuilder(17); + + appendHexByte(sb, address[0]); + for (int i = 1; i < EncodeConstants.MAC_ADDRESS_LENGTH; i++) { + sb.append(':'); + appendHexByte(sb, address[i]); + } + + return sb.toString(); + } + + /** + * Reads and parses null-terminated string from ByteBuf + * @param rawMessage + * @param length maximal length of String + * @return String with name of port + */ + public static String decodeNullTerminatedString(final ByteBuf rawMessage, final int length) { + byte[] name = new byte[length]; + rawMessage.readBytes(name); + return new String(name).trim(); + } + + /** + * Read an IPv4 address from a buffer and format it into dotted-quad string. + * + * @param buf Input buffer + * @return Dotted-quad string + */ + public static String readIpv4Address(final ByteBuf buf) { + final StringBuilder sb = new StringBuilder(EncodeConstants.GROUPS_IN_IPV4_ADDRESS * 4 - 1); + + sb.append(buf.readUnsignedByte()); + for (int i = 1; i < EncodeConstants.GROUPS_IN_IPV4_ADDRESS; i++) { + sb.append('.'); + sb.append(buf.readUnsignedByte()); + } + + 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. + * + * @param buf Input buffer + * @return IPv6 address in string format + */ + public static String readIpv6Address(final ByteBuf buf) { + final StringBuilder sb = new StringBuilder(EncodeConstants.GROUPS_IN_IPV6_ADDRESS * 5 - 1); + + appendHexUnsignedShort(sb, buf.readUnsignedShort()); + for (int i = 1; i < EncodeConstants.GROUPS_IN_IPV6_ADDRESS; i++) { + sb.append(':'); + appendHexUnsignedShort(sb, buf.readUnsignedShort()); + } + + return sb.toString(); + } + + public static Ipv4Address readIetfIpv4Address(final ByteBuf buf) { + final byte[] tmp = new byte[4]; + buf.readBytes(tmp); + return IetfInetUtil.INSTANCE.ipv4AddressFor(tmp); + } + + public static Ipv6Address readIetfIpv6Address(final ByteBuf buf) { + final byte[] tmp = new byte[16]; + buf.readBytes(tmp); + return IetfInetUtil.INSTANCE.ipv6AddressFor(tmp); + } + + public static MacAddress readIetfMacAddress(final ByteBuf buf) { + final byte[] tmp = new byte[EncodeConstants.MAC_ADDRESS_LENGTH]; + buf.readBytes(tmp); + return IetfYangUtil.INSTANCE.macAddressFor(tmp); + } + + public static byte[] serializeList(final List list) throws IOException{ + ByteBuffer byteBuffer = ByteBuffer.allocate(list.size() * 2); + for (Short aShort : list) { + byteBuffer.putShort(aShort); + } + return byteBuffer.array(); + } +} diff --git a/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java new file mode 100644 index 0000000000..6e285f958b --- /dev/null +++ b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactory.java @@ -0,0 +1,110 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; + +/** + * @author michal.polkorab + */ +public abstract class ExperimenterDeserializerKeyFactory { + + private ExperimenterDeserializerKeyFactory() { + //not called + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createExperimenterErrorDeserializerKey( + short version, Long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, ErrorMessage.class); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @param type experimenter type according to vendor implementation + * @return key instance + */ + 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 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); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createMultipartReplyTFDeserializerKey( + short version, Long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, TableFeatureProperties.class); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createQueuePropertyDeserializerKey( + short version, Long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, QueueProperty.class); + } + + /** + * @param version openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdDeserializerKey createMeterBandDeserializerKey( + short version, Long experimenterId) { + return new ExperimenterIdDeserializerKey(version, experimenterId, MeterBandExperimenterCase.class); + } + +} \ No newline at end of file diff --git a/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java new file mode 100755 index 0000000000..ea0a69ce43 --- /dev/null +++ b/openflowjava/openflowjava-util/src/main/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactory.java @@ -0,0 +1,71 @@ +/* + * 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.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdMeterSubTypeSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdSerializerKey; +import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterIdTypeSerializerKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterMeterBandSubType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.experimenter.core.ExperimenterDataOfChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; + +/** + * @author michal.polkorab + */ +public abstract class ExperimenterSerializerKeyFactory { + + /** + * @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, 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, long type) { + return new ExperimenterIdTypeSerializerKey<>(msgVersion, experimenterId, type, ExperimenterDataOfChoice.class); + } + + /** + * @param msgVersion openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdSerializerKey createMultipartRequestTFSerializerKey( + short msgVersion, long experimenterId) { + return new ExperimenterIdSerializerKey<>(msgVersion, experimenterId, TableFeatureProperties.class); + } + + /** + * @param msgVersion openflow wire version + * @param experimenterId experimenter / vendor ID + * @return key instance + */ + public static ExperimenterIdSerializerKey createMeterBandSerializerKey( + 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/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java b/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java new file mode 100644 index 0000000000..b7f0f593ca --- /dev/null +++ b/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ByteBufUtilsTest.java @@ -0,0 +1,469 @@ +/* + * 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.util; + +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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInputBuilder; + +/** + * @author michal.polkorab + * + */ +public class ByteBufUtilsTest { + + 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)} + */ + @Test + public void testHexStringToBytes() { + byte[] data = ByteBufUtils.hexStringToBytes("01 02 03 04 05 ff"); + + Assert.assertArrayEquals(EXPECTED, data); + } + + /** + * Test of {@link ByteBufUtils#hexStringToBytes(String, boolean)} + */ + @Test + public void testHexStringToBytes2() { + byte[] data = ByteBufUtils.hexStringToBytes("0102030405ff", false); + + Assert.assertArrayEquals(EXPECTED, data); + } + + /** + * Test of {@link ByteBufUtils#hexStringToByteBuf(String)} + */ + @Test + public void testHexStringToByteBuf() { + ByteBuf bb = ByteBufUtils.hexStringToByteBuf("01 02 03 04 05 ff"); + + Assert.assertArrayEquals(EXPECTED, byteBufToByteArray(bb)); + } + + /** + * Test of {@link ByteBufUtils#hexStringToByteBuf(String, ByteBuf)} + */ + @Test + public void testHexStringToGivenByteBuf() { + ByteBuf buffer = UnpooledByteBufAllocator.DEFAULT.buffer(); + ByteBufUtils.hexStringToByteBuf("01 02 03 04 05 ff", buffer); + + Assert.assertArrayEquals(EXPECTED, byteBufToByteArray(buffer)); + } + + private static byte[] byteBufToByteArray(ByteBuf bb) { + byte[] result = new byte[bb.readableBytes()]; + bb.readBytes(result); + return result; + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromMap(java.util.Map)} + */ + @Test + public void testFillBitmaskByEmptyMap() { + Map emptyMap = new HashMap<>(); + String expectedBinaryString = "00000000000000000000000000000000"; + String bitmaskInBinaryString = toBinaryString(emptyMap, 32); + + Assert.assertEquals("Not null string", expectedBinaryString, bitmaskInBinaryString); + } + + private static String toBinaryString(Map emptyMap, int length) { + String binaryString = Integer.toBinaryString(ByteBufUtils.fillBitMaskFromMap(emptyMap)); + return String.format("%"+length+"s", binaryString).replaceAll(" ", "0"); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromMap(java.util.Map)} + */ + @Test + public void testFillBitmaskByFullMap() { + Map fullMap = new HashMap<>(); + String expectedBinaryString = "11111111111111111111111111111111"; + String bitmaskValueInBinarySytring; + for(Integer i=0;i<=31;i++) { + fullMap.put(i, true); + } + bitmaskValueInBinarySytring = toBinaryString(fullMap, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromMap(java.util.Map)} + */ + @Test + public void testFillBitmaskByZeroMap() { + Map zeroMap = new HashMap<>(); + String expectedBinaryString = "00000000000000000000000000000000"; + String bitmaskValueInBinarySytring; + for(Integer i=0;i<=31;i++) { + zeroMap.put(i, false); + } + bitmaskValueInBinarySytring = toBinaryString(zeroMap, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromMap(java.util.Map)} + */ + @Test + public void testFillBitmaskByRandomSet() { + Map randomMap = new HashMap<>(); + String expectedBinaryString = "00000000000000000111100000000000"; + String bitmaskValueInBinarySytring; + Boolean mapValue; + for(Integer i=0;i<=31;i++) { + mapValue = false; + if(i>=11 && i<=14) { + mapValue = true; + } + randomMap.put(i, mapValue); + } + bitmaskValueInBinarySytring = toBinaryString(randomMap, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromList(List)} + */ + @Test + public void testFillBitmaskByEmptyList() { + List emptyList = new ArrayList<>(); + emptyList.add(null); + String expectedBinaryString = "00000000000000000000000000000000"; + String bitmaskInBinaryString = listToBinaryString(emptyList, 32); + + Assert.assertEquals("Not null string", expectedBinaryString, bitmaskInBinaryString); + } + + private static String listToBinaryString(List emptyList, int length) { + int[] bitMaskArray; + bitMaskArray = ByteBufUtils.fillBitMaskFromList(emptyList); + String binaryString = Integer.toBinaryString(bitMaskArray[0]); + return String.format("%"+length+"s", binaryString).replaceAll(" ", "0"); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromList(List)} + */ + @Test + public void testFillBitmaskByFullList() { + List fullList = new ArrayList<>(); + String expectedBinaryString = "11111111111111111111111111111111"; + String bitmaskValueInBinarySytring; + for(Integer i=0;i<=31;i++) { + fullList.add(true); + } + bitmaskValueInBinarySytring = listToBinaryString(fullList, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromList(List)} + */ + @Test + public void testFillBitmaskByZeroList() { + List zeroList = new ArrayList<>(); + String expectedBinaryString = "00000000000000000000000000000000"; + String bitmaskValueInBinarySytring; + for(Integer i=0;i<=31;i++) { + zeroList.add(false); + } + bitmaskValueInBinarySytring = listToBinaryString(zeroList, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#fillBitMaskFromList(List)} + */ + @Test + public void testFillBitmaskFromRandomList() { + List randomList = new ArrayList<>(); + String expectedBinaryString = "00000000000000000111100000000000"; + String bitmaskValueInBinarySytring; + Boolean listValue; + for(Integer i=0;i<=31;i++) { + listValue = false; + if(i>=11 && i<=14) { + listValue = true; + } + randomList.add(listValue); + } + bitmaskValueInBinarySytring = listToBinaryString(randomList, 32); + Assert.assertEquals("Strings does not match", expectedBinaryString, bitmaskValueInBinarySytring); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test + public void testMacToBytes() { + Assert.assertArrayEquals("Wrong byte array", new byte[]{0, 1, 2, 3, (byte) 255, 5}, + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:05")); + Assert.assertArrayEquals("Wrong byte array", new byte[]{1, 2, 3, 4, (byte) 255, 5}, + ByteBufUtils.macAddressToBytes("01:02:03:04:FF:05")); + Assert.assertArrayEquals("Wrong byte array", new byte[]{1, 2, 3, 4, (byte) 255, 5}, + ByteBufUtils.macAddressToBytes("1:2:3:4:FF:5")); + Assert.assertArrayEquals("Wrong byte array", new byte[]{1, 2, 3, 4, 5, (byte) 255}, + ByteBufUtils.macAddressToBytes("1:2:3:4:5:FF")); + Assert.assertArrayEquals("Wrong byte array", new byte[]{1, 15, 3, 4, 5, 6}, + ByteBufUtils.macAddressToBytes("1:F:3:4:5:6")); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytes2() { + Assert.assertArrayEquals("Wrong byte array", new byte[]{0, 1, 2, 3, (byte) 255, 5}, + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:0G")); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesTooShort() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesTooShort2() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testIncorrectMacToBytes() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF::"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testIncorrectMacToBytes2() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:::"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesTooLong() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:05:85"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesInvalidOctet() { + ByteBufUtils.macAddressToBytes("00:01:02:03:FF:05d"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesInvalidOctet2() { + ByteBufUtils.macAddressToBytes("00:01:rr:03:FF:05"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToBytes(String)} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToBytesInvalidOctet3() { + ByteBufUtils.macAddressToBytes("00:01:05d:03:FF:02"); + } + + /** + * Test of {@link ByteBufUtils#macAddressToString(byte[])} + */ + @Test(expected=IllegalArgumentException.class) + public void testMacToString() { + Assert.assertEquals("Wrong string decoded", "00:01:02:03:FF:05", + ByteBufUtils.macAddressToString(new byte[]{0, 1, 2, 3, (byte) 255, 5})); + ByteBufUtils.macAddressToString(new byte[]{0, 1, 2, 3, (byte) 255, 5, 6}); + } + + /** + * Test of {@link ByteBufUtils#decodeNullTerminatedString(ByteBuf, int)} + */ + @Test + public void testDecodeString() { + ByteBuf buf = ByteBufUtils.hexStringToByteBuf("4A 41 4D 45 53 20 42 4F 4E 44 00 00 00 00 00 00"); + Assert.assertEquals("Wrong string decoded", "JAMES BOND", ByteBufUtils.decodeNullTerminatedString(buf, 16)); + + ByteBuf buf2 = ByteBufUtils.hexStringToByteBuf("53 50 49 44 45 52 4D 41 4E 00 00 00 00 00 00"); + Assert.assertEquals("Wrong string decoded", "SPIDERMAN", ByteBufUtils.decodeNullTerminatedString(buf2, 15)); + } + + /** + * Test of {@link ByteBufUtils#byteBufToHexString(ByteBuf)} + */ + @Test + public void testByteBufToHexString() { + ByteBuf buf = ByteBufUtils.hexStringToByteBuf("00 01 02 03 04 05 06 07"); + buf.skipBytes(4); + Assert.assertEquals("Wrong data read", "04 05 06 07", ByteBufUtils.byteBufToHexString(buf)); + } + + /** + * Buffer padding test + */ + @Test + public void testPadBuffer() { + ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(); + ByteBufUtils.padBuffer(4, buf); + Assert.assertEquals("Wrong padding", 0, buf.readUnsignedInt()); + ByteBufUtils.padBuffer(0, buf); + Assert.assertTrue("Wrong padding", buf.readableBytes() == 0); + } + + /** + * Write OF header test + */ + @Test + public void testWriteHeader() { + ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(); + HelloInputBuilder helloBuilder = new HelloInputBuilder(); + helloBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID); + helloBuilder.setXid(12345L); + helloBuilder.setElements(null); + HelloInput helloInput = helloBuilder.build(); + ByteBufUtils.writeOFHeader((byte) 0, helloInput, buf, EncodeConstants.OFHEADER_SIZE); + Assert.assertEquals("Wrong version", EncodeConstants.OF13_VERSION_ID, buf.readUnsignedByte()); + Assert.assertEquals("Wrong type", 0, buf.readUnsignedByte()); + Assert.assertEquals("Wrong length", EncodeConstants.OFHEADER_SIZE, buf.readUnsignedShort()); + Assert.assertEquals("Wrong xid", 12345, buf.readUnsignedInt()); + Assert.assertTrue("Unexpected data", buf.readableBytes() == 0); + } + + /** + * Fill bitmask test + */ + @Test + public void testFillBitmask() { + Assert.assertEquals("Wrong bitmask", 0, ByteBufUtils.fillBitMask(0, false)); + Assert.assertEquals("Wrong bitmask", 1, ByteBufUtils.fillBitMask(0, true)); + Assert.assertEquals("Wrong bitmask", 3, ByteBufUtils.fillBitMask(0, true, true)); + Assert.assertEquals("Wrong bitmask", 2, ByteBufUtils.fillBitMask(0, false, true)); + Assert.assertEquals("Wrong bitmask", 1, ByteBufUtils.fillBitMask(0, true, false)); + Assert.assertEquals("Wrong bitmask", 2, ByteBufUtils.fillBitMask(1, true, false)); + Assert.assertEquals("Wrong bitmask", 4, ByteBufUtils.fillBitMask(1, false, true)); + Assert.assertEquals("Wrong bitmask", 6, ByteBufUtils.fillBitMask(1, true, true)); + Assert.assertEquals("Wrong bitmask", 0, ByteBufUtils.fillBitMask(1)); + } + + /** + * Test bytes to hex string + */ + @Test + public void testBytesToHexString() { + byte[] array = new byte[]{10, 11, 12, 13, 14, 15, 16}; + Assert.assertEquals("Wrong conversion", "0a 0b 0c 0d 0e 0f 10", ByteBufUtils.bytesToHexString(array)); + byte[] empty = new byte[0]; + Assert.assertEquals("Wrong conversion", "", ByteBufUtils.bytesToHexString(empty)); + } + + /** + * Test ipv4 address conversion + */ + @Test(expected=IndexOutOfBoundsException.class) + public void testReadIpv4Address() { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeByte(10); + buffer.writeByte(20); + buffer.writeByte(30); + buffer.writeByte(40); + String ipv4Address = ByteBufUtils.readIpv4Address(buffer); + Assert.assertEquals("Wrong conversion", "10.20.30.40", ipv4Address); + Assert.assertTrue("Unexpected data", buffer.readableBytes() == 0); + + ByteBuf buffer2 = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeByte(10); + ipv4Address = ByteBufUtils.readIpv4Address(buffer2); + } + + /** + * Test ipv6 address conversion + */ + @Test(expected=IndexOutOfBoundsException.class) + public void testReadIpv6Address() { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeShort(10); + buffer.writeShort(65535); + buffer.writeShort(4096); + buffer.writeShort(0); + buffer.writeShort(1024); + buffer.writeShort(42); + buffer.writeShort(2568); + buffer.writeShort(45689); + String ipv4Address = ByteBufUtils.readIpv6Address(buffer); + Assert.assertEquals("Wrong conversion", "000A:FFFF:1000:0000:0400:002A:0A08:B279", ipv4Address); + Assert.assertTrue("Unexpected data", buffer.readableBytes() == 0); + + ByteBuf buffer2 = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeShort(10); + ipv4Address = ByteBufUtils.readIpv6Address(buffer2); + } + + @Test + public void testSerializeList() throws IOException { + + List shorts = new ArrayList<>(); + shorts.add((short) 1); + shorts.add((short) 255); + + final byte[] bytes = ByteBufUtils.serializeList(shorts); + Assert.assertTrue(bytes.length == shorts.size()*2); + Assert.assertArrayEquals(EXPECTEDVALUES1AND255, bytes); + } + + @Test + public void testUpdateHeader() throws IOException { + ByteBuf buffer = PooledByteBufAllocator.DEFAULT.buffer(); + buffer.writeInt(1); + int start = buffer.writerIndex(); + buffer.writeShort(4); + buffer.writeShort(EncodeConstants.EMPTY_LENGTH); + buffer.writeLong(8); + int end = buffer.writerIndex(); + + ByteBufUtils.updateOFHeaderLength(buffer, start); + Assert.assertEquals(buffer.readInt(), 1); + Assert.assertEquals(buffer.readShort(), 4); + Assert.assertEquals(buffer.readShort(), 12); + Assert.assertEquals(buffer.readLong(), 8l); + Assert.assertEquals(buffer.getShort(start + EncodeConstants.OFHEADER_LENGTH_INDEX), end - start); + } +} diff --git a/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java b/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java new file mode 100644 index 0000000000..a8cc83682a --- /dev/null +++ b/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterDeserializerKeyFactoryTest.java @@ -0,0 +1,121 @@ +/* + * 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.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.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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; + +/** + * @author michal.polkorab + */ +public class ExperimenterDeserializerKeyFactoryTest { + + @Test + public void testCreateExperimenterErrorDeserializerKey() throws Exception { + ExperimenterIdDeserializerKey createdKey; + ExperimenterIdDeserializerKey comparationKey; + + createdKey = ExperimenterDeserializerKeyFactory + .createExperimenterErrorDeserializerKey(EncodeConstants.OF10_VERSION_ID, 42L); + 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, 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, 1L); + comparationKey = new ExperimenterIdDeserializerKey(EncodeConstants.OF10_VERSION_ID, + 45L, ExperimenterDataOfChoice.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @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, + 46L, TableFeatureProperties.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @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, + 47L, QueueProperty.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @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, + 44L, MeterBandExperimenterCase.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @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, + 43L, ExperimenterDataOfChoice.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } + + @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, + 43L, ExperimenterDataOfChoice.class); + Assert.assertEquals("Wrong key created", comparationKey, createdKey); + } +} \ No newline at end of file diff --git a/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java b/openflowjava/openflowjava-util/src/test/java/org/opendaylight/openflowjava/util/ExperimenterSerializerKeyFactoryTest.java new file mode 100755 index 0000000000..471e413399 --- /dev/null +++ b/openflowjava/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/openflowjava/parent/pom.xml b/openflowjava/parent/pom.xml new file mode 100644 index 0000000000..4238e08035 --- /dev/null +++ b/openflowjava/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/openflowjava/pom.xml b/openflowjava/pom.xml new file mode 100644 index 0000000000..e3eda8b0ce --- /dev/null +++ b/openflowjava/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + parent + + + 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 + openflowjava-util + + diff --git a/openflowjava/simple-client/pom.xml b/openflowjava/simple-client/pom.xml new file mode 100644 index 0000000000..b399646e61 --- /dev/null +++ b/openflowjava/simple-client/pom.xml @@ -0,0 +1,55 @@ + + 4.0.0 + + org.opendaylight.openflowjava + openflowjava-parent + 0.10.0-SNAPSHOT + ../parent + + simple-client + bundle + + ODL :: openflowjava :: ${project.artifactId} + + https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main + HEAD + + + + + + org.apache.felix + maven-bundle-plugin + + + org.opendaylight.openflowjava.protocol.impl.clients.* + + + + + + + + + ${project.groupId} + openflow-protocol-impl + + + io.netty + netty-handler + + + com.google.guava + guava + + + org.slf4j + slf4j-log4j12 + + + net.sourceforge.argparse4j + argparse4j + + + diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/CallableClient.java new file mode 100644 index 0000000000..67142e389f --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientEvent.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientEvent.java new file mode 100644 index 0000000000..8538d7ba75 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientEvent.java @@ -0,0 +1,23 @@ +/* + * 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.clients; + +/** + * Uniting interface used for scenario support + * @author michal.polkorab + * + */ +public interface ClientEvent { + + /** + * Common method for triggering events + * @return true if event executed successfully + */ + boolean eventExecuted(); +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java new file mode 100644 index 0000000000..64217d8e37 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslContextFactory.java @@ -0,0 +1,72 @@ +/* + * 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.clients; + +import java.security.KeyStore; +import java.security.Security; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; + +/** + * Class for setting up TLS connection. + * + * @author michal.polkorab + */ +public final class ClientSslContextFactory { + + private ClientSslContextFactory() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + // "TLS" - supports some version of TLS + // Use "TLSv1", "TLSv1.1", "TLSv1.2" for specific TLS version + private static final String PROTOCOL = "TLS"; + private static final SSLContext CLIENT_CONTEXT; + + static { + String algorithm = Security.getProperty("ssl.KeyManagerFactory.algorithm"); + if (algorithm == null) { + algorithm = "SunX509"; + } + + SSLContext clientContext; + try { + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(ClientSslKeyStore.asInputStream(), + ClientSslKeyStore.getKeyStorePassword()); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); + kmf.init(ks, ClientSslKeyStore.getCertificatePassword()); + + KeyStore ts = KeyStore.getInstance("JKS"); + ts.load(ClientSslTrustStore.asInputStream(), + ClientSslTrustStore.getKeyStorePassword()); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); + tmf.init(ts); + + clientContext = SSLContext.getInstance(PROTOCOL); + clientContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + } catch (Exception e) { + throw new Error( + "Failed to initialize the client-side SSLContext", e); + } + + CLIENT_CONTEXT = clientContext; + } + + /** + * @return client context + */ + public static SSLContext getClientContext() { + return CLIENT_CONTEXT; + } +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslKeyStore.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslKeyStore.java new file mode 100644 index 0000000000..e3e6069770 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslKeyStore.java @@ -0,0 +1,52 @@ +/* + * 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.clients; + +import java.io.InputStream; + +/** + * Class for storing keys + * + * @author michal.polkorab + */ +public final class ClientSslKeyStore { + + private static final String KEY_STORE_FILENAME = "/selfSignedSwitch"; + + private ClientSslKeyStore() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * InputStream instance of key + * + * @return key as InputStream + */ + public static InputStream asInputStream() { + InputStream in = ClientSslKeyStore.class.getResourceAsStream(KEY_STORE_FILENAME); + if (in == null) { + throw new IllegalStateException("KeyStore file not found: " + KEY_STORE_FILENAME); + } + return in; + } + + /** + * @return certificate password as char[] + */ + public static char[] getCertificatePassword() { + return "opendaylight".toCharArray(); + } + + /** + * @return KeyStore password as char[] + */ + public static char[] getKeyStorePassword() { + return "opendaylight".toCharArray(); + } +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslTrustStore.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslTrustStore.java new file mode 100644 index 0000000000..5f7929f686 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ClientSslTrustStore.java @@ -0,0 +1,52 @@ +/* + * 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.clients; + +import java.io.InputStream; + +/** + * Class for storing keys + * + * @author michal.polkorab + */ +public final class ClientSslTrustStore { + + private static final String KEY_STORE_FILENAME = "/selfSignedController"; + + private ClientSslTrustStore() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * InputStream instance of key + * + * @return key as InputStream + */ + public static InputStream asInputStream() { + InputStream in = ClientSslTrustStore.class.getResourceAsStream(KEY_STORE_FILENAME); + if (in == null) { + throw new IllegalStateException("KeyStore file not found: " + KEY_STORE_FILENAME); + } + return in; + } + + /** + * @return certificate password as char[] + */ + public static char[] getCertificatePassword() { + return "opendaylight".toCharArray(); + } + + /** + * @return KeyStore password as char[] + */ + public static char[] getKeyStorePassword() { + return "opendaylight".toCharArray(); + } +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/EventType.java new file mode 100644 index 0000000000..ff83c6bfce --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java new file mode 100644 index 0000000000..5afb039f17 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ListeningSimpleClient.java @@ -0,0 +1,130 @@ +/* + * 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.clients; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.util.concurrent.Future; + +import java.net.InetSocketAddress; +import java.util.concurrent.ExecutionException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * Listening client for testing purposes + * @author martin.uhlir + * + */ +public class ListeningSimpleClient implements OFClient { + + private static final Logger LOG = LoggerFactory.getLogger(ListeningSimpleClient.class); + private int port; + private boolean securedClient = false; + private EventLoopGroup workerGroup; + private SettableFuture isOnlineFuture; + private SettableFuture scenarioDone; + private ScenarioHandler scenarioHandler; + + /** + * Constructor of the class + * + * @param port host listening port + */ + public ListeningSimpleClient(int port) { + this.port = port; + init(); + } + + private void init() { + isOnlineFuture = SettableFuture.create(); + scenarioDone = SettableFuture.create(); + } + + /** + * Starting class of {@link ListeningSimpleClient} + */ + @Override + public void run() { + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + workerGroup = new NioEventLoopGroup(); + SimpleClientInitializer clientInitializer = new SimpleClientInitializer(isOnlineFuture, securedClient); + clientInitializer.setScenario(scenarioHandler); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup, workerGroup) + .channel(NioServerSocketChannel.class) + .childHandler(clientInitializer); + + ChannelFuture f = b.bind(port).sync(); + // Update port, as it may have been specified as 0 + this.port = ((InetSocketAddress) f.channel().localAddress()).getPort(); + isOnlineFuture.set(true); + + synchronized (scenarioHandler) { + LOG.debug("WAITING FOR SCENARIO"); + while (! scenarioHandler.isScenarioFinished()) { + scenarioHandler.wait(); + } + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); + } finally { + LOG.debug("listening client shutting down"); + try { + workerGroup.shutdownGracefully().get(); + bossGroup.shutdownGracefully().get(); + LOG.debug("listening client shutdown succesful"); + } catch (InterruptedException | ExecutionException e) { + LOG.error(e.getMessage(), e); + } + } + scenarioDone.set(true); + } + + /** + * @return close future + */ + public Future disconnect() { + LOG.debug("disconnecting client"); + return workerGroup.shutdownGracefully(); + } + + @Override + public void setSecuredClient(boolean securedClient) { + this.securedClient = securedClient; + } + + @Override + public SettableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + @Override + public SettableFuture getScenarioDone() { + return scenarioDone; + } + + @Override + public void setScenarioHandler(ScenarioHandler scenario) { + this.scenarioHandler = scenario; + } + + /** + * @return actual port number + */ + public int getPort() { + return this.port; + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/OFClient.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/OFClient.java new file mode 100644 index 0000000000..169395c6fb --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/OFClient.java @@ -0,0 +1,40 @@ +/* + * 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.impl.clients; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * Unifying interface for simple clients / switch simulators + * + * @author michal.polkorab + */ +public interface OFClient extends Runnable { + + /** + * @return the isOnlineFuture which is set when client is started + */ + SettableFuture getIsOnlineFuture(); + + /** + * @return the scenarioDone when scenario is successfully finished + */ + SettableFuture getScenarioDone(); + + /** + * @param scenario list of desired actions + */ + void setScenarioHandler(ScenarioHandler scenario); + + /** + * @param securedClient true is client should use encrypted communication, + * false otherwise + */ + void setSecuredClient(boolean securedClient); +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenario.java new file mode 100644 index 0000000000..1a989ce99c --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java new file mode 100644 index 0000000000..3e01cfa543 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioFactory.java @@ -0,0 +1,108 @@ +/* + * 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.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 + * + * @author michal.polkorab + */ +public final class ScenarioFactory { + + private ScenarioFactory() { + throw new UnsupportedOperationException("Utility class shouldn't be instantiated"); + } + + /** + * Creates stack with handshake needed messages. XID of messages: + *

    + *
  1. hello sent - 00000001 + *
  2. hello waiting - 00000002 + *
  3. features request waiting - 00000003 + *
  4. features reply sent - 00000003 + *
+ * @return stack filled with Handshake messages + */ + public static Deque createHandshakeScenario() { + 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 08 00 00 00 02"))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 05 00 08 00 00 00 03"))); + stack.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 06 00 20 00 00 00 03 " + + "00 01 02 03 04 05 06 07 00 01 02 03 01 00 00 00 00 01 02 03 00 01 02 03"))); + 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. features request waiting - 00000003 + *
  4. features reply sent - 00000003 + *
+ * @param auxiliaryId auxiliaryId wanted in featuresReply message + * @return stack filled with Handshake messages (featuresReply with auxiliaryId set) + */ + public static Deque createHandshakeScenarioWithAuxiliaryId(byte auxiliaryId) { + Deque queue = new ArrayDeque<>(); + queue.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 00 00 08 00 00 00 01"))); + queue.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 00 00 08 00 00 00 02"))); + queue.addFirst(new WaitForMessageEvent(ByteBufUtils.hexStringToBytes("04 05 00 08 00 00 00 03"))); + queue.addFirst(new SendEvent(ByteBufUtils.hexStringToBytes("04 06 00 20 00 00 00 03 " + + "00 01 02 03 04 05 06 07 00 01 02 03 01 " + String.format("%02x ", auxiliaryId) + " 00 00 00 01 02 03 00 01 02 03"))); + return queue; + } + +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java new file mode 100644 index 0000000000..88fd9b64bc --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioHandler.java @@ -0,0 +1,147 @@ +/* + * 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.clients; + +import io.netty.channel.ChannelHandlerContext; + +import java.util.Deque; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * + * @author michal.polkorab + * + */ +public class ScenarioHandler extends Thread { + + private static final Logger LOG = LoggerFactory.getLogger(ScenarioHandler.class); + private Deque scenario; + 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 {@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()) { + LOG.debug("Running event #{}", eventNumber); + ClientEvent peek = scenario.peekLast(); + if (peek instanceof WaitForMessageEvent) { + LOG.debug("WaitForMessageEvent"); + try { + WaitForMessageEvent event = (WaitForMessageEvent) peek; + event.setHeaderReceived(ofMsg.poll(2000, TimeUnit.MILLISECONDS)); + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); + break; + } + } else if (peek instanceof 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 > freeze) { + LOG.warn("Scenario frozen: {}", freezeCounter); + LOG.warn("Scenario step not finished NOT OK!", freezeCounter); + this.finishedOK = false; + break; + } + try { + sleep(sleepBetweenTries); + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); + } + } + LOG.debug("Scenario finished"); + synchronized (this) { + scenarioFinished = true; + this.notify(); + } + } + + /** + * @return true if scenario is done / empty + */ + public boolean isEmpty() { + return scenario.isEmpty(); + } + + /** + * @return scenario + */ + public Deque getScenario() { + return scenario; + } + + /** + * @param scenario scenario filled with desired events + */ + public void setScenario(Deque scenario) { + this.scenario = scenario; + } + + /** + * @param ctx context which will be used for sending messages (SendEvents) + */ + public void setCtx(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + + /** + * @param message received message that is compared to expected message + */ + public void addOfMsg(byte[] message) { + ofMsg.add(message); + } + + /** + * @return true is scenario is finished + */ + public boolean isScenarioFinished() { + return scenarioFinished; + } + + public boolean isFinishedOK() { + return finishedOK; + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioService.java new file mode 100644 index 0000000000..0221acfc09 --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/ScenarioServiceImpl.java new file mode 100644 index 0000000000..9e1df907b3 --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Scenarios.java new file mode 100644 index 0000000000..4c7695506c --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java new file mode 100644 index 0000000000..98934f08d7 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SendEvent.java @@ -0,0 +1,59 @@ +/* + * 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.clients; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class representing sending message event + * + * @author michal.polkorab + */ +public class SendEvent implements ClientEvent { + + private static final Logger LOG = LoggerFactory.getLogger(SendEvent.class); + protected byte[] msgToSend; + protected ChannelHandlerContext ctx; + + /** + * @param msgToSend message to be sent + */ + public SendEvent(byte[] msgToSend) { + this.msgToSend = new byte[msgToSend.length]; + System.arraycopy(msgToSend, 0, this.msgToSend, 0, msgToSend.length); + } + + @Override + public boolean eventExecuted() { + LOG.debug("sending message"); + LOG.debug("start of run"); + ByteBuf buffer = ctx.alloc().buffer(); + buffer.writeBytes(msgToSend); + ctx.writeAndFlush(buffer); + + if (LOG.isDebugEnabled()) { + LOG.debug(">> {}", ByteBufUtils.bytesToHexString(msgToSend)); + LOG.debug("message sent"); + } + return true; + } + + /** + * @param ctx context which will be used for sending messages (SendEvents) + */ + public void setCtx(ChannelHandlerContext ctx) { + this.ctx = ctx; + } + +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java new file mode 100644 index 0000000000..fb0fda091e --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClient.java @@ -0,0 +1,149 @@ +/* + * 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.clients; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.util.concurrent.Future; + +import java.net.InetAddress; +import java.util.concurrent.ExecutionException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * Simple client for testing purposes + * + * @author michal.polkorab + */ +public class SimpleClient implements OFClient { + + private static final Logger LOG = LoggerFactory.getLogger(SimpleClient.class); + private final String host; + private final int port; + private boolean securedClient = false; + private EventLoopGroup group; + private SettableFuture isOnlineFuture; + private SettableFuture scenarioDone; + private ScenarioHandler scenarioHandler; + + /** + * Constructor of class + * + * @param host address of host + * @param port host listening port + */ + public SimpleClient(String host, int port) { + this.host = host; + this.port = port; + init(); + } + + private void init() { + isOnlineFuture = SettableFuture.create(); + scenarioDone = SettableFuture.create(); + } + + /** + * Starting class of {@link SimpleClient} + */ + @Override + public void run() { + group = new NioEventLoopGroup(); + SimpleClientInitializer clientInitializer = new SimpleClientInitializer(isOnlineFuture, securedClient); + clientInitializer.setScenario(scenarioHandler); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .handler(clientInitializer); + + b.connect(host, port).sync(); + + synchronized (scenarioHandler) { + LOG.debug("WAITING FOR SCENARIO"); + while (! scenarioHandler.isScenarioFinished()) { + scenarioHandler.wait(); + } + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); + } finally { + LOG.debug("shutting down"); + try { + group.shutdownGracefully().get(); + LOG.debug("shutdown succesful"); + } catch (InterruptedException | ExecutionException e) { + LOG.error(e.getMessage(), e); + } + } + scenarioDone.set(true); + } + + /** + * @return close future + */ + public Future disconnect() { + LOG.debug("disconnecting client"); + return group.shutdownGracefully(); + } + + @Override + public void setSecuredClient(boolean securedClient) { + this.securedClient = securedClient; + } + + /** + * Sets up {@link SimpleClient} and fires run() + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String host; + int port; + SimpleClient sc; + if (args.length != 3) { + 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(); + port = 6633; + sc = new SimpleClient(host, port); + sc.setSecuredClient(true); + } else { + host = args[0]; + port = Integer.parseInt(args[1]); + sc = new SimpleClient(host, port); + sc.setSecuredClient(Boolean.parseBoolean(args[2])); + } + sc.run(); + } + + @Override + public SettableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + @Override + public SettableFuture getScenarioDone() { + return scenarioDone; + } + + @Override + public void setScenarioHandler(ScenarioHandler scenario) { + this.scenarioHandler = scenario; + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java new file mode 100644 index 0000000000..02c9cd98d8 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientFramer.java @@ -0,0 +1,66 @@ +/* + * 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.clients; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.ByteToMessageDecoder; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for decoding incoming messages into message frames. + * + * @author michal.polkorab + */ +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 LOG = LoggerFactory.getLogger(SimpleClientFramer.class); + + /** + * Constructor of class. + */ + public SimpleClientFramer() { + LOG.trace("Creating OFFrameDecoder"); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + 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) { + 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) { + LOG.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); + return; + } + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + + ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); + list.add(messageBuffer); + messageBuffer.retain(); + bb.skipBytes(length); + } + +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java new file mode 100644 index 0000000000..863f9aebad --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientHandler.java @@ -0,0 +1,75 @@ +/* + * 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.clients; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * + * @author michal.polkorab + */ +public class SimpleClientHandler extends ChannelInboundHandlerAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(SimpleClientHandler.class); + private static final int LENGTH_INDEX_IN_HEADER = 2; + private SettableFuture isOnlineFuture; + protected ScenarioHandler scenarioHandler; + + /** + * @param isOnlineFuture future notifier of connected channel + * @param scenarioHandler handler of scenario events + */ + public SimpleClientHandler(SettableFuture isOnlineFuture, ScenarioHandler scenarioHandler) { + this.isOnlineFuture = isOnlineFuture; + this.scenarioHandler = scenarioHandler; + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ByteBuf bb = (ByteBuf) msg; + if (LOG.isDebugEnabled()) { + LOG.debug("<< {}", ByteBufUtils.byteBufToHexString(bb)); + } + int length = bb.getUnsignedShort(bb.readerIndex() + LENGTH_INDEX_IN_HEADER); + LOG.trace("SimpleClientHandler - start of read"); + byte[] message = new byte[length]; + bb.readBytes(message); + scenarioHandler.addOfMsg(message); + LOG.trace("end of read"); + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + LOG.debug("Client is active"); + if (isOnlineFuture != null) { + isOnlineFuture.set(true); + isOnlineFuture = null; + } + scenarioHandler.setCtx(ctx); + scenarioHandler.start(); + + } + + /** + * @param scenarioHandler handler of scenario events + */ + public void setScenario(ScenarioHandler scenarioHandler) { + this.scenarioHandler = scenarioHandler; + } + +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java new file mode 100644 index 0000000000..21afc08b55 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SimpleClientInitializer.java @@ -0,0 +1,63 @@ +/* + * 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.clients; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.SocketChannel; +import io.netty.handler.ssl.SslHandler; + +import javax.net.ssl.SSLEngine; + +import com.google.common.util.concurrent.SettableFuture; + +/** Initializes secured {@link SimpleClient} pipeline + * + * @author michal.polkorab + */ +public class SimpleClientInitializer extends ChannelInitializer { + + private SettableFuture isOnlineFuture; + private final boolean secured; + private ScenarioHandler scenarioHandler; + + /** + * @param isOnlineFuture future notifier of connected channel + * @param secured true if {@link SimpleClient} should use encrypted communication + */ + public SimpleClientInitializer(SettableFuture isOnlineFuture, boolean secured) { + this.isOnlineFuture = isOnlineFuture; + this.secured = secured; + } + + @Override + public void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + if (secured) { + SSLEngine engine = ClientSslContextFactory.getClientContext() + .createSSLEngine(); + engine.setUseClientMode(true); + pipeline.addLast("ssl", new SslHandler(engine)); + } + SimpleClientHandler simpleClientHandler = new SimpleClientHandler(isOnlineFuture, scenarioHandler); + simpleClientHandler.setScenario(scenarioHandler); + pipeline.addLast("framer", new SimpleClientFramer()); + pipeline.addLast("handler", simpleClientHandler); + isOnlineFuture = null; + + } + + /** + * @param scenarioHandler handler of scenario events + */ + public void setScenario(ScenarioHandler scenarioHandler) { + this.scenarioHandler = scenarioHandler; + } +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java new file mode 100644 index 0000000000..19229abce3 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/SleepEvent.java @@ -0,0 +1,43 @@ +/* + * 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.clients; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class representing sleep (wait) event + * + * @author michal.polkorab + */ +public class SleepEvent implements ClientEvent { + + private static final Logger LOG = LoggerFactory.getLogger(SleepEvent.class); + private long sleepTime; + + /** + * + * @param sleepTime time of {@link Thread#sleep(long)} in milliseconds + */ + public SleepEvent(long sleepTime) { + this.sleepTime = sleepTime; + } + + @Override + public boolean eventExecuted() { + try { + Thread.sleep(sleepTime); + LOG.debug("Sleeping"); + return true; + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); + } + return false; + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/Step.java new file mode 100644 index 0000000000..d3c230b768 --- /dev/null +++ b/openflowjava/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/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java new file mode 100644 index 0000000000..f7ff0a6198 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClient.java @@ -0,0 +1,149 @@ +/* + * 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.impl.clients; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelOption; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.nio.NioDatagramChannel; +import io.netty.util.concurrent.Future; + +import java.net.InetAddress; +import java.util.concurrent.ExecutionException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.SettableFuture; + +/** + * Simple client for testing purposes + * + * @author michal.polkorab + */ +public class UdpSimpleClient implements OFClient { + + private static final Logger LOG = LoggerFactory.getLogger(UdpSimpleClient.class); + private final String host; + private final int port; + private EventLoopGroup group; + private SettableFuture isOnlineFuture; + private SettableFuture scenarioDone; + private ScenarioHandler scenarioHandler; + + /** + * Constructor of class + * + * @param host address of host + * @param port host listening port + */ + public UdpSimpleClient(String host, int port) { + this.host = host; + this.port = port; + init(); + } + + private void init() { + isOnlineFuture = SettableFuture.create(); + scenarioDone = SettableFuture.create(); + } + + /** + * Starting class of {@link UdpSimpleClient} + */ + @Override + public void run() { + group = new NioEventLoopGroup(); + UdpSimpleClientInitializer clientInitializer = new UdpSimpleClientInitializer(isOnlineFuture); + clientInitializer.setScenario(scenarioHandler); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioDatagramChannel.class) + .option(ChannelOption.SO_BROADCAST, false) + .handler(clientInitializer); + + b.connect(host, port).sync(); + + synchronized (scenarioHandler) { + LOG.debug("WAITING FOR SCENARIO"); + while (! scenarioHandler.isScenarioFinished()) { + scenarioHandler.wait(); + } + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); + } finally { + LOG.debug("shutting down"); + try { + group.shutdownGracefully().get(); + LOG.debug("shutdown succesful"); + } catch (InterruptedException | ExecutionException e) { + LOG.error(e.getMessage(), e); + } + } + scenarioDone.set(true); + } + + /** + * @return close future + */ + public Future disconnect() { + LOG.debug("disconnecting client"); + return group.shutdownGracefully(); + } + + /** + * Sets up {@link UdpSimpleClient} and fires run() + * + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { + String host; + int port; + UdpSimpleClient sc; + if (args.length != 2) { + 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(); + port = 6633; + sc = new UdpSimpleClient(host, port); + } else { + host = args[0]; + port = Integer.parseInt(args[1]); + sc = new UdpSimpleClient(host, port); + } + sc.run(); + + } + + @Override + public SettableFuture getIsOnlineFuture() { + return isOnlineFuture; + } + + @Override + public SettableFuture getScenarioDone() { + return scenarioDone; + } + + @Override + public void setScenarioHandler(ScenarioHandler scenario) { + this.scenarioHandler = scenario; + } + + @Override + public void setSecuredClient(boolean securedClient) { + // TODO: Finish implementation when DTLS is supported + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java new file mode 100644 index 0000000000..b893a8f346 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientFramer.java @@ -0,0 +1,67 @@ +/* + * 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.impl.clients; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.socket.DatagramPacket; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class for decoding incoming udp messages into message frames. + * + * @author michal.polkorab + */ +public class UdpSimpleClientFramer extends MessageToMessageDecoder { + + /** 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 LOG = LoggerFactory.getLogger(UdpSimpleClientFramer.class); + + /** + * Constructor of class. + */ + public UdpSimpleClientFramer() { + LOG.trace("Creating OFFrameDecoder"); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + LOG.warn("Unexpected exception from downstream.", cause); + ctx.close(); + } + + @Override + protected void decode(ChannelHandlerContext chc, DatagramPacket msg, List list) throws Exception { + ByteBuf bb = msg.content(); + if (bb.readableBytes() < LENGTH_OF_HEADER) { + 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) { + LOG.debug("skipping bb - too few data for msg: {} < {}", bb.readableBytes(), length); + return; + } + LOG.debug("OF Protocol message received, type:{}", bb.getByte(bb.readerIndex() + 1)); + + ByteBuf messageBuffer = bb.slice(bb.readerIndex(), length); + list.add(messageBuffer); + messageBuffer.retain(); + bb.skipBytes(length); + } +} diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java new file mode 100644 index 0000000000..a68b6ab795 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/UdpSimpleClientInitializer.java @@ -0,0 +1,50 @@ +/* + * 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.impl.clients; + +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.socket.DatagramChannel; + +import com.google.common.util.concurrent.SettableFuture; + +/** Initializes udp pipeline + * + * @author michal.polkorab + */ +public class UdpSimpleClientInitializer extends ChannelInitializer { + + private SettableFuture isOnlineFuture; + private ScenarioHandler scenarioHandler; + + /** + * @param isOnlineFuture future notifier of connected channel + */ + public UdpSimpleClientInitializer(SettableFuture isOnlineFuture) { + this.isOnlineFuture = isOnlineFuture; + } + + @Override + public void initChannel(DatagramChannel ch) throws Exception { + ChannelPipeline pipeline = ch.pipeline(); + SimpleClientHandler simpleClientHandler = new SimpleClientHandler(isOnlineFuture, scenarioHandler); + simpleClientHandler.setScenario(scenarioHandler); + pipeline.addLast("framer", new UdpSimpleClientFramer()); + pipeline.addLast("handler", simpleClientHandler); + isOnlineFuture = null; + } + + /** + * @param scenarioHandler handler of scenario events + */ + public void setScenario(ScenarioHandler scenarioHandler) { + this.scenarioHandler = scenarioHandler; + } +} \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java new file mode 100644 index 0000000000..0854a27989 --- /dev/null +++ b/openflowjava/simple-client/src/main/java/org/opendaylight/openflowjava/protocol/impl/clients/WaitForMessageEvent.java @@ -0,0 +1,60 @@ +/* + * 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.clients; + +import java.util.Arrays; + +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class representing waiting on message + * @author michal.polkorab + */ +public class WaitForMessageEvent implements ClientEvent { + + private static final Logger LOG = LoggerFactory.getLogger(WaitForMessageEvent.class); + private byte[] headerExpected; + private byte[] headerReceived; + + /** + * @param headerExpected header (first 8 bytes) of expected message + */ + public WaitForMessageEvent(byte[] headerExpected) { + this.headerExpected = new byte[headerExpected.length]; + System.arraycopy(headerExpected, 0, this.headerExpected, 0, headerExpected.length); + } + + @Override + public boolean eventExecuted() { + if (headerReceived == null) { + return false; + } + if (!Arrays.equals(headerExpected, headerReceived)) { + if (LOG.isDebugEnabled()) { + LOG.debug("expected msg: {}", ByteBufUtils.bytesToHexString(headerExpected)); + LOG.debug("received msg: {}", ByteBufUtils.bytesToHexString(headerReceived)); + } + return false; + } + LOG.debug("Headers OK"); + return true; + } + + /** + * @param headerReceived header (first 8 bytes) of expected message + */ + public void setHeaderReceived(byte[] headerReceived) { + if (headerReceived != null) { + this.headerReceived = new byte[headerReceived.length]; + System.arraycopy(headerReceived, 0, this.headerReceived, 0, headerReceived.length); + } + } +} diff --git a/openflowjava/simple-client/src/main/resources/scenario.xml b/openflowjava/simple-client/src/main/resources/scenario.xml new file mode 100644 index 0000000000..572bd31376 --- /dev/null +++ b/openflowjava/simple-client/src/main/resources/scenario.xml @@ -0,0 +1,41 @@ + + + + + 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/openflowjava/simple-client/src/main/resources/scenario.xsd b/openflowjava/simple-client/src/main/resources/scenario.xsd new file mode 100644 index 0000000000..59727ca3ec --- /dev/null +++ b/openflowjava/simple-client/src/main/resources/scenario.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openflowjava/simple-client/src/main/resources/selfSignedController b/openflowjava/simple-client/src/main/resources/selfSignedController new file mode 100644 index 0000000000000000000000000000000000000000..9f4e421dad53beae6ce49b5354b57be87de93563 GIT binary patch literal 1351 zcmezO_TO6u1_mY|W&~rA;?$h9;>`5C)Rg4>ypp2)oSf7mprl*D`44}9biY9pW48ex z8<#d4BMYMzlOQ7_D+5atW4Yvn%f|g`Cp1&TuWyQzzMQcv^XY+v%}dX%-6&Vdy42}Y zW&Md6=BGC+9-G9G-f{T*-v=}9R>p2pd60GZRFmngy_`j5xr*LNt4#OT)!F5VskSSe zdwe>u_~8G80l5sbjm7epvc_L;@i-Iw+^oUKvF`Kp-8T|FC(dQu?)x$?N}qQz--BbB zp09UpJ!5X-v_RzW*XC;t(I)m87b{L(`qp-Q|KDp@r>L;9zAgZA?x_I z9~(bO`MEFQVIThZiZQ_-Kd;Z$Hmz)N^9l zLmRQG?vR>ZjR%X@$!Tw1Ryr|naXt4hMbo5@zmuvMRjkh}`M7UI;DpW<&G#QhJ)O@s zsXHyMp*mDGh0(|Q-+50h=EfEVrp5*#kEWuH-;QN$_%rE%an3c{^`%DKGD@no-cR2x zX;KoCZg-e-@8r?{{SLNVFH{$#8NIn~*cY&fgDZWf;ntrHj~qBBW^9@D=Bz~iz*@?WHo-ph3UQE;v?Vjnn^Z3&ao!}p~`kPp`aVbeTkog-jGV z=kq^seAlyVjs?S^)VkbSU|_fHyj-E(HaWk5Kkjds!bbBM9(xy7N3467aZAQq?4-8b MR!6VGPUY390E5dNe*gdg literal 0 HcmV?d00001 diff --git a/openflowjava/simple-client/src/main/resources/selfSignedSwitch b/openflowjava/simple-client/src/main/resources/selfSignedSwitch new file mode 100644 index 0000000000000000000000000000000000000000..645ac44243d3a8af51fa012f7879d245d05c1054 GIT binary patch literal 1348 zcmezO_TO6u1_mY|W&~q_;?$h9;>`5C)Rf}#%#!2`poCk&^&f|T^aO(@#vTJcHZE;8 zMixdbCP79z z{vL2FH)cr72==#S)LUgc(PHjlri(wOALuim?f*=E<7+PNT*lcA@mu-6lmw(yh4<-L}h-Y&+z{I!>H?Z#{ZQ!{7(h^Pn5o=`((rK^)eF|8BY8l9%L)92pnUq z5qhQumJAHc$p%f#@jxuQfSHMriHXIvf&YmCHygWFo5wi|7G_okgT@9!ZUas>=1>+k zVWwbjLs0`^5QjsUC%+&yFD0=uCo?^x1SZUmU6>2IFgJE#W>jGVIdNV?69Y2?GebiI zBO`+-FxS$+1j-!@PHbY_0ZiyRuz+I(a^#sB8yWuA2RF)=3TX!2_nM>k=E?JKg4=^^ z-n%dyma}iz7O0l#8tb4G_&d_JH{#d+qhEI!d^66fYKrV-7ByE+kQ;?hjsY#V=I=4^0WMI{&xAO++ilu5aB4XiALW_Kd;kHysq{B zlM=J!+>0KJ$C*SKrY8jSiz;)U*)(Zq)1ucc+#e!jzJi?g{o#VvYqM?do!+xL#%xFU z&dMq4cmJ|_)$}vmhufCDDLpVUyl>Z)NdISr>;jDqTRg=Im0$R1hzV~$&uP?iV%b9* zv8wKnnqG|ui`U6%Z(de9F>i4__b)}$q>sOosu)$Q&n)@4Z$;pQ&K1q~A4WZ$&o-$$ zEv}(DR5gXs$NJxSPc7!gRtAtewrlO0Rieb17@)L6(p79twcpl?#C@I554~EPbX71u zXj7qobZC$7{mwmB+n?xVA1pbf{Ih^p{C3LK>~A|SvX(1(l`mOPwn4?{^H!~D%kwuU zp6UMdurtVJ$FDU{j@`=9tc{kvCOd)GtJS)vX7~U1e-GbY{(AC#)8lfpCs;3g|8BYJ zVnqXa16g32mgQp+V-fki@~qY6YpgvUy*{(v?mKM|ZLgw$k|UV)84ProL@H7mGR;I& zb1vSVr#Pp#c-;qWu?I{dz73Wqi_+Zp9Q~<%o^R5#J)YMMmR^YWQ7f+gl<8W)zE1Om KmC%%2<4FL78zvqA literal 0 HcmV?d00001 -- 2.36.6