From 175197da8ea43335df3daeba4c6296fcd83a057c Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Thu, 10 Nov 2016 13:31:25 +0100 Subject: Post split cleanup - change groupIds - change packages - update poms Change-Id: I343c5a292a67de1dd50687870ca4ab5b7276e93e Signed-off-by: Maros Marsalek Signed-off-by: Marek Gradzki --- vpp-common/vpp-translate-utils/pom.xml | 2 +- .../util/AbstractInterfaceTypeCustomizer.java | 100 +++++++++++ .../common/translate/util/AddressTranslator.java | 85 +++++++++ .../common/translate/util/ByteDataTranslator.java | 79 +++++++++ .../translate/util/FutureJVppCustomizer.java | 44 +++++ .../common/translate/util/Ipv4AddressRange.java | 121 +++++++++++++ .../common/translate/util/Ipv4Translator.java | 137 +++++++++++++++ .../common/translate/util/Ipv6Translator.java | 158 +++++++++++++++++ .../common/translate/util/JvppReplyConsumer.java | 194 +++++++++++++++++++++ .../common/translate/util/MacTranslator.java | 110 ++++++++++++ .../common/translate/util/NamingContext.java | 179 +++++++++++++++++++ .../translate/util/ReadTimeoutException.java | 33 ++++ .../common/translate/util/TagRewriteOperation.java | 88 ++++++++++ .../common/translate/util/VppStatusListener.java | 46 +++++ .../translate/util/WriteTimeoutException.java | 33 ++++ .../vpp/util/AbstractInterfaceTypeCustomizer.java | 100 ----------- .../translate/vpp/util/AddressTranslator.java | 85 --------- .../translate/vpp/util/ByteDataTranslator.java | 79 --------- .../translate/vpp/util/FutureJVppCustomizer.java | 44 ----- .../translate/vpp/util/Ipv4AddressRange.java | 121 ------------- .../translate/vpp/util/Ipv4Translator.java | 137 --------------- .../translate/vpp/util/Ipv6Translator.java | 158 ----------------- .../translate/vpp/util/JvppReplyConsumer.java | 194 --------------------- .../translate/vpp/util/MacTranslator.java | 110 ------------ .../translate/vpp/util/NamingContext.java | 179 ------------------- .../translate/vpp/util/ReadTimeoutException.java | 33 ---- .../translate/vpp/util/TagRewriteOperation.java | 88 ---------- .../translate/vpp/util/VppStatusListener.java | 46 ----- .../translate/vpp/util/WriteTimeoutException.java | 33 ---- .../translate/util/AddressTranslatorTest.java | 36 ++++ .../translate/util/ByteDataTranslatorTest.java | 53 ++++++ .../translate/util/Ipv4AddressRangeTest.java | 58 ++++++ .../common/translate/util/Ipv4TranslatorTest.java | 50 ++++++ .../common/translate/util/Ipv6TranslatorTest.java | 57 ++++++ .../translate/util/JvppReplyConsumerTest.java | 79 +++++++++ .../common/translate/util/MacTranslatorTest.java | 90 ++++++++++ .../translate/util/VppStatusListenerTest.java | 38 ++++ .../translate/vpp/util/AddressTranslatorTest.java | 36 ---- .../translate/vpp/util/ByteDataTranslatorTest.java | 52 ------ .../translate/vpp/util/Ipv4AddressRangeTest.java | 57 ------ .../translate/vpp/util/Ipv4TranslatorTest.java | 49 ------ .../translate/vpp/util/Ipv6TranslatorTest.java | 56 ------ .../translate/vpp/util/JvppReplyConsumerTest.java | 76 -------- .../translate/vpp/util/MacTranslatorTest.java | 89 ---------- .../translate/vpp/util/VppStatusListenerTest.java | 37 ---- .../vpp/util/cache/DumpCacheManagerTest.java | 152 ---------------- 46 files changed, 1869 insertions(+), 2012 deletions(-) create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AbstractInterfaceTypeCustomizer.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AddressTranslator.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslator.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/FutureJVppCustomizer.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRange.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4Translator.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumer.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/MacTranslator.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/NamingContext.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ReadTimeoutException.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/TagRewriteOperation.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/VppStatusListener.java create mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/WriteTimeoutException.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AbstractInterfaceTypeCustomizer.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AddressTranslator.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslator.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/FutureJVppCustomizer.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRange.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4Translator.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv6Translator.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumer.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/MacTranslator.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/NamingContext.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ReadTimeoutException.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/TagRewriteOperation.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/VppStatusListener.java delete mode 100644 vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/WriteTimeoutException.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/AddressTranslatorTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslatorTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRangeTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4TranslatorTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv6TranslatorTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumerTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/MacTranslatorTest.java create mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/VppStatusListenerTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/AddressTranslatorTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslatorTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRangeTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4TranslatorTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv6TranslatorTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumerTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/MacTranslatorTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/VppStatusListenerTest.java delete mode 100644 vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java (limited to 'vpp-common/vpp-translate-utils') diff --git a/vpp-common/vpp-translate-utils/pom.xml b/vpp-common/vpp-translate-utils/pom.xml index 85994feb3..c217bdb26 100644 --- a/vpp-common/vpp-translate-utils/pom.xml +++ b/vpp-common/vpp-translate-utils/pom.xml @@ -17,7 +17,7 @@ - io.fd.honeycomb.vpp + io.fd.hc2vpp.common vpp-impl-parent 1.16.12-SNAPSHOT ../../vpp-common/vpp-impl-parent diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AbstractInterfaceTypeCustomizer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AbstractInterfaceTypeCustomizer.java new file mode 100644 index 000000000..2a9af4604 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AbstractInterfaceTypeCustomizer.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Validation WriteCustomizers for Interface subnodes. + * Validates the type of interface. + */ +public abstract class AbstractInterfaceTypeCustomizer + extends FutureJVppCustomizer implements WriterCustomizer { + + protected AbstractInterfaceTypeCustomizer(final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + private void checkProperInterfaceType(@Nonnull final WriteContext writeContext, + @Nonnull final InstanceIdentifier id) { + final InstanceIdentifier ifcTypeFromIid = id.firstIdentifierOf(Interface.class); + checkArgument(ifcTypeFromIid != null, "Instance identifier does not contain {} type", Interface.class); + checkArgument(id.firstKeyOf(Interface.class) != null, "Instance identifier does not contain keyed {} type", + Interface.class); + final Optional interfaceConfig = writeContext.readAfter(ifcTypeFromIid); + checkState(interfaceConfig.isPresent(), + "Unable to get Interface configuration for an interface: %s currently being updated", ifcTypeFromIid); + + IllegalInterfaceTypeException + .checkInterfaceType(interfaceConfig.get(), getExpectedInterfaceType()); + } + + protected abstract Class getExpectedInterfaceType(); + + /** + * Validate expected interface type + */ + @Override + public final void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final D dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + checkProperInterfaceType(writeContext, id); + writeInterface(id, dataAfter, writeContext); + } + + protected abstract void writeInterface(final InstanceIdentifier id, final D dataAfter, + final WriteContext writeContext) + throws WriteFailedException; + + // Validation for update and delete is not necessary + + /** + * Indicates unexpected interface type + */ + protected static final class IllegalInterfaceTypeException extends IllegalArgumentException { + + private IllegalInterfaceTypeException(final String msg) { + super(msg); + } + + /** + * Check the type of interface equals expected type + * + * @throws IllegalInterfaceTypeException if type of interface is null or not expected + */ + static void checkInterfaceType(@Nonnull final Interface ifc, + @Nonnull final Class expectedType) { + if (ifc.getType() == null || !expectedType.equals(ifc.getType())) { + throw new IllegalInterfaceTypeException(String.format( + "Unexpected interface type: %s for interface: %s. Expected interface is: %s", ifc.getType(), + ifc.getName(), expectedType)); + } + } + + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AddressTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AddressTranslator.java new file mode 100644 index 000000000..b9665df9a --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/AddressTranslator.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +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.Ipv4AddressNoZone; +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.Ipv6AddressNoZone; + +/** + * Aggregation trait providing logic for converting address based data + */ +public interface AddressTranslator extends Ipv4Translator, Ipv6Translator, MacTranslator { + + default byte[] ipAddressToArray(IpAddress address) { + checkNotNull(address, "Cannot resolve null adddress"); + + if (isIpv6(address)) { + return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(address.getIpv6Address())); + } else { + return ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(address.getIpv4Address())); + } + } + + + /** + * Converts {@link IpAddress} to array representing {@link Ipv4Address} or {@link Ipv6Address} + */ + default byte[] ipAddressToArray(boolean isIpv6, @Nonnull IpAddress address) { + checkNotNull(address, "Cannot convert null Address"); + + if (isIpv6) { + return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(address.getIpv6Address())); + } else { + return ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(address.getIpv4Address())); + } + } + + /** + * Converts array bytes to {@link IpAddress}. + */ + @Nonnull + default IpAddress arrayToIpAddress(boolean isIpv6, byte[] ip) { + if (isIpv6) { + return new IpAddress(arrayToIpv6AddressNoZone(ip)); + } else { + return new IpAddress(arrayToIpv4AddressNoZone(ip)); + } + } + + /** + * Converts array bytes to {@link IpAddress} + */ + @Nonnull + default IpAddress arrayToIpAddressReversed(boolean isIpv6, byte[] ip) { + if (isIpv6) { + return new IpAddress(arrayToIpv6AddressNoZoneReversed(ip)); + } else { + return new IpAddress(arrayToIpv4AddressNoZoneReversed(ip)); + } + } + + default IpAddress reverseAddress(@Nonnull final IpAddress address) { + //arrayToIpAdddress internaly reverts order + return arrayToIpAddress(isIpv6(address), ipAddressToArray(address)); + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslator.java new file mode 100644 index 000000000..a96542623 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslator.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Trait providing logic for working with binary-based data + */ +public interface ByteDataTranslator { + + /** + * Returns 0 if argument is null or false, 1 otherwise. + * + * @param value Boolean value to be converted + * @return byte value equal to 0 or 1 + */ + default byte booleanToByte(@Nullable final Boolean value) { + return value != null && value + ? (byte) 1 + : (byte) 0; + } + + /** + * Returns Boolean.TRUE if argument is 0, Boolean.FALSE otherwise. + * + * @param value byte value to be converted + * @return Boolean value + * @throws IllegalArgumentException if argument is neither 0 nor 1 + */ + @Nonnull + default Boolean byteToBoolean(final byte value) { + if (value == 0) { + return Boolean.FALSE; + } else if (value == 1) { + return Boolean.TRUE; + } + throw new IllegalArgumentException(String.format("0 or 1 was expected but was %d", value)); + } + + /** + * Reverses bytes in the byte array + * + * @param bytes input array + * @return reversed array + */ + default byte[] reverseBytes(final byte[] bytes) { + final byte[] reversed = new byte[bytes.length]; + int i = 1; + for (byte aByte : bytes) { + reversed[bytes.length - i++] = aByte; + } + + return reversed; + } + + /** + * Return (interned) string from byte array while removing \u0000. Strings represented as fixed length byte[] from + * vpp contain \u0000. + */ + default String toString(final byte[] cString) { + return new String(cString).replaceAll("\\u0000", "").intern(); + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/FutureJVppCustomizer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/FutureJVppCustomizer.java new file mode 100644 index 000000000..6d527c702 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/FutureJVppCustomizer.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +/** + * Abstract utility to hold the vppApi reference. + */ +@Beta +public abstract class FutureJVppCustomizer { + + private final FutureJVppCore futureJVppCore; + + public FutureJVppCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { + this.futureJVppCore = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); + } + + /** + * Get vppApi reference + * + * @return vppApi reference + */ + public FutureJVppCore getFutureJVpp() { + return futureJVppCore; + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRange.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRange.java new file mode 100644 index 000000000..032b9051d --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRange.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import java.util.Objects; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * IPv4 address range representation. + */ +public final class Ipv4AddressRange { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressRange.class); + + private final Ipv4AddressNoZone start; + private final Ipv4AddressNoZone end; + + private Ipv4AddressRange( + @Nonnull final Ipv4AddressNoZone start, + @Nonnull final Ipv4AddressNoZone end) { + this.start = start; + this.end = end; + } + + public Ipv4AddressNoZone getStart() { + return start; + } + + public Ipv4AddressNoZone getEnd() { + return end; + } + + @Override + public boolean equals(final Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + final Ipv4AddressRange that = (Ipv4AddressRange) other; + return Objects.equals(start, that.start) + && Objects.equals(end, that.end); + } + + @Override + public int hashCode() { + return Objects.hash(start, end); + } + + @Override + public String toString() { + return "Ipv4AddressRange{" + + "start=" + start + + ", end=" + end + + '}'; + } + + /** + * Create address range from prefix. + */ + public static Ipv4AddressRange fromPrefix(@Nonnull final Ipv4Prefix prefix) { + final String addressString = prefix.getValue().split("/")[0]; + byte prefixLength = Ipv4Translator.INSTANCE.extractPrefix(prefix); + + if (prefixLength == 32) { + // 32 Prefix can be handled instantly + return new Ipv4AddressRange(new Ipv4AddressNoZone(addressString), new Ipv4AddressNoZone(addressString)); + } + + final byte[] prefixAddrBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(addressString); + final byte[] prefixAddrBytes0 = new byte[prefixAddrBytes.length]; + final byte[] prefixAddrBytesF = new byte[prefixAddrBytes.length]; + + byte index = 0; + while (prefixLength >= 8) { + prefixAddrBytes0[index] = prefixAddrBytes[index]; + prefixAddrBytesF[index] = prefixAddrBytes[index]; + index++; + prefixLength -= 8; + } + + // Take care of the rest + if (prefixLength != 0) { + final int mask0 = (byte) (Math.pow(2, prefixLength) - 1) << (8 - prefixLength); + prefixAddrBytes0[index] = (byte) (prefixAddrBytes[index] & mask0); + + final int maskF = (byte) (Math.pow(2, 8 - prefixLength) - 1); + prefixAddrBytesF[index] = (byte) (prefixAddrBytes[index] | maskF); + + index++; + } + + for (int i = index; i < 4; i++) { + prefixAddrBytes0[i] = 0; + prefixAddrBytesF[i] = (byte) 255; + } + + return new Ipv4AddressRange( + Ipv4Translator.INSTANCE.arrayToIpv4AddressNoZoneReversed(prefixAddrBytes0), + Ipv4Translator.INSTANCE.arrayToIpv4AddressNoZoneReversed(prefixAddrBytesF)); + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4Translator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4Translator.java new file mode 100644 index 000000000..255639655 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv4Translator.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.net.InetAddresses; +import java.net.UnknownHostException; +import java.util.Arrays; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; + +/** + * Trait providing logic for translation of ipv4-related data. + */ +public interface Ipv4Translator extends ByteDataTranslator { + + /** + * Make available also from static context. + */ + Ipv4Translator INSTANCE = new Ipv4Translator() {}; + + /** + * Creates address array from address part of {@link Ipv4Prefix} + */ + default byte[] ipv4AddressPrefixToArray(@Nonnull final Ipv4Prefix ipv4Prefix) { + checkNotNull(ipv4Prefix, "Cannot convert null prefix"); + + byte[] retval = new byte[4]; + String[] address = ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/')).split("\\."); + + for (int d = 0; d < 4; d++) { + retval[d] = (byte) (Short.parseShort(address[d]) & 0xff); + } + return retval; + } + + /** + * Extracts {@link Ipv4Prefix} prefix + */ + default byte extractPrefix(Ipv4Prefix data) { + checkNotNull(data, "Cannot extract from null"); + + return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1)); + } + + /** + * Converts byte array to {@link Ipv4Prefix} with specified prefixLength + */ + default Ipv4Prefix arrayToIpv4Prefix(final byte[] address, byte prefixLength) { + Ipv4AddressNoZone addressPart = arrayToIpv4AddressNoZone(address); + + return new Ipv4Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength))); + } + + /** + * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order. + * + * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No + * change in order. + */ + @Nonnull + default Ipv4AddressNoZone arrayToIpv4AddressNoZone(@Nonnull byte[] ip) { + // VPP sends ipv4 in a 16 byte array + if (ip.length == 16) { + ip = Arrays.copyOfRange(ip, 0, 4); + } + try { + // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order + // compared to byte order it was submitted + return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Unable to parse ipv4", e); + } + } + + /** + * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order. + * + * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No + * change in order. + */ + @Nonnull + default Ipv4AddressNoZone arrayToIpv4AddressNoZoneReversed(@Nonnull byte[] ip) { + // VPP sends ipv4 in a 16 byte array + + if (ip.length == 16) { + ip = Arrays.copyOfRange(ip, 0, 4); + } + + ip = reverseBytes(ip); + + try { + // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order + // compared to byte order it was submitted + return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Unable to parse ipv4", e); + } + } + + + /** + * Transform Ipv4 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order + * as the address. + * + * @return byte array with address bytes + */ + default byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) { + return ipv4AddressNoZoneToArray(ipv4Addr.getValue()); + } + + default byte[] ipv4AddressNoZoneToArray(final String ipv4Addr) { + byte[] retval = new byte[4]; + String[] dots = ipv4Addr.split("\\."); + + for (int d = 0; d < 4; d++) { + retval[d] = (byte) (Short.parseShort(dots[d]) & 0xff); + } + return retval; + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java new file mode 100644 index 000000000..0d645c3c0 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.net.InetAddresses; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.apache.commons.lang3.StringUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; + +/** + * Trait providing logic for translation of ipv6-related data + */ +public interface Ipv6Translator extends ByteDataTranslator { + + /** + * Transform Ipv6 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order + * as the address. + * + * @return byte array with address bytes + */ + default byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6AddressNoZone ipv6Addr) { + byte[] retval = new byte[16]; + + //splits address and add ommited zeros for easier parsing + List segments = Arrays.asList(ipv6Addr.getValue().split(":")) + .stream() + .map(segment -> StringUtils.repeat('0', 4 - segment.length()) + segment) + .collect(Collectors.toList()); + + byte index = 0; + for (String segment : segments) { + + String firstPart = segment.substring(0, 2); + String secondPart = segment.substring(2); + + //first part should be ommited + if ("00".equals(firstPart)) { + index++; + } else { + retval[index++] = ((byte) Short.parseShort(firstPart, 16)); + } + + retval[index++] = ((byte) Short.parseShort(secondPart, 16)); + } + + return retval; + } + + /** + * Creates address array from address part of {@link Ipv6Prefix} + */ + default byte[] ipv6AddressPrefixToArray(@Nonnull final Ipv6Prefix ipv4Prefix) { + checkNotNull(ipv4Prefix, "Cannot convert null prefix"); + + return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone( + new Ipv6Address(ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/'))))); + } + + /** + * Extracts {@link Ipv6Prefix} prefix + */ + default byte extractPrefix(Ipv6Prefix data) { + checkNotNull(data, "Cannot extract from null"); + + return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1)); + } + + /** + * Converts byte array to {@link Ipv6Prefix} with specified prefixLength + */ + default Ipv6Prefix arrayToIpv6Prefix(final byte[] address, byte prefixLength) { + Ipv6AddressNoZone addressPart = arrayToIpv6AddressNoZone(address); + + return new Ipv6Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength))); + } + + /** + * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in reversed order. + * + * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No + * change in order. + */ + @Nonnull + default Ipv6AddressNoZone arrayToIpv6AddressNoZone(@Nonnull byte[] ip) { + checkArgument(ip.length == 16, "Illegal array length"); + + try { + return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Unable to parse ipv6", e); + } + } + + /** + * Detects whether {@code IpAddress} is ipv6 + */ + default boolean isIpv6(IpAddress address) { + checkNotNull(address, "Address cannot be null"); + + checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address"); + return address.getIpv6Address() != null; + } + + /** + * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in natural order. + * + * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No + * change in order. + */ + @Nonnull + default Ipv6AddressNoZone arrayToIpv6AddressNoZoneReversed(@Nonnull byte[] ip) { + checkArgument(ip.length == 16, "Illegal array length"); + + ip = reverseBytes(ip); + + try { + return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Unable to parse ipv6", e); + } + } + + + /** + * Detects whether {@code IpPrefix} is ipv6 + */ + default boolean isIpv6(IpPrefix address) { + checkNotNull(address, "Address cannot be null"); + checkState(!(address.getIpv4Prefix() == null && address.getIpv6Prefix() == null), "Invalid address"); + return address.getIpv6Prefix() != null; + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumer.java new file mode 100644 index 000000000..db656e721 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumer.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.dto.JVppReply; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Trait providing logic for consuming reply's to jvpp api calls + */ +public interface JvppReplyConsumer { + + int DEFAULT_TIMEOUT_IN_SECONDS = 5; + + /** + * Consumes reply for jvpp call representing any write operation + * Should be used in case of calls where it's not clear which write crud operation respective + * call represents, for ex. setRouting + */ + default > REP getReplyForWrite(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType) + throws WriteFailedException { + return getReplyForWrite(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); + } + + /** + * Consumes reply for jvpp call representing any write operation + * Should be used in case of calls where it's not clear which write crud operation respective + * call represents, for ex. setRouting + */ + default > REP getReplyForWrite(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnegative final int timeoutInSeconds) + throws WriteFailedException { + try { + return getReply(future, timeoutInSeconds); + } catch (TimeoutException e) { + throw new WriteTimeoutException(replyType, e); + } catch (VppBaseCallException e) { + throw new WriteFailedException(replyType, e); + } + + } + + /** + * Consumes reply for jvpp call representing create operation + */ + default > REP getReplyForCreate(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnull final DataObject data) + throws WriteFailedException { + return getReplyForCreate(future, replyType, data, DEFAULT_TIMEOUT_IN_SECONDS); + } + + /** + * Consumes reply for jvpp call representing create operation + */ + default > REP getReplyForCreate(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnull final DataObject data, + @Nonnegative final int timeoutInSeconds) + throws WriteFailedException { + try { + return getReply(future, timeoutInSeconds); + } catch (VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(replyType, data, e); + } catch (TimeoutException e) { + throw new WriteTimeoutException(replyType, e); + } + } + + /** + * Consumes reply for jvpp call representing update operation + */ + default > REP getReplyForUpdate(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnull final DataObject dataBefore, + @Nonnull final DataObject dataAfter) + throws WriteFailedException { + return getReplyForUpdate(future, replyType, dataBefore, dataAfter, DEFAULT_TIMEOUT_IN_SECONDS); + } + + /** + * Consumes reply for jvpp call representing update operation + */ + default > REP getReplyForUpdate(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnull final DataObject dataBefore, + @Nonnull final DataObject dataAfter, + @Nonnegative final int timeoutInSeconds) + throws WriteFailedException { + try { + return getReply(future, timeoutInSeconds); + } catch (VppBaseCallException e) { + throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter, e); + } catch (TimeoutException e) { + throw new WriteTimeoutException(replyType, e); + } + } + + /** + * Consumes reply for jvpp call representing delete operation + */ + default > REP getReplyForDelete(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType) + throws WriteFailedException { + return getReplyForDelete(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); + } + + /** + * Consumes reply for jvpp call representing delete operation + */ + default > REP getReplyForDelete(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnegative final int timeoutInSeconds) + throws WriteFailedException { + try { + return getReply(future, timeoutInSeconds); + } catch (VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(replyType, e); + } catch (TimeoutException e) { + throw new WriteTimeoutException(replyType, e); + } + } + + default > REP getReplyForRead(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType) + throws ReadFailedException { + return getReplyForRead(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); + } + + default > REP getReplyForRead(@Nonnull Future future, + @Nonnull final InstanceIdentifier replyType, + @Nonnegative final int timeoutInSeconds) + throws ReadFailedException { + try { + return getReply(future, timeoutInSeconds); + } catch (TimeoutException e) { + throw new ReadTimeoutException(replyType, e); + } catch (VppBaseCallException e) { + throw new ReadFailedException(replyType, e); + } + } + + default > REP getReply(@Nonnull Future future) + throws TimeoutException, VppBaseCallException { + return getReply(future, DEFAULT_TIMEOUT_IN_SECONDS); + } + + default > REP getReply(@Nonnull Future future, + @Nonnegative final int timeoutInSeconds) + throws TimeoutException, VppBaseCallException { + try { + checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0"); + return future.get(timeoutInSeconds, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("Interrupted", e); + } catch (ExecutionException e) { + // Execution exception could generally contains any exception + // when using exceptions instead of return codes just rethrow it for processing on corresponding place + if (e instanceof ExecutionException && (e.getCause() instanceof VppBaseCallException)) { + throw (VppBaseCallException) (e.getCause()); + } + throw new IllegalStateException(e); + } + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/MacTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/MacTranslator.java new file mode 100644 index 000000000..b31dc30b2 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/MacTranslator.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Splitter; +import java.util.Arrays; +import java.util.List; +import java.util.function.BiConsumer; +import javax.annotation.Nonnull; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; + +/** + * Trait providing logic for translation of MAC address data + */ +public interface MacTranslator { + + Splitter COLON_SPLITTER = Splitter.on(':'); + + /** + * Parse string represented mac address (using ":" as separator) into a byte array + */ + @Nonnull + default byte[] parseMac(@Nonnull final String macAddress) { + final List parts = COLON_SPLITTER.splitToList(macAddress); + checkArgument(parts.size() == 6, "Mac address is expected to have 6 parts but was: %s", macAddress); + return parseMacLikeString(parts); + } + + default byte[] parseMacLikeString(final List strings) { + return strings.stream().limit(6).map(this::parseHexByte).collect( + () -> new byte[strings.size()], + new BiConsumer() { + + private int i = -1; + + @Override + public void accept(final byte[] bytes, final Byte aByte) { + bytes[++i] = aByte; + } + }, + (bytes, bytes2) -> { + throw new UnsupportedOperationException("Parallel collect not supported"); + }); + } + + /** + * Converts byte array to address string ,not separated with ":" + */ + default String byteArrayToMacUnseparated(byte[] address) { + checkArgument(address.length >= 6, "Illegal array length"); + return Hex.encodeHexString(Arrays.copyOf(address, 6)); + } + + /** + * Converts byte array to address string ,separated with ":" + */ + default String byteArrayToMacSeparated(byte[] address) { + checkArgument(address.length >= 6, "Illegal array length"); + + String unseparatedAddress = Hex.encodeHexString(Arrays.copyOf(address, 6)); + String separated = ""; + + for (int i = 0; i < unseparatedAddress.length(); i = i + 2) { + if (i == (unseparatedAddress.length() - 2)) { + separated = separated + unseparatedAddress.substring(0 + i, 2 + i); + } else { + separated = separated + unseparatedAddress.substring(0 + i, 2 + i) + ":"; + } + } + + return separated; + } + + /** + * Converts MAC string to byte array + */ + default byte[] macToByteArray(String mac) { + checkNotNull(mac, "MAC cannot be null"); + + mac = mac.replace(":", ""); + + try { + return Hex.decodeHex(mac.toCharArray()); + } catch (DecoderException e) { + throw new IllegalArgumentException("Unable to convert mac", e); + } + } + + default byte parseHexByte(final String aByte) { + return (byte) Integer.parseInt(aByte, 16); + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/NamingContext.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/NamingContext.java new file mode 100644 index 000000000..393df0898 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/NamingContext.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Utility adapter on top of {@link MappingContext} storing integer to string mappings according to naming-context yang + * model. + */ +public final class NamingContext implements AutoCloseable { + + private static final Collector SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); + private final String artificialNamePrefix; + private final KeyedInstanceIdentifier + namingContextIid; + + /** + * Create new naming context + * + * @param artificialNamePrefix artificial name to be used for items without a name in VPP (or not provided) + * @param instanceName name of this context instance. Will be used as list item identifier within context + * data tree + */ + public NamingContext(@Nonnull final String artificialNamePrefix, @Nonnull final String instanceName) { + this.artificialNamePrefix = artificialNamePrefix; + namingContextIid = InstanceIdentifier.create(Contexts.class).child( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.class, + new NamingContextKey(instanceName)); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. If not present, artificial name will be + * generated. + * + * @param index index of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized String getName(final int index, @Nonnull final MappingContext mappingContext) { + if (!containsName(index, mappingContext)) { + final String artificialName = getArtificialName(index); + addName(index, artificialName, mappingContext); + } + + final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); + checkState(read.isPresent(), "Mapping for index: %s is not present. But should be", index); + + return read.get().getMapping().stream() + .filter(mapping -> mapping.getIndex().equals(index)) + .collect(SINGLE_ITEM_COLLECTOR).getName(); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. if present + * + * @param index index of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized Optional getNameIfPresent(final int index, + @Nonnull final MappingContext mappingContext) { + final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); + + return read.isPresent() + ? Optional.of(read.get().getMapping().stream() + .filter(mapping -> mapping.getIndex().equals(index)) + .collect(SINGLE_ITEM_COLLECTOR) + .getName()) + : Optional.absent(); + } + + /** + * Check whether mapping is present for index. + * + * @param index index of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { + final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); + return read.isPresent() + ? read.get().getMapping().stream().anyMatch(mapping -> mapping.getIndex().equals(index)) + : false; + } + + + /** + * Add mapping to current context + * + * @param index index of a mapped item + * @param name name of a mapped item + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void addName(final int index, final String name, final MappingContext mappingContext) { + final KeyedInstanceIdentifier mappingIid = getMappingIid(name); + mappingContext.put(mappingIid, new MappingBuilder().setIndex(index).setName(name).build()); + } + + private KeyedInstanceIdentifier getMappingIid(final String name) { + return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(name)); + } + + /** + * Remove mapping from current context + * + * @param name name of a mapped item + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void removeName(final String name, final MappingContext mappingContext) { + mappingContext.delete(getMappingIid(name)); + } + + /** + * Returns index value associated with the given name. + * + * @param name the name whose associated index value is to be returned + * @param mappingContext mapping context providing context data for current transaction + * @return integer index value matching supplied name + * @throws IllegalArgumentException if name was not found + */ + public synchronized int getIndex(final String name, final MappingContext mappingContext) { + final Optional read = mappingContext.read(getMappingIid(name)); + checkArgument(read.isPresent(), "No mapping stored for name: %s", name); + return read.get().getIndex(); + + } + + /** + * Check whether mapping is present for name. + * + * @param name name of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsIndex(final String name, final MappingContext mappingContext) { + return mappingContext.read(getMappingIid(name)).isPresent(); + } + + private String getArtificialName(final int index) { + return artificialNamePrefix + index; + } + + @Override + public void close() throws Exception { + /// Not removing the mapping from backing storage + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ReadTimeoutException.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ReadTimeoutException.java new file mode 100644 index 000000000..e9c451791 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/ReadTimeoutException.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import com.google.common.annotations.Beta; +import io.fd.honeycomb.translate.read.ReadFailedException; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Thrown when read method invocation times out. + */ +@Beta +public class ReadTimeoutException extends ReadFailedException { + + public ReadTimeoutException(final InstanceIdentifier id, final Throwable cause) { + super(id, cause); + } + +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/TagRewriteOperation.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/TagRewriteOperation.java new file mode 100644 index 000000000..32b2b16cd --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/TagRewriteOperation.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import com.google.common.base.Preconditions; +import com.google.common.primitives.UnsignedBytes; +import javax.annotation.Nonnegative; +import javax.annotation.Nullable; + +/** + * Defines vlan tag rewrite config options for VPP. + *

+ * TODO HONEYCOMB-184 corresponding enum (defined in l2_vtr.h) should be defined in vpe.api + * (does vpp's IDL support enum type definition?) + * which would allow to generate this class in jvpp + */ +public enum TagRewriteOperation { + disabled(0), + push_1(0), + push_2(0), + pop_1(1), + pop_2(2), + translate_1_to_1(1), + translate_1_to_2(1), + translate_2_to_1(2), + translate_2_to_2(2); + + private static final int MAX_INDEX = 3; + private static TagRewriteOperation[][] translation = new TagRewriteOperation[][]{ + {disabled, push_1, push_2}, + {pop_1, translate_1_to_1, translate_1_to_2}, + {pop_2, translate_2_to_1, translate_2_to_2} + }; + private final int code; + private final byte popTags; + + TagRewriteOperation(final int popTags) { + this.code = this.ordinal(); + this.popTags = UnsignedBytes.checkedCast(popTags); + } + + /** + * Returns VPP tag rewrite operation for given number of tags to pop and tags to push. + * + * @param toPop number of tags to pop (0..2) + * @param toPush number of tags to push (0..2) + * @return vpp tag rewrite operation for given input parameters + */ + public static TagRewriteOperation get(@Nonnegative final int toPop, @Nonnegative final int toPush) { + Preconditions.checkElementIndex(toPop, MAX_INDEX, "Illegal number of tags to pop"); + Preconditions.checkElementIndex(toPush, MAX_INDEX, "Illegal number of tags to push"); + return translation[toPop][toPush]; + } + + /** + * Returns VPP tag rewrite operation for given operation code. + * + * @param code VPP tag rewrite operation code + * @return vpp tag rewrite operation for given input parameter + */ + @Nullable + public static TagRewriteOperation get(@Nonnegative final int code) { + for (TagRewriteOperation operation : TagRewriteOperation.values()) { + if (code == operation.code) { + return operation; + } + } + return null; + } + + public byte getPopTags() { + return popTags; + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/VppStatusListener.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/VppStatusListener.java new file mode 100644 index 000000000..5377f5786 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/VppStatusListener.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Listens to vpp status changes. Restarts honeycomb if vpp is down. + */ +public final class VppStatusListener implements KeepaliveReaderWrapper.KeepaliveFailureListener { + + /** + * Value picked up by honeycomb start script, tigers honeycomb restart when returned by the java process + */ + public static final int RESTART_ERROR_CODE = 100; + private static final Logger LOG = LoggerFactory.getLogger(VppStatusListener.class); + + private volatile boolean down; + + public boolean isDown() { + return down; + } + + @Override + public void onKeepaliveFailure() { + LOG.error("Keepalive failed. VPP is probably DOWN! Restarting Honeycomb"); + this.down = true; + System.exit(RESTART_ERROR_CODE); + } +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/WriteTimeoutException.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/WriteTimeoutException.java new file mode 100644 index 000000000..d762201ff --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/WriteTimeoutException.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import com.google.common.annotations.Beta; +import io.fd.honeycomb.translate.write.WriteFailedException; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Thrown when write method invocation times out. + */ +@Beta +public class WriteTimeoutException extends WriteFailedException { + + public WriteTimeoutException(final InstanceIdentifier id, final Throwable cause) { + super(id, cause); + } + +} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AbstractInterfaceTypeCustomizer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AbstractInterfaceTypeCustomizer.java deleted file mode 100644 index faf9be5d8..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AbstractInterfaceTypeCustomizer.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.spi.write.WriterCustomizer; -import io.fd.honeycomb.translate.write.WriteContext; -import io.fd.honeycomb.translate.write.WriteFailedException; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -/** - * Validation WriteCustomizers for Interface subnodes. - * Validates the type of interface. - */ -public abstract class AbstractInterfaceTypeCustomizer - extends FutureJVppCustomizer implements WriterCustomizer { - - protected AbstractInterfaceTypeCustomizer(final FutureJVppCore futureJVppCore) { - super(futureJVppCore); - } - - private void checkProperInterfaceType(@Nonnull final WriteContext writeContext, - @Nonnull final InstanceIdentifier id) { - final InstanceIdentifier ifcTypeFromIid = id.firstIdentifierOf(Interface.class); - checkArgument(ifcTypeFromIid != null, "Instance identifier does not contain {} type", Interface.class); - checkArgument(id.firstKeyOf(Interface.class) != null, "Instance identifier does not contain keyed {} type", - Interface.class); - final Optional interfaceConfig = writeContext.readAfter(ifcTypeFromIid); - checkState(interfaceConfig.isPresent(), - "Unable to get Interface configuration for an interface: %s currently being updated", ifcTypeFromIid); - - IllegalInterfaceTypeException - .checkInterfaceType(interfaceConfig.get(), getExpectedInterfaceType()); - } - - protected abstract Class getExpectedInterfaceType(); - - /** - * Validate expected interface type - */ - @Override - public final void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final D dataAfter, - @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkProperInterfaceType(writeContext, id); - writeInterface(id, dataAfter, writeContext); - } - - protected abstract void writeInterface(final InstanceIdentifier id, final D dataAfter, - final WriteContext writeContext) - throws WriteFailedException; - - // Validation for update and delete is not necessary - - /** - * Indicates unexpected interface type - */ - protected static final class IllegalInterfaceTypeException extends IllegalArgumentException { - - private IllegalInterfaceTypeException(final String msg) { - super(msg); - } - - /** - * Check the type of interface equals expected type - * - * @throws IllegalInterfaceTypeException if type of interface is null or not expected - */ - static void checkInterfaceType(@Nonnull final Interface ifc, - @Nonnull final Class expectedType) { - if (ifc.getType() == null || !expectedType.equals(ifc.getType())) { - throw new IllegalInterfaceTypeException(String.format( - "Unexpected interface type: %s for interface: %s. Expected interface is: %s", ifc.getType(), - ifc.getName(), expectedType)); - } - } - - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AddressTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AddressTranslator.java deleted file mode 100644 index bfcb41e3c..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/AddressTranslator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkNotNull; - -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -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.Ipv4AddressNoZone; -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.Ipv6AddressNoZone; - -/** - * Aggregation trait providing logic for converting address based data - */ -public interface AddressTranslator extends Ipv4Translator, Ipv6Translator, MacTranslator { - - default byte[] ipAddressToArray(IpAddress address) { - checkNotNull(address, "Cannot resolve null adddress"); - - if (isIpv6(address)) { - return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(address.getIpv6Address())); - } else { - return ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(address.getIpv4Address())); - } - } - - - /** - * Converts {@link IpAddress} to array representing {@link Ipv4Address} or {@link Ipv6Address} - */ - default byte[] ipAddressToArray(boolean isIpv6, @Nonnull IpAddress address) { - checkNotNull(address, "Cannot convert null Address"); - - if (isIpv6) { - return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(address.getIpv6Address())); - } else { - return ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(address.getIpv4Address())); - } - } - - /** - * Converts array bytes to {@link IpAddress}. - */ - @Nonnull - default IpAddress arrayToIpAddress(boolean isIpv6, byte[] ip) { - if (isIpv6) { - return new IpAddress(arrayToIpv6AddressNoZone(ip)); - } else { - return new IpAddress(arrayToIpv4AddressNoZone(ip)); - } - } - - /** - * Converts array bytes to {@link IpAddress} - */ - @Nonnull - default IpAddress arrayToIpAddressReversed(boolean isIpv6, byte[] ip) { - if (isIpv6) { - return new IpAddress(arrayToIpv6AddressNoZoneReversed(ip)); - } else { - return new IpAddress(arrayToIpv4AddressNoZoneReversed(ip)); - } - } - - default IpAddress reverseAddress(@Nonnull final IpAddress address) { - //arrayToIpAdddress internaly reverts order - return arrayToIpAddress(isIpv6(address), ipAddressToArray(address)); - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslator.java deleted file mode 100644 index b7df219aa..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslator.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -/** - * Trait providing logic for working with binary-based data - */ -public interface ByteDataTranslator { - - /** - * Returns 0 if argument is null or false, 1 otherwise. - * - * @param value Boolean value to be converted - * @return byte value equal to 0 or 1 - */ - default byte booleanToByte(@Nullable final Boolean value) { - return value != null && value - ? (byte) 1 - : (byte) 0; - } - - /** - * Returns Boolean.TRUE if argument is 0, Boolean.FALSE otherwise. - * - * @param value byte value to be converted - * @return Boolean value - * @throws IllegalArgumentException if argument is neither 0 nor 1 - */ - @Nonnull - default Boolean byteToBoolean(final byte value) { - if (value == 0) { - return Boolean.FALSE; - } else if (value == 1) { - return Boolean.TRUE; - } - throw new IllegalArgumentException(String.format("0 or 1 was expected but was %d", value)); - } - - /** - * Reverses bytes in the byte array - * - * @param bytes input array - * @return reversed array - */ - default byte[] reverseBytes(final byte[] bytes) { - final byte[] reversed = new byte[bytes.length]; - int i = 1; - for (byte aByte : bytes) { - reversed[bytes.length - i++] = aByte; - } - - return reversed; - } - - /** - * Return (interned) string from byte array while removing \u0000. Strings represented as fixed length byte[] from - * vpp contain \u0000. - */ - default String toString(final byte[] cString) { - return new String(cString).replaceAll("\\u0000", "").intern(); - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/FutureJVppCustomizer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/FutureJVppCustomizer.java deleted file mode 100644 index 2a43ab503..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/FutureJVppCustomizer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import com.google.common.annotations.Beta; -import com.google.common.base.Preconditions; -import javax.annotation.Nonnull; -import io.fd.vpp.jvpp.core.future.FutureJVppCore; - -/** - * Abstract utility to hold the vppApi reference. - */ -@Beta -public abstract class FutureJVppCustomizer { - - private final FutureJVppCore futureJVppCore; - - public FutureJVppCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { - this.futureJVppCore = Preconditions.checkNotNull(futureJVppCore, "futureJVppCore should not be null"); - } - - /** - * Get vppApi reference - * - * @return vppApi reference - */ - public FutureJVppCore getFutureJVpp() { - return futureJVppCore; - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRange.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRange.java deleted file mode 100644 index 7528c5464..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRange.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import java.util.Objects; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * IPv4 address range representation. - */ -public final class Ipv4AddressRange { - - private static final Logger LOG = LoggerFactory.getLogger(Ipv4AddressRange.class); - - private final Ipv4AddressNoZone start; - private final Ipv4AddressNoZone end; - - private Ipv4AddressRange( - @Nonnull final Ipv4AddressNoZone start, - @Nonnull final Ipv4AddressNoZone end) { - this.start = start; - this.end = end; - } - - public Ipv4AddressNoZone getStart() { - return start; - } - - public Ipv4AddressNoZone getEnd() { - return end; - } - - @Override - public boolean equals(final Object other) { - if (this == other) { - return true; - } - if (other == null || getClass() != other.getClass()) { - return false; - } - final Ipv4AddressRange that = (Ipv4AddressRange) other; - return Objects.equals(start, that.start) - && Objects.equals(end, that.end); - } - - @Override - public int hashCode() { - return Objects.hash(start, end); - } - - @Override - public String toString() { - return "Ipv4AddressRange{" - + "start=" + start - + ", end=" + end - + '}'; - } - - /** - * Create address range from prefix. - */ - public static Ipv4AddressRange fromPrefix(@Nonnull final Ipv4Prefix prefix) { - final String addressString = prefix.getValue().split("/")[0]; - byte prefixLength = Ipv4Translator.INSTANCE.extractPrefix(prefix); - - if (prefixLength == 32) { - // 32 Prefix can be handled instantly - return new Ipv4AddressRange(new Ipv4AddressNoZone(addressString), new Ipv4AddressNoZone(addressString)); - } - - final byte[] prefixAddrBytes = Ipv4Translator.INSTANCE.ipv4AddressNoZoneToArray(addressString); - final byte[] prefixAddrBytes0 = new byte[prefixAddrBytes.length]; - final byte[] prefixAddrBytesF = new byte[prefixAddrBytes.length]; - - byte index = 0; - while (prefixLength >= 8) { - prefixAddrBytes0[index] = prefixAddrBytes[index]; - prefixAddrBytesF[index] = prefixAddrBytes[index]; - index++; - prefixLength -= 8; - } - - // Take care of the rest - if (prefixLength != 0) { - final int mask0 = (byte) (Math.pow(2, prefixLength) - 1) << (8 - prefixLength); - prefixAddrBytes0[index] = (byte) (prefixAddrBytes[index] & mask0); - - final int maskF = (byte) (Math.pow(2, 8 - prefixLength) - 1); - prefixAddrBytesF[index] = (byte) (prefixAddrBytes[index] | maskF); - - index++; - } - - for (int i = index; i < 4; i++) { - prefixAddrBytes0[i] = 0; - prefixAddrBytesF[i] = (byte) 255; - } - - return new Ipv4AddressRange( - Ipv4Translator.INSTANCE.arrayToIpv4AddressNoZoneReversed(prefixAddrBytes0), - Ipv4Translator.INSTANCE.arrayToIpv4AddressNoZoneReversed(prefixAddrBytesF)); - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4Translator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4Translator.java deleted file mode 100644 index b5f93dfba..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv4Translator.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.net.InetAddresses; -import java.net.UnknownHostException; -import java.util.Arrays; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; - -/** - * Trait providing logic for translation of ipv4-related data. - */ -public interface Ipv4Translator extends ByteDataTranslator { - - /** - * Make available also from static context. - */ - Ipv4Translator INSTANCE = new Ipv4Translator() {}; - - /** - * Creates address array from address part of {@link Ipv4Prefix} - */ - default byte[] ipv4AddressPrefixToArray(@Nonnull final Ipv4Prefix ipv4Prefix) { - checkNotNull(ipv4Prefix, "Cannot convert null prefix"); - - byte[] retval = new byte[4]; - String[] address = ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/')).split("\\."); - - for (int d = 0; d < 4; d++) { - retval[d] = (byte) (Short.parseShort(address[d]) & 0xff); - } - return retval; - } - - /** - * Extracts {@link Ipv4Prefix} prefix - */ - default byte extractPrefix(Ipv4Prefix data) { - checkNotNull(data, "Cannot extract from null"); - - return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1)); - } - - /** - * Converts byte array to {@link Ipv4Prefix} with specified prefixLength - */ - default Ipv4Prefix arrayToIpv4Prefix(final byte[] address, byte prefixLength) { - Ipv4AddressNoZone addressPart = arrayToIpv4AddressNoZone(address); - - return new Ipv4Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength))); - } - - /** - * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order. - * - * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No - * change in order. - */ - @Nonnull - default Ipv4AddressNoZone arrayToIpv4AddressNoZone(@Nonnull byte[] ip) { - // VPP sends ipv4 in a 16 byte array - if (ip.length == 16) { - ip = Arrays.copyOfRange(ip, 0, 4); - } - try { - // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order - // compared to byte order it was submitted - return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Unable to parse ipv4", e); - } - } - - /** - * Parse byte array returned by VPP representing an Ipv4 address. Vpp returns IP byte arrays in reversed order. - * - * @return Ipv4AddressNoZone containing string representation of IPv4 address constructed from submitted bytes. No - * change in order. - */ - @Nonnull - default Ipv4AddressNoZone arrayToIpv4AddressNoZoneReversed(@Nonnull byte[] ip) { - // VPP sends ipv4 in a 16 byte array - - if (ip.length == 16) { - ip = Arrays.copyOfRange(ip, 0, 4); - } - - ip = reverseBytes(ip); - - try { - // Not reversing the byte array here!! because the IP coming from VPP is in reversed byte order - // compared to byte order it was submitted - return new Ipv4AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Unable to parse ipv4", e); - } - } - - - /** - * Transform Ipv4 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order - * as the address. - * - * @return byte array with address bytes - */ - default byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) { - return ipv4AddressNoZoneToArray(ipv4Addr.getValue()); - } - - default byte[] ipv4AddressNoZoneToArray(final String ipv4Addr) { - byte[] retval = new byte[4]; - String[] dots = ipv4Addr.split("\\."); - - for (int d = 0; d < 4; d++) { - retval[d] = (byte) (Short.parseShort(dots[d]) & 0xff); - } - return retval; - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv6Translator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv6Translator.java deleted file mode 100644 index 6197b38ef..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/Ipv6Translator.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.net.InetAddresses; -import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.apache.commons.lang3.StringUtils; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; -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.Ipv6AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; - -/** - * Trait providing logic for translation of ipv6-related data - */ -public interface Ipv6Translator extends ByteDataTranslator { - - /** - * Transform Ipv6 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order - * as the address. - * - * @return byte array with address bytes - */ - default byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6AddressNoZone ipv6Addr) { - byte[] retval = new byte[16]; - - //splits address and add ommited zeros for easier parsing - List segments = Arrays.asList(ipv6Addr.getValue().split(":")) - .stream() - .map(segment -> StringUtils.repeat('0', 4 - segment.length()) + segment) - .collect(Collectors.toList()); - - byte index = 0; - for (String segment : segments) { - - String firstPart = segment.substring(0, 2); - String secondPart = segment.substring(2); - - //first part should be ommited - if ("00".equals(firstPart)) { - index++; - } else { - retval[index++] = ((byte) Short.parseShort(firstPart, 16)); - } - - retval[index++] = ((byte) Short.parseShort(secondPart, 16)); - } - - return retval; - } - - /** - * Creates address array from address part of {@link Ipv6Prefix} - */ - default byte[] ipv6AddressPrefixToArray(@Nonnull final Ipv6Prefix ipv4Prefix) { - checkNotNull(ipv4Prefix, "Cannot convert null prefix"); - - return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone( - new Ipv6Address(ipv4Prefix.getValue().substring(0, ipv4Prefix.getValue().indexOf('/'))))); - } - - /** - * Extracts {@link Ipv6Prefix} prefix - */ - default byte extractPrefix(Ipv6Prefix data) { - checkNotNull(data, "Cannot extract from null"); - - return Byte.valueOf(data.getValue().substring(data.getValue().indexOf('/') + 1)); - } - - /** - * Converts byte array to {@link Ipv6Prefix} with specified prefixLength - */ - default Ipv6Prefix arrayToIpv6Prefix(final byte[] address, byte prefixLength) { - Ipv6AddressNoZone addressPart = arrayToIpv6AddressNoZone(address); - - return new Ipv6Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength))); - } - - /** - * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in reversed order. - * - * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No - * change in order. - */ - @Nonnull - default Ipv6AddressNoZone arrayToIpv6AddressNoZone(@Nonnull byte[] ip) { - checkArgument(ip.length == 16, "Illegal array length"); - - try { - return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Unable to parse ipv6", e); - } - } - - /** - * Detects whether {@code IpAddress} is ipv6 - */ - default boolean isIpv6(IpAddress address) { - checkNotNull(address, "Address cannot be null"); - - checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address"); - return address.getIpv6Address() != null; - } - - /** - * Parse byte array returned by VPP representing an Ipv6 address. Vpp returns IP byte arrays in natural order. - * - * @return Ipv46ddressNoZone containing string representation of IPv6 address constructed from submitted bytes. No - * change in order. - */ - @Nonnull - default Ipv6AddressNoZone arrayToIpv6AddressNoZoneReversed(@Nonnull byte[] ip) { - checkArgument(ip.length == 16, "Illegal array length"); - - ip = reverseBytes(ip); - - try { - return new Ipv6AddressNoZone(InetAddresses.toAddrString(InetAddresses.fromLittleEndianByteArray(ip))); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Unable to parse ipv6", e); - } - } - - - /** - * Detects whether {@code IpPrefix} is ipv6 - */ - default boolean isIpv6(IpPrefix address) { - checkNotNull(address, "Address cannot be null"); - checkState(!(address.getIpv4Prefix() == null && address.getIpv6Prefix() == null), "Invalid address"); - return address.getIpv6Prefix() != null; - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumer.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumer.java deleted file mode 100644 index 9e85c5d8b..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumer.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkArgument; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.VppBaseCallException; -import io.fd.vpp.jvpp.dto.JVppReply; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import javax.annotation.Nonnegative; -import javax.annotation.Nonnull; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Trait providing logic for consuming reply's to jvpp api calls - */ -public interface JvppReplyConsumer { - - int DEFAULT_TIMEOUT_IN_SECONDS = 5; - - /** - * Consumes reply for jvpp call representing any write operation - * Should be used in case of calls where it's not clear which write crud operation respective - * call represents, for ex. setRouting - */ - default > REP getReplyForWrite(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType) - throws WriteFailedException { - return getReplyForWrite(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); - } - - /** - * Consumes reply for jvpp call representing any write operation - * Should be used in case of calls where it's not clear which write crud operation respective - * call represents, for ex. setRouting - */ - default > REP getReplyForWrite(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnegative final int timeoutInSeconds) - throws WriteFailedException { - try { - return getReply(future, timeoutInSeconds); - } catch (TimeoutException e) { - throw new WriteTimeoutException(replyType, e); - } catch (VppBaseCallException e) { - throw new WriteFailedException(replyType, e); - } - - } - - /** - * Consumes reply for jvpp call representing create operation - */ - default > REP getReplyForCreate(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnull final DataObject data) - throws WriteFailedException { - return getReplyForCreate(future, replyType, data, DEFAULT_TIMEOUT_IN_SECONDS); - } - - /** - * Consumes reply for jvpp call representing create operation - */ - default > REP getReplyForCreate(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnull final DataObject data, - @Nonnegative final int timeoutInSeconds) - throws WriteFailedException { - try { - return getReply(future, timeoutInSeconds); - } catch (VppBaseCallException e) { - throw new WriteFailedException.CreateFailedException(replyType, data, e); - } catch (TimeoutException e) { - throw new WriteTimeoutException(replyType, e); - } - } - - /** - * Consumes reply for jvpp call representing update operation - */ - default > REP getReplyForUpdate(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnull final DataObject dataBefore, - @Nonnull final DataObject dataAfter) - throws WriteFailedException { - return getReplyForUpdate(future, replyType, dataBefore, dataAfter, DEFAULT_TIMEOUT_IN_SECONDS); - } - - /** - * Consumes reply for jvpp call representing update operation - */ - default > REP getReplyForUpdate(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnull final DataObject dataBefore, - @Nonnull final DataObject dataAfter, - @Nonnegative final int timeoutInSeconds) - throws WriteFailedException { - try { - return getReply(future, timeoutInSeconds); - } catch (VppBaseCallException e) { - throw new WriteFailedException.UpdateFailedException(replyType, dataBefore, dataAfter, e); - } catch (TimeoutException e) { - throw new WriteTimeoutException(replyType, e); - } - } - - /** - * Consumes reply for jvpp call representing delete operation - */ - default > REP getReplyForDelete(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType) - throws WriteFailedException { - return getReplyForDelete(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); - } - - /** - * Consumes reply for jvpp call representing delete operation - */ - default > REP getReplyForDelete(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnegative final int timeoutInSeconds) - throws WriteFailedException { - try { - return getReply(future, timeoutInSeconds); - } catch (VppBaseCallException e) { - throw new WriteFailedException.DeleteFailedException(replyType, e); - } catch (TimeoutException e) { - throw new WriteTimeoutException(replyType, e); - } - } - - default > REP getReplyForRead(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType) - throws ReadFailedException { - return getReplyForRead(future, replyType, DEFAULT_TIMEOUT_IN_SECONDS); - } - - default > REP getReplyForRead(@Nonnull Future future, - @Nonnull final InstanceIdentifier replyType, - @Nonnegative final int timeoutInSeconds) - throws ReadFailedException { - try { - return getReply(future, timeoutInSeconds); - } catch (TimeoutException e) { - throw new ReadTimeoutException(replyType, e); - } catch (VppBaseCallException e) { - throw new ReadFailedException(replyType, e); - } - } - - default > REP getReply(@Nonnull Future future) - throws TimeoutException, VppBaseCallException { - return getReply(future, DEFAULT_TIMEOUT_IN_SECONDS); - } - - default > REP getReply(@Nonnull Future future, - @Nonnegative final int timeoutInSeconds) - throws TimeoutException, VppBaseCallException { - try { - checkArgument(timeoutInSeconds > 0, "Timeout cannot be < 0"); - return future.get(timeoutInSeconds, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw new IllegalStateException("Interrupted", e); - } catch (ExecutionException e) { - // Execution exception could generally contains any exception - // when using exceptions instead of return codes just rethrow it for processing on corresponding place - if (e instanceof ExecutionException && (e.getCause() instanceof VppBaseCallException)) { - throw (VppBaseCallException) (e.getCause()); - } - throw new IllegalStateException(e); - } - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/MacTranslator.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/MacTranslator.java deleted file mode 100644 index 14cc28909..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/MacTranslator.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.Splitter; -import java.util.Arrays; -import java.util.List; -import java.util.function.BiConsumer; -import javax.annotation.Nonnull; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; - -/** - * Trait providing logic for translation of MAC address data - */ -public interface MacTranslator { - - Splitter COLON_SPLITTER = Splitter.on(':'); - - /** - * Parse string represented mac address (using ":" as separator) into a byte array - */ - @Nonnull - default byte[] parseMac(@Nonnull final String macAddress) { - final List parts = COLON_SPLITTER.splitToList(macAddress); - checkArgument(parts.size() == 6, "Mac address is expected to have 6 parts but was: %s", macAddress); - return parseMacLikeString(parts); - } - - default byte[] parseMacLikeString(final List strings) { - return strings.stream().limit(6).map(this::parseHexByte).collect( - () -> new byte[strings.size()], - new BiConsumer() { - - private int i = -1; - - @Override - public void accept(final byte[] bytes, final Byte aByte) { - bytes[++i] = aByte; - } - }, - (bytes, bytes2) -> { - throw new UnsupportedOperationException("Parallel collect not supported"); - }); - } - - /** - * Converts byte array to address string ,not separated with ":" - */ - default String byteArrayToMacUnseparated(byte[] address) { - checkArgument(address.length >= 6, "Illegal array length"); - return Hex.encodeHexString(Arrays.copyOf(address, 6)); - } - - /** - * Converts byte array to address string ,separated with ":" - */ - default String byteArrayToMacSeparated(byte[] address) { - checkArgument(address.length >= 6, "Illegal array length"); - - String unseparatedAddress = Hex.encodeHexString(Arrays.copyOf(address, 6)); - String separated = ""; - - for (int i = 0; i < unseparatedAddress.length(); i = i + 2) { - if (i == (unseparatedAddress.length() - 2)) { - separated = separated + unseparatedAddress.substring(0 + i, 2 + i); - } else { - separated = separated + unseparatedAddress.substring(0 + i, 2 + i) + ":"; - } - } - - return separated; - } - - /** - * Converts MAC string to byte array - */ - default byte[] macToByteArray(String mac) { - checkNotNull(mac, "MAC cannot be null"); - - mac = mac.replace(":", ""); - - try { - return Hex.decodeHex(mac.toCharArray()); - } catch (DecoderException e) { - throw new IllegalArgumentException("Unable to convert mac", e); - } - } - - default byte parseHexByte(final String aByte) { - return (byte) Integer.parseInt(aByte, 16); - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/NamingContext.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/NamingContext.java deleted file mode 100644 index 467ac5161..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/NamingContext.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.MappingContext; -import io.fd.honeycomb.translate.util.RWUtils; -import java.util.stream.Collector; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder; -import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -/** - * Utility adapter on top of {@link MappingContext} storing integer to string mappings according to naming-context yang - * model. - */ -public final class NamingContext implements AutoCloseable { - - private static final Collector SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); - private final String artificialNamePrefix; - private final KeyedInstanceIdentifier - namingContextIid; - - /** - * Create new naming context - * - * @param artificialNamePrefix artificial name to be used for items without a name in VPP (or not provided) - * @param instanceName name of this context instance. Will be used as list item identifier within context - * data tree - */ - public NamingContext(@Nonnull final String artificialNamePrefix, @Nonnull final String instanceName) { - this.artificialNamePrefix = artificialNamePrefix; - namingContextIid = InstanceIdentifier.create(Contexts.class).child( - org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.class, - new NamingContextKey(instanceName)); - } - - /** - * Retrieve name for mapping stored provided mappingContext instance. If not present, artificial name will be - * generated. - * - * @param index index of a mapped item - * @param mappingContext mapping context providing context data for current transaction - * @return name mapped to provided index - */ - @Nonnull - public synchronized String getName(final int index, @Nonnull final MappingContext mappingContext) { - if (!containsName(index, mappingContext)) { - final String artificialName = getArtificialName(index); - addName(index, artificialName, mappingContext); - } - - final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); - checkState(read.isPresent(), "Mapping for index: %s is not present. But should be", index); - - return read.get().getMapping().stream() - .filter(mapping -> mapping.getIndex().equals(index)) - .collect(SINGLE_ITEM_COLLECTOR).getName(); - } - - /** - * Retrieve name for mapping stored provided mappingContext instance. if present - * - * @param index index of a mapped item - * @param mappingContext mapping context providing context data for current transaction - * @return name mapped to provided index - */ - @Nonnull - public synchronized Optional getNameIfPresent(final int index, - @Nonnull final MappingContext mappingContext) { - final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); - - return read.isPresent() - ? Optional.of(read.get().getMapping().stream() - .filter(mapping -> mapping.getIndex().equals(index)) - .collect(SINGLE_ITEM_COLLECTOR) - .getName()) - : Optional.absent(); - } - - /** - * Check whether mapping is present for index. - * - * @param index index of a mapped item - * @param mappingContext mapping context providing context data for current transaction - * @return true if present, false otherwise - */ - public synchronized boolean containsName(final int index, @Nonnull final MappingContext mappingContext) { - final Optional read = mappingContext.read(namingContextIid.child(Mappings.class)); - return read.isPresent() - ? read.get().getMapping().stream().anyMatch(mapping -> mapping.getIndex().equals(index)) - : false; - } - - - /** - * Add mapping to current context - * - * @param index index of a mapped item - * @param name name of a mapped item - * @param mappingContext mapping context providing context data for current transaction - */ - public synchronized void addName(final int index, final String name, final MappingContext mappingContext) { - final KeyedInstanceIdentifier mappingIid = getMappingIid(name); - mappingContext.put(mappingIid, new MappingBuilder().setIndex(index).setName(name).build()); - } - - private KeyedInstanceIdentifier getMappingIid(final String name) { - return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(name)); - } - - /** - * Remove mapping from current context - * - * @param name name of a mapped item - * @param mappingContext mapping context providing context data for current transaction - */ - public synchronized void removeName(final String name, final MappingContext mappingContext) { - mappingContext.delete(getMappingIid(name)); - } - - /** - * Returns index value associated with the given name. - * - * @param name the name whose associated index value is to be returned - * @param mappingContext mapping context providing context data for current transaction - * @return integer index value matching supplied name - * @throws IllegalArgumentException if name was not found - */ - public synchronized int getIndex(final String name, final MappingContext mappingContext) { - final Optional read = mappingContext.read(getMappingIid(name)); - checkArgument(read.isPresent(), "No mapping stored for name: %s", name); - return read.get().getIndex(); - - } - - /** - * Check whether mapping is present for name. - * - * @param name name of a mapped item - * @param mappingContext mapping context providing context data for current transaction - * @return true if present, false otherwise - */ - public synchronized boolean containsIndex(final String name, final MappingContext mappingContext) { - return mappingContext.read(getMappingIid(name)).isPresent(); - } - - private String getArtificialName(final int index) { - return artificialNamePrefix + index; - } - - @Override - public void close() throws Exception { - /// Not removing the mapping from backing storage - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ReadTimeoutException.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ReadTimeoutException.java deleted file mode 100644 index cacca39f5..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/ReadTimeoutException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import com.google.common.annotations.Beta; -import io.fd.honeycomb.translate.read.ReadFailedException; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Thrown when read method invocation times out. - */ -@Beta -public class ReadTimeoutException extends ReadFailedException { - - public ReadTimeoutException(final InstanceIdentifier id, final Throwable cause) { - super(id, cause); - } - -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/TagRewriteOperation.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/TagRewriteOperation.java deleted file mode 100644 index 0bfd28587..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/TagRewriteOperation.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import com.google.common.base.Preconditions; -import com.google.common.primitives.UnsignedBytes; -import javax.annotation.Nonnegative; -import javax.annotation.Nullable; - -/** - * Defines vlan tag rewrite config options for VPP. - *

- * TODO HONEYCOMB-184 corresponding enum (defined in l2_vtr.h) should be defined in vpe.api - * (does vpp's IDL support enum type definition?) - * which would allow to generate this class in jvpp - */ -public enum TagRewriteOperation { - disabled(0), - push_1(0), - push_2(0), - pop_1(1), - pop_2(2), - translate_1_to_1(1), - translate_1_to_2(1), - translate_2_to_1(2), - translate_2_to_2(2); - - private static final int MAX_INDEX = 3; - private static TagRewriteOperation[][] translation = new TagRewriteOperation[][]{ - {disabled, push_1, push_2}, - {pop_1, translate_1_to_1, translate_1_to_2}, - {pop_2, translate_2_to_1, translate_2_to_2} - }; - private final int code; - private final byte popTags; - - TagRewriteOperation(final int popTags) { - this.code = this.ordinal(); - this.popTags = UnsignedBytes.checkedCast(popTags); - } - - /** - * Returns VPP tag rewrite operation for given number of tags to pop and tags to push. - * - * @param toPop number of tags to pop (0..2) - * @param toPush number of tags to push (0..2) - * @return vpp tag rewrite operation for given input parameters - */ - public static TagRewriteOperation get(@Nonnegative final int toPop, @Nonnegative final int toPush) { - Preconditions.checkElementIndex(toPop, MAX_INDEX, "Illegal number of tags to pop"); - Preconditions.checkElementIndex(toPush, MAX_INDEX, "Illegal number of tags to push"); - return translation[toPop][toPush]; - } - - /** - * Returns VPP tag rewrite operation for given operation code. - * - * @param code VPP tag rewrite operation code - * @return vpp tag rewrite operation for given input parameter - */ - @Nullable - public static TagRewriteOperation get(@Nonnegative final int code) { - for (TagRewriteOperation operation : TagRewriteOperation.values()) { - if (code == operation.code) { - return operation; - } - } - return null; - } - - public byte getPopTags() { - return popTags; - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/VppStatusListener.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/VppStatusListener.java deleted file mode 100644 index 1ea196651..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/VppStatusListener.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import io.fd.honeycomb.translate.util.read.KeepaliveReaderWrapper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Listens to vpp status changes. Restarts honeycomb if vpp is down. - */ -public final class VppStatusListener implements KeepaliveReaderWrapper.KeepaliveFailureListener { - - /** - * Value picked up by honeycomb start script, tigers honeycomb restart when returned by the java process - */ - public static final int RESTART_ERROR_CODE = 100; - private static final Logger LOG = LoggerFactory.getLogger(VppStatusListener.class); - - private volatile boolean down; - - public boolean isDown() { - return down; - } - - @Override - public void onKeepaliveFailure() { - LOG.error("Keepalive failed. VPP is probably DOWN! Restarting Honeycomb"); - this.down = true; - System.exit(RESTART_ERROR_CODE); - } -} diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/WriteTimeoutException.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/WriteTimeoutException.java deleted file mode 100644 index 7d5bac3d0..000000000 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/vpp/util/WriteTimeoutException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import com.google.common.annotations.Beta; -import io.fd.honeycomb.translate.write.WriteFailedException; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -/** - * Thrown when write method invocation times out. - */ -@Beta -public class WriteTimeoutException extends WriteFailedException { - - public WriteTimeoutException(final InstanceIdentifier id, final Throwable cause) { - super(id, cause); - } - -} diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/AddressTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/AddressTranslatorTest.java new file mode 100644 index 000000000..97fb2747c --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/AddressTranslatorTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +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; + +public class AddressTranslatorTest implements AddressTranslator { + + @Test + public void testRevertAddress() { + assertEquals("1.2.168.192", + reverseAddress(new IpAddress(new Ipv4Address("192.168.2.1"))).getIpv4Address().getValue()); + assertEquals("3473:7003:2e8a::a385:b80d:120", + reverseAddress(new IpAddress(new Ipv6Address("2001:db8:85a3:0:0:8a2e:370:7334"))).getIpv6Address() + .getValue()); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslatorTest.java new file mode 100644 index 000000000..8494568ec --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/ByteDataTranslatorTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import org.junit.Test; + +public class ByteDataTranslatorTest implements ByteDataTranslator { + + @Test + public void testBooleanToByte() { + assertEquals(0, booleanToByte(null)); + assertEquals(0, booleanToByte(false)); + assertEquals(1, booleanToByte(true)); + } + + @Test + public void testByteToBoolean() { + assertEquals(Boolean.FALSE, byteToBoolean((byte) 0)); + assertEquals(Boolean.TRUE, byteToBoolean((byte) 1)); + } + + @Test(expected = IllegalArgumentException.class) + public void testByteToBooleanFailed() { + byteToBoolean((byte) 123); + } + + @Test + public void testToString() { + final byte[] expected = "test".getBytes(); + final byte[] cString = new byte[expected.length + 10]; + System.arraycopy(expected, 0, cString, 0, expected.length); + final String jString = toString(cString); + assertArrayEquals(expected, jString.getBytes()); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRangeTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRangeTest.java new file mode 100644 index 000000000..ebaa65f43 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4AddressRangeTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; + +import io.fd.hc2vpp.common.translate.util.Ipv4AddressRange; +import java.util.Arrays; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; + +@RunWith(Parameterized.class) +public class Ipv4AddressRangeTest { + + private final String prefix; + private final String start; + private final String end; + + public Ipv4AddressRangeTest(String prefix, String start, String end) { + this.prefix = prefix; + this.start = start; + this.end = end; + } + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][] { + { "1.1.1.1/0", "0.0.0.0", "255.255.255.255"}, + { "1.1.1.1/32", "1.1.1.1", "1.1.1.1"}, + { "192.168.1.5/8", "192.0.0.0", "192.255.255.255"}, + { "192.168.1.5/10", "192.128.0.0", "192.191.255.255"} + }); + } + + @Test + public void test() throws Exception { + final Ipv4AddressRange range = Ipv4AddressRange.fromPrefix(new Ipv4Prefix(prefix)); + assertEquals(start, range.getStart().getValue()); + assertEquals(end, range.getEnd().getValue()); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4TranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4TranslatorTest.java new file mode 100644 index 000000000..722e2c62c --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv4TranslatorTest.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; + +import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; + +public class Ipv4TranslatorTest implements Ipv4Translator { + + @Test + public void testIpv4NoZone() throws Exception { + final Ipv4AddressNoZone ipv4Addr = new Ipv4AddressNoZone("192.168.1.1"); + byte[] bytes = ipv4AddressNoZoneToArray(ipv4Addr); + assertEquals((byte) 192, bytes[0]); + // Simulating the magic of VPP + bytes = reverseBytes(bytes); + final Ipv4AddressNoZone ipv4AddressNoZone = arrayToIpv4AddressNoZone(bytes); + assertEquals(ipv4Addr, ipv4AddressNoZone); + } + + @Test + public void testIpv4AddressPrefixToArray() { + byte[] ip = ipv4AddressPrefixToArray(new Ipv4Prefix("192.168.2.1/24")); + + assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(ip).getValue()); + } + + @Test + public void testExtractPrefix() { + assertEquals(24, extractPrefix(new Ipv4Prefix("192.168.2.1/24"))); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv6TranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv6TranslatorTest.java new file mode 100644 index 000000000..073754a98 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/Ipv6TranslatorTest.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; + +import io.fd.hc2vpp.common.translate.util.Ipv6Translator; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; + +public class Ipv6TranslatorTest implements Ipv6Translator { + + @Test + public void testIpv6NoZone() { + final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("3ffe:1900:4545:3:200:f8ff:fe21:67cf"); + byte[] bytes = ipv6AddressNoZoneToArray(ipv6Addr); + assertEquals((byte) 63, bytes[0]); + + bytes = reverseBytes(bytes); + final Ipv6AddressNoZone ivp6AddressNoZone = arrayToIpv6AddressNoZone(bytes); + assertEquals(ipv6Addr, ivp6AddressNoZone); + } + + @Test + public void testIpv6AddressPrefixToArray() { + byte[] ip = ipv6AddressPrefixToArray(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48")); + + assertEquals("cf67:21fe:fff8:2:300:4545:19:fe3f", arrayToIpv6AddressNoZone(ip).getValue()); + } + + @Test + public void testIpv4AddressPrefixToArray() { + byte[] ip = ipv6AddressPrefixToArray(new Ipv6Prefix("2001:0db8:0a0b:12f0:0000:0000:0000:0001/128")); + + assertEquals("100::f012:b0a:b80d:120", arrayToIpv6AddressNoZone(ip).getValue()); + } + + @Test + public void testExtractPrefix() { + assertEquals(48, extractPrefix(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48"))); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumerTest.java new file mode 100644 index 000000000..daf68d2b6 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/JvppReplyConsumerTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.ReadTimeoutException; +import io.fd.hc2vpp.common.translate.util.WriteTimeoutException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.junit.Test; +import org.opendaylight.yangtools.yang.binding.DataContainer; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.dto.JVppReply; + +public class JvppReplyConsumerTest implements JvppReplyConsumer { + + private static class AnDataObject implements DataObject { + @Override + public Class getImplementedInterface() { + return null; + } + } + + @Test + public void testGetReplyForWriteTimeout() throws Exception { + final Future> future = mock(Future.class); + when(future.get(anyLong(), eq(TimeUnit.SECONDS))).thenThrow(TimeoutException.class); + final InstanceIdentifier + replyType = InstanceIdentifier.create(AnDataObject.class); + try { + getReplyForWrite(future, replyType); + } catch (WriteTimeoutException e) { + assertTrue(e.getCause() instanceof TimeoutException); + assertEquals(replyType, e.getFailedId()); + return; + } + fail("WriteTimeoutException was expected"); + } + + @Test + public void testGetReplyForReadTimeout() throws Exception { + final Future> future = mock(Future.class); + final InstanceIdentifier replyType = + InstanceIdentifier.create(AnDataObject.class); + when(future.get(anyLong(), eq(TimeUnit.SECONDS))).thenThrow(TimeoutException.class); + try { + getReplyForRead(future, replyType); + } catch (ReadTimeoutException e) { + assertTrue(e.getCause() instanceof TimeoutException); + assertEquals(replyType, e.getFailedId()); + return; + } + fail("ReadTimeoutException was expected"); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/MacTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/MacTranslatorTest.java new file mode 100644 index 000000000..f716b0f0a --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/MacTranslatorTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertEquals; + +import io.fd.hc2vpp.common.translate.util.MacTranslator; +import org.junit.Test; + +public class MacTranslatorTest implements MacTranslator { + + @Test + public void testParseMac() throws Exception { + byte[] bytes = parseMac("00:fF:7f:15:5e:A9"); + assertMac(bytes); + } + + private void assertMac(final byte[] bytes) { + assertEquals(6, bytes.length); + assertEquals((byte) 0, bytes[0]); + assertEquals((byte) 255, bytes[1]); + assertEquals((byte) 127, bytes[2]); + assertEquals((byte) 21, bytes[3]); + assertEquals((byte) 94, bytes[4]); + assertEquals((byte) 169, bytes[5]); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseMacLonger() throws Exception { + byte[] bytes = parseMac("00:fF:7f:15:5e:A9:88:77"); + assertMac(bytes); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseMacShorter() throws Exception { + parseMac("00:fF:7f"); + } + + @Test(expected = IllegalArgumentException.class) + public void testParseRandomString() throws Exception { + parseMac("random{}}@$*&*!"); + } + + @Test(expected = NumberFormatException.class) + public void testParseMacNumberFormatEx() throws Exception { + parseMac("00:XX:7f:15:5e:77\""); + } + + @Test + public void testByteArrayToMacUnseparated() { + byte[] address = parseMac("aa:bb:cc:dd:ee:ff"); + + String converted = byteArrayToMacUnseparated(address); + + assertEquals("aabbccddeeff", converted); + } + + @Test + public void testByteArrayToMacSeparated() { + byte[] address = parseMac("aa:bb:cc:dd:ee:ff"); + + String converted = byteArrayToMacSeparated(address); + + assertEquals("aa:bb:cc:dd:ee:ff", converted); + } + + @Test(expected = IllegalArgumentException.class) + public void testByteArrayToMacUnseparatedIllegal() { + byteArrayToMacUnseparated(new byte[]{54, 26, 87, 32, 14}); + } + + @Test(expected = IllegalArgumentException.class) + public void testByteArrayToMacSeparatedIllegal() { + byteArrayToMacSeparated(new byte[]{54, 26, 87, 32, 14}); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/VppStatusListenerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/VppStatusListenerTest.java new file mode 100644 index 000000000..39edd6091 --- /dev/null +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/hc2vpp/common/translate/util/VppStatusListenerTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.common.translate.util; + +import static org.junit.Assert.assertTrue; + +import io.fd.hc2vpp.common.translate.util.VppStatusListener; +import org.junit.Rule; +import org.junit.Test; +import org.junit.contrib.java.lang.system.ExpectedSystemExit; + +public class VppStatusListenerTest { + + @Rule + public final ExpectedSystemExit exit = ExpectedSystemExit.none(); + + @Test + public void testOnKeepaliveFailure() throws Exception { + final VppStatusListener vppStatus = new VppStatusListener(); + exit.expectSystemExitWithStatus(VppStatusListener.RESTART_ERROR_CODE); + exit.checkAssertionAfterwards(() -> assertTrue(vppStatus.isDown())); + vppStatus.onKeepaliveFailure(); + } +} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/AddressTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/AddressTranslatorTest.java deleted file mode 100644 index 71a41dd5e..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/AddressTranslatorTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -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; - -public class AddressTranslatorTest implements AddressTranslator { - - @Test - public void testRevertAddress() { - assertEquals("1.2.168.192", - reverseAddress(new IpAddress(new Ipv4Address("192.168.2.1"))).getIpv4Address().getValue()); - assertEquals("3473:7003:2e8a::a385:b80d:120", - reverseAddress(new IpAddress(new Ipv6Address("2001:db8:85a3:0:0:8a2e:370:7334"))).getIpv6Address() - .getValue()); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslatorTest.java deleted file mode 100644 index 3462b4cf8..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/ByteDataTranslatorTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class ByteDataTranslatorTest implements ByteDataTranslator { - - @Test - public void testBooleanToByte() { - assertEquals(0, booleanToByte(null)); - assertEquals(0, booleanToByte(false)); - assertEquals(1, booleanToByte(true)); - } - - @Test - public void testByteToBoolean() { - assertEquals(Boolean.FALSE, byteToBoolean((byte) 0)); - assertEquals(Boolean.TRUE, byteToBoolean((byte) 1)); - } - - @Test(expected = IllegalArgumentException.class) - public void testByteToBooleanFailed() { - byteToBoolean((byte) 123); - } - - @Test - public void testToString() { - final byte[] expected = "test".getBytes(); - final byte[] cString = new byte[expected.length + 10]; - System.arraycopy(expected, 0, cString, 0, expected.length); - final String jString = toString(cString); - assertArrayEquals(expected, jString.getBytes()); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRangeTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRangeTest.java deleted file mode 100644 index aef81fce6..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4AddressRangeTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.Collection; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; - -@RunWith(Parameterized.class) -public class Ipv4AddressRangeTest { - - private final String prefix; - private final String start; - private final String end; - - public Ipv4AddressRangeTest(String prefix, String start, String end) { - this.prefix = prefix; - this.start = start; - this.end = end; - } - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList(new Object[][] { - { "1.1.1.1/0", "0.0.0.0", "255.255.255.255"}, - { "1.1.1.1/32", "1.1.1.1", "1.1.1.1"}, - { "192.168.1.5/8", "192.0.0.0", "192.255.255.255"}, - { "192.168.1.5/10", "192.128.0.0", "192.191.255.255"} - }); - } - - @Test - public void test() throws Exception { - final Ipv4AddressRange range = Ipv4AddressRange.fromPrefix(new Ipv4Prefix(prefix)); - assertEquals(start, range.getStart().getValue()); - assertEquals(end, range.getEnd().getValue()); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4TranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4TranslatorTest.java deleted file mode 100644 index 39fc620b2..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv4TranslatorTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; - -public class Ipv4TranslatorTest implements Ipv4Translator { - - @Test - public void testIpv4NoZone() throws Exception { - final Ipv4AddressNoZone ipv4Addr = new Ipv4AddressNoZone("192.168.1.1"); - byte[] bytes = ipv4AddressNoZoneToArray(ipv4Addr); - assertEquals((byte) 192, bytes[0]); - // Simulating the magic of VPP - bytes = reverseBytes(bytes); - final Ipv4AddressNoZone ipv4AddressNoZone = arrayToIpv4AddressNoZone(bytes); - assertEquals(ipv4Addr, ipv4AddressNoZone); - } - - @Test - public void testIpv4AddressPrefixToArray() { - byte[] ip = ipv4AddressPrefixToArray(new Ipv4Prefix("192.168.2.1/24")); - - assertEquals("1.2.168.192", arrayToIpv4AddressNoZone(ip).getValue()); - } - - @Test - public void testExtractPrefix() { - assertEquals(24, extractPrefix(new Ipv4Prefix("192.168.2.1/24"))); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv6TranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv6TranslatorTest.java deleted file mode 100644 index 6a5d13613..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/Ipv6TranslatorTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; - -public class Ipv6TranslatorTest implements Ipv6Translator { - - @Test - public void testIpv6NoZone() { - final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("3ffe:1900:4545:3:200:f8ff:fe21:67cf"); - byte[] bytes = ipv6AddressNoZoneToArray(ipv6Addr); - assertEquals((byte) 63, bytes[0]); - - bytes = reverseBytes(bytes); - final Ipv6AddressNoZone ivp6AddressNoZone = arrayToIpv6AddressNoZone(bytes); - assertEquals(ipv6Addr, ivp6AddressNoZone); - } - - @Test - public void testIpv6AddressPrefixToArray() { - byte[] ip = ipv6AddressPrefixToArray(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48")); - - assertEquals("cf67:21fe:fff8:2:300:4545:19:fe3f", arrayToIpv6AddressNoZone(ip).getValue()); - } - - @Test - public void testIpv4AddressPrefixToArray() { - byte[] ip = ipv6AddressPrefixToArray(new Ipv6Prefix("2001:0db8:0a0b:12f0:0000:0000:0000:0001/128")); - - assertEquals("100::f012:b0a:b80d:120", arrayToIpv6AddressNoZone(ip).getValue()); - } - - @Test - public void testExtractPrefix() { - assertEquals(48, extractPrefix(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48"))); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumerTest.java deleted file mode 100644 index 9b1cecf38..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/JvppReplyConsumerTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.junit.Test; -import org.opendaylight.yangtools.yang.binding.DataContainer; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import io.fd.vpp.jvpp.dto.JVppReply; - -public class JvppReplyConsumerTest implements JvppReplyConsumer { - - private static class AnDataObject implements DataObject { - @Override - public Class getImplementedInterface() { - return null; - } - } - - @Test - public void testGetReplyForWriteTimeout() throws Exception { - final Future> future = mock(Future.class); - when(future.get(anyLong(), eq(TimeUnit.SECONDS))).thenThrow(TimeoutException.class); - final InstanceIdentifier - replyType = InstanceIdentifier.create(AnDataObject.class); - try { - getReplyForWrite(future, replyType); - } catch (WriteTimeoutException e) { - assertTrue(e.getCause() instanceof TimeoutException); - assertEquals(replyType, e.getFailedId()); - return; - } - fail("WriteTimeoutException was expected"); - } - - @Test - public void testGetReplyForReadTimeout() throws Exception { - final Future> future = mock(Future.class); - final InstanceIdentifier replyType = - InstanceIdentifier.create(AnDataObject.class); - when(future.get(anyLong(), eq(TimeUnit.SECONDS))).thenThrow(TimeoutException.class); - try { - getReplyForRead(future, replyType); - } catch (ReadTimeoutException e) { - assertTrue(e.getCause() instanceof TimeoutException); - assertEquals(replyType, e.getFailedId()); - return; - } - fail("ReadTimeoutException was expected"); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/MacTranslatorTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/MacTranslatorTest.java deleted file mode 100644 index 2b5df66fd..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/MacTranslatorTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class MacTranslatorTest implements MacTranslator { - - @Test - public void testParseMac() throws Exception { - byte[] bytes = parseMac("00:fF:7f:15:5e:A9"); - assertMac(bytes); - } - - private void assertMac(final byte[] bytes) { - assertEquals(6, bytes.length); - assertEquals((byte) 0, bytes[0]); - assertEquals((byte) 255, bytes[1]); - assertEquals((byte) 127, bytes[2]); - assertEquals((byte) 21, bytes[3]); - assertEquals((byte) 94, bytes[4]); - assertEquals((byte) 169, bytes[5]); - } - - @Test(expected = IllegalArgumentException.class) - public void testParseMacLonger() throws Exception { - byte[] bytes = parseMac("00:fF:7f:15:5e:A9:88:77"); - assertMac(bytes); - } - - @Test(expected = IllegalArgumentException.class) - public void testParseMacShorter() throws Exception { - parseMac("00:fF:7f"); - } - - @Test(expected = IllegalArgumentException.class) - public void testParseRandomString() throws Exception { - parseMac("random{}}@$*&*!"); - } - - @Test(expected = NumberFormatException.class) - public void testParseMacNumberFormatEx() throws Exception { - parseMac("00:XX:7f:15:5e:77\""); - } - - @Test - public void testByteArrayToMacUnseparated() { - byte[] address = parseMac("aa:bb:cc:dd:ee:ff"); - - String converted = byteArrayToMacUnseparated(address); - - assertEquals("aabbccddeeff", converted); - } - - @Test - public void testByteArrayToMacSeparated() { - byte[] address = parseMac("aa:bb:cc:dd:ee:ff"); - - String converted = byteArrayToMacSeparated(address); - - assertEquals("aa:bb:cc:dd:ee:ff", converted); - } - - @Test(expected = IllegalArgumentException.class) - public void testByteArrayToMacUnseparatedIllegal() { - byteArrayToMacUnseparated(new byte[]{54, 26, 87, 32, 14}); - } - - @Test(expected = IllegalArgumentException.class) - public void testByteArrayToMacSeparatedIllegal() { - byteArrayToMacSeparated(new byte[]{54, 26, 87, 32, 14}); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/VppStatusListenerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/VppStatusListenerTest.java deleted file mode 100644 index 93ee8ef06..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/VppStatusListenerTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util; - -import static org.junit.Assert.assertTrue; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.contrib.java.lang.system.ExpectedSystemExit; - -public class VppStatusListenerTest { - - @Rule - public final ExpectedSystemExit exit = ExpectedSystemExit.none(); - - @Test - public void testOnKeepaliveFailure() throws Exception { - final VppStatusListener vppStatus = new VppStatusListener(); - exit.expectSystemExitWithStatus(VppStatusListener.RESTART_ERROR_CODE); - exit.checkAssertionAfterwards(() -> assertTrue(vppStatus.isDown())); - vppStatus.onKeepaliveFailure(); - } -} \ No newline at end of file diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java deleted file mode 100644 index 81a47e8a2..000000000 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/vpp/util/cache/DumpCacheManagerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.translate.vpp.util.cache; - -import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.when; - -import com.google.common.base.Optional; -import io.fd.honeycomb.translate.ModificationCache; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.util.read.cache.CacheKeyFactory; -import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpPostProcessingFunction; -import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; -import io.fd.vpp.jvpp.core.dto.IpDetails; -import io.fd.vpp.jvpp.core.dto.IpDetailsReplyDump; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class DumpCacheManagerTest { - - private interface DataObj extends DataObject {} - - @Mock - private EntityDumpExecutor executor; - - private InstanceIdentifier identifier; - - private DumpCacheManager managerPositive; - private DumpCacheManager managerPositiveWithPostProcessing; - private DumpCacheManager managerNegative; - private ModificationCache cache; - private CacheKeyFactory cacheKeyFactory; - - @Before - public void init() { - MockitoAnnotations.initMocks(this); - managerPositive = - new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(executor) - .build(); - - managerPositiveWithPostProcessing = - new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(executor) - .withPostProcessingFunction(createPostProcessor()) - .build(); - - managerNegative = - new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(executor) - .build(); - - cache = new ModificationCache(); - identifier = InstanceIdentifier.create(DataObj.class); - //manager uses this implementation by default, so it can be used to test behaviour - cacheKeyFactory = new IdentifierCacheKeyFactory(); - - } - - /** - * This test verify full dump-caching cycle - */ - @Test - public void testCaching() throws ReadFailedException { - final IpDetailsReplyDump stage1Data = new IpDetailsReplyDump(); - final String key = cacheKeyFactory.createKey(identifier); - - - // executor cant return null data - when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(new IpDetailsReplyDump()); - - final Optional stage1Optional = managerNegative.getDump(identifier, cache, NO_PARAMS); - - // this is first call so instance should be from executor - // and it should be cached after calling executor - assertEquals(true, stage1Optional.isPresent()); - assertEquals(stage1Data, stage1Optional.get()); - assertEquals(true, cache.containsKey(key)); - assertEquals(stage1Data, cache.get(key)); - - //rebind executor with other data - IpDetailsReplyDump stage2LoadedDump = new IpDetailsReplyDump(); - when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(stage2LoadedDump); - - final Optional stage2Optional = managerPositive.getDump(identifier, cache, NO_PARAMS); - - assertEquals(true, stage2Optional.isPresent()); - assertEquals(stage2LoadedDump, stage2Optional.get()); - - //rebind executor with other data - IpDetailsReplyDump stage3LoadedDump = new IpDetailsReplyDump(); - when(executor.executeDump(identifier, NO_PARAMS)).thenReturn(stage3LoadedDump); - - final Optional stage3Optional = managerPositive.getDump(identifier, cache, NO_PARAMS); - assertEquals(true, stage3Optional.isPresent()); - //check if it returns instance cached from previous stage - assertEquals(stage2LoadedDump, stage3Optional.get()); - } - - @Test - public void testPostprocessing() throws ReadFailedException { - IpDetailsReplyDump dump = new IpDetailsReplyDump(); - IpDetails details = new IpDetails(); - details.swIfIndex = 2; - dump.ipDetails.add(details); - - when(executor.executeDump(identifier, null)).thenReturn(dump); - - Optional optionalDump = - managerPositiveWithPostProcessing.getDump(identifier, cache, NO_PARAMS); - - assertEquals(true, optionalDump.isPresent()); - assertEquals(1, optionalDump.get().ipDetails.size()); - assertEquals(7, optionalDump.get().ipDetails.get(0).swIfIndex); - } - - private EntityDumpPostProcessingFunction createPostProcessor() { - return ipDetailsReplyDump -> { - IpDetailsReplyDump modified = new IpDetailsReplyDump(); - - for (IpDetails detail : ipDetailsReplyDump.ipDetails) { - IpDetails modifiedDetail = new IpDetails(); - modifiedDetail.swIfIndex = detail.swIfIndex + 5; - - modified.ipDetails.add(modifiedDetail); - } - - return modified; - }; - } -} \ No newline at end of file -- cgit 1.2.3-korg