From aba4f1652a6bb8dda5e5fd5f71909212062279f6 Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 16 May 2023 03:23:44 +0200 Subject: [PATCH] Integrate AbstractIetfInetUtil We have a single specialization, remove INSTANCE and make sure methods are static. JIRA: MDSAL-826 Change-Id: I051482f26837d216bbd68c3705beb0c6ec609b2d Signed-off-by: Robert Varga --- .../types/rev130715/AbstractIetfInetUtil.java | 641 ------------------ .../inet/types/rev130715/IetfInetUtil.java | 632 ++++++++++++++++- .../types/rev130715/IetfInetUtilTest.java | 137 ++-- 3 files changed, 694 insertions(+), 716 deletions(-) delete mode 100644 model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/AbstractIetfInetUtil.java diff --git a/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/AbstractIetfInetUtil.java b/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/AbstractIetfInetUtil.java deleted file mode 100644 index 729a303990..0000000000 --- a/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/AbstractIetfInetUtil.java +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Copyright (c) 2016 Pantheon Technologies s.r.o. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -import com.google.common.annotations.Beta; -import com.google.common.net.InetAddresses; -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.AbstractMap.SimpleImmutableEntry; -import java.util.Map.Entry; -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory; -import org.opendaylight.mdsal.model.ietf.util.Ipv4Utils; -import org.opendaylight.mdsal.model.ietf.util.Ipv6Utils; - -/** - * A set of utility methods to efficiently instantiate various ietf-inet-types DTOs. - */ -@Beta -@SuppressWarnings("checkstyle:classTypeParameterName") -public abstract class AbstractIetfInetUtil { - private static final StringValueObjectFactory V4NZ_FACTORY = - StringValueObjectFactory.create(Ipv4AddressNoZone.class, "0.0.0.0"); - private static final StringValueObjectFactory P4_FACTORY = - StringValueObjectFactory.create(Ipv4Prefix.class, "0.0.0.0/0"); - private static final StringValueObjectFactory V6NZ_FACTORY = - StringValueObjectFactory.create(Ipv6AddressNoZone.class, "::0"); - private static final StringValueObjectFactory P6_FACTORY = - StringValueObjectFactory.create(Ipv6Prefix.class, "::0/0"); - - /** - * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length. - * - * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array - * @return An IpAddress object - * @throws IllegalArgumentException if bytes has length different from 4 or 6 - * @throws NullPointerException if bytes is null - */ - public final @NonNull IpAddress ipAddressFor(final byte @NonNull[] bytes) { - return switch (bytes.length) { - case Ipv4Utils.INET4_LENGTH -> new IpAddress(ipv4AddressFor(bytes)); - case Ipv6Utils.INET6_LENGTH -> new IpAddress(ipv6AddressFor(bytes)); - default -> throwInvalidArray(bytes); - }; - } - - public final @NonNull IpAddress ipAddressFor(final @NonNull InetAddress addr) { - requireAddress(addr); - if (addr instanceof Inet4Address) { - return new IpAddress(ipv4AddressFor(addr)); - } else if (addr instanceof Inet6Address) { - return new IpAddress(ipv6AddressFor(addr)); - } else { - throw unhandledAddress(addr); - } - } - - private static @NonNull T requireAddress(final T addr) { - return requireNonNull(addr, "Address must not be null"); - } - - /** - * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length. - * - * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array - * @return A no-zone IpAddress object - * @throws IllegalArgumentException if bytes has length different from 4 or 6 - * @throws NullPointerException if bytes is null - */ - public final @NonNull IpAddressNoZone ipAddressNoZoneFor(final byte @NonNull[] bytes) { - return switch (bytes.length) { - case Ipv4Utils.INET4_LENGTH -> new IpAddressNoZone(ipv4AddressFor(bytes)); - case Ipv6Utils.INET6_LENGTH -> new IpAddressNoZone(ipv6AddressFor(bytes)); - default -> throwInvalidArray(bytes); - }; - } - - public final @NonNull IpAddressNoZone ipAddressNoZoneFor(final @NonNull InetAddress addr) { - requireAddress(addr); - if (addr instanceof Inet4Address) { - return new IpAddressNoZone(ipv4AddressFor(addr)); - } else if (addr instanceof Inet6Address) { - return new IpAddressNoZone(ipv6AddressFor(addr)); - } else { - throw unhandledAddress(addr); - } - } - - private static T throwInvalidArray(final byte[] bytes) { - throw new IllegalArgumentException("Invalid array length " + bytes.length); - } - - private static IllegalArgumentException unhandledAddress(final InetAddress addr) { - return new IllegalArgumentException("Unhandled address " + addr); - } - - /** - * Create an IpPrefix by combining the address with a mask. The address - * bytes are interpreted as an address and the specified mask is concatenated to - * it. The address bytes are not masked. - * - * @param bytes Input address as a 4-byte (IPv4) or 16-byte (IPv6) array - * @param mask Prefix mask - * @return An IpPrefix object - * @throws IllegalArgumentException if bytes has length different from 4 or 16 or if mask is not - * in range 0-32 or 0-128 respectively - * @throws NullPointerException if bytes is null - */ - public final @NonNull IpPrefix ipPrefixFor(final byte @NonNull[] bytes, final int mask) { - return switch (bytes.length) { - case Ipv4Utils.INET4_LENGTH -> new IpPrefix(ipv4PrefixFor(bytes, mask)); - case Ipv6Utils.INET6_LENGTH -> new IpPrefix(ipv6PrefixFor(bytes, mask)); - default -> throwInvalidArray(bytes); - }; - } - - public final @NonNull IpPrefix ipPrefixFor(final @NonNull InetAddress addr, final int mask) { - requireAddress(addr); - if (addr instanceof Inet4Address) { - return new IpPrefix(ipv4PrefixFor(addr, mask)); - } else if (addr instanceof Inet6Address) { - return new IpPrefix(ipv6PrefixFor(addr, mask)); - } else { - throw unhandledAddress(addr); - } - } - - public final @NonNull IpPrefix ipPrefixFor(final @NonNull IpAddress addr) { - final var v4 = addr.getIpv4Address(); - return v4 != null ? new IpPrefix(ipv4PrefixFor(v4)) : new IpPrefix(ipv6PrefixFor(coerceIpv6Address(addr))); - } - - public final @NonNull IpPrefix ipPrefixForNoZone(final @NonNull IpAddressNoZone addr) { - final var v4 = addr.getIpv4AddressNoZone(); - return v4 != null ? new IpPrefix(ipv4PrefixFor(inet4AddressForNoZone(v4))) - : new IpPrefix(ipv6PrefixFor(coerceIpv6AddressNoZone(addr))); - } - - public final @NonNull InetAddress inetAddressFor(final @NonNull IpAddress addr) { - final var v4 = addr.getIpv4Address(); - return v4 != null ? inet4AddressFor(v4) : inet6AddressFor(coerceIpv6Address(addr)); - } - - public final @NonNull InetAddress inetAddressForNoZone(final @NonNull IpAddressNoZone addr) { - final var v4 = addr.getIpv4AddressNoZone(); - return v4 != null ? inet4AddressForNoZone(v4) : inet6AddressForNoZone(coerceIpv6AddressNoZone(addr)); - } - - public final @NonNull Inet4Address inet4AddressFor(final @NonNull Ipv4Address addr) { - try { - return (Inet4Address) InetAddress.getByAddress(ipv4AddressBytes(addr)); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid address " + addr, e); - } - } - - public final @NonNull Inet4Address inet4AddressForNoZone(final @NonNull Ipv4AddressNoZone addr) { - try { - return (Inet4Address) InetAddress.getByAddress(ipv4AddressNoZoneBytes(addr)); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid address " + addr, e); - } - } - - public final @NonNull Inet6Address inet6AddressFor(final @NonNull Ipv6Address addr) { - try { - return (Inet6Address) InetAddress.getByAddress(ipv6AddressBytes(addr)); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid address " + addr, e); - } - } - - public final @NonNull Inet6Address inet6AddressForNoZone(final @NonNull Ipv6AddressNoZone addr) { - try { - return (Inet6Address) InetAddress.getByAddress(ipv6AddressNoZoneBytes(addr)); - } catch (UnknownHostException e) { - throw new IllegalArgumentException("Invalid address " + addr, e); - } - } - - /** - * Create an Ipv4AddressNoZone by interpreting input bytes as an IPv4 address. - * - * @param bytes 4-byte array - * @return An Ipv4AddressNoZone object - * @throws IllegalArgumentException if bytes has length different from 4 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final byte @NonNull[] bytes) { - return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bytes)); - } - - /** - * Create an Ipv4AddressNoZone by interpreting an {@link Inet4Address}. - * - * @param addr An {@link Inet4Address} - * @return An Ipv4AddressNoZone object - * @throws IllegalArgumentException if addr is not an {@link Inet4Address} - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final @NonNull InetAddress addr) { - return V4NZ_FACTORY.newInstance(addressStringV4(addr)); - } - - /** - * Create an Ipv4AddressNoZone by interpreting input 32 bits as an IPv4 address in big-endian format. - * - * @param bits 32 bits, big endian - * @return An Ipv4AddressNoZone object - */ - public final @NonNull Ipv4AddressNoZone ipv4AddressFor(final int bits) { - return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bits)); - } - - /** - * Create an Ipv4AddressNoZone by interpreting an Ipv4Address. - * - * @param addr An Ipv4Address - * @return An Ipv4AddressNoZone object - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv4AddressNoZone ipv4AddressNoZoneFor(final @NonNull Ipv4Address addr) { - requireAddress(addr); - return addr instanceof Ipv4AddressNoZone noZone ? noZone - : V4NZ_FACTORY.newInstance(stripZone(addr.getValue())); - } - - public final @NonNull Ipv4AddressNoZone ipv4AddressFrom(final @NonNull Ipv4Prefix prefix) { - return prefixToAddress(V4NZ_FACTORY, prefix.getValue()); - } - - public final byte @NonNull[] ipv4AddressBytes(final @NonNull Ipv4Address addr) { - /* - * This implementation relies heavily on the input string having been validated to comply with - * the Ipv4Address pattern, which may include a zone index. - */ - final var str = addr.getValue(); - final int percent = str.indexOf('%'); - return Ipv4Utils.addressBytes(str, percent == -1 ? str.length() : percent); - } - - public final int ipv4AddressBits(final @NonNull Ipv4Address addr) { - final var str = addr.getValue(); - final int percent = str.indexOf('%'); - return Ipv4Utils.addressBits(str, percent == -1 ? str.length() : percent); - } - - public final byte @NonNull[] ipv4AddressNoZoneBytes(final @NonNull Ipv4AddressNoZone addr) { - /* - * This implementation relies heavily on the input string having been validated to comply with - * the Ipv4AddressNoZone pattern, which must not include a zone index. - */ - final String str = addr.getValue(); - return Ipv4Utils.addressBytes(str, str.length()); - } - - public final int ipv4AddressNoZoneBits(final @NonNull Ipv4AddressNoZone addr) { - final var str = addr.getValue(); - return Ipv4Utils.addressBits(str, str.length()); - } - - /** - * Create a /32 Ipv4Prefix by interpreting input bytes as an IPv4 address. - * - * @param bytes four-byte array - * @return An Ipv4Prefix object - * @throws IllegalArgumentException if bytes has length different from 4 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] bytes) { - return P4_FACTORY.newInstance(prefixStringV4(bytes)); - } - - /** - * Create a Ipv4Prefix by combining the address with a mask. The address - * bytes are interpreted as an address and the specified mask is concatenated to - * it. The address bytes are not masked, hence input address = { 1, 2, 3, 4 } - * and mask=24 will result in 1.2.3.4/24. - * - * @param address Input address as a 4-byte array - * @param mask Prefix mask - * @return An Ipv4Prefix object - * @throws IllegalArgumentException if bytes has length different from 4 or if mask is not in range 0-32 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] address, final int mask) { - return P4_FACTORY.newInstance(prefixStringV4(address, mask)); - } - - /** - * Create a /32 Ipv4Prefix for an {@link Inet4Address}. - * - * @param addr An {@link Inet4Address} - * @return An Ipv4Prefix object - * @throws IllegalArgumentException if addr is not an Inet4Address - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr) { - return P4_FACTORY.newInstance(addressStringV4(addr) + "/32"); - } - - /** - * Create a Ipv4Prefix by combining the address with a mask. The address bytes are not masked. - * - * @param addr An {@link Inet4Address} - * @param mask Prefix mask - * @return An Ipv4Prefix object - * @throws IllegalArgumentException if addr is not an Inet4Address or if mask is not in range 0-32 - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr, final int mask) { - return newIpv4Prefix(addressStringV4(addr), mask); - } - - public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr) { - return P4_FACTORY.newInstance(stripZone(addr.getValue()) + "/32"); - } - - public final @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr, final int mask) { - return newIpv4Prefix(stripZone(addr.getValue()), mask); - } - - public final @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr) { - return P4_FACTORY.newInstance(addr.getValue() + "/32"); - } - - public final @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr, final int mask) { - return newIpv4Prefix(addr.getValue(), mask); - } - - public final @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] address, final int mask) { - if (mask == 0) { - // Easy case, reuse the template - return P4_FACTORY.getTemplate(); - } - - return v4PrefixForShort(address, 0, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); - } - - public final @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] array, final int startOffset, - final int mask) { - if (mask == 0) { - // Easy case, reuse the template - return P4_FACTORY.getTemplate(); - } - - return v4PrefixForShort(array, startOffset, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); - } - - private static String stripZone(final String str) { - final int percent = str.indexOf('%'); - return percent == -1 ? str : str.substring(0, percent); - } - - private @NonNull Ipv4Prefix newIpv4Prefix(final String addr, final int mask) { - checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); - return P4_FACTORY.newInstance(addr + '/' + mask); - } - - public final @NonNull Entry splitIpv4Prefix(final @NonNull Ipv4Prefix prefix) { - return splitPrefix(V4NZ_FACTORY, prefix.getValue()); - } - - public final byte @NonNull[] ipv4PrefixToBytes(final @NonNull Ipv4Prefix prefix) { - final var str = prefix.getValue(); - final int slash = str.lastIndexOf('/'); - - final byte[] bytes = new byte[Ipv4Utils.INET4_LENGTH + 1]; - Ipv4Utils.fillIpv4Bytes(bytes, 0, str, 0, slash); - bytes[Ipv4Utils.INET4_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10); - return bytes; - } - - /** - * Create an Ipv6Address by interpreting input bytes as an IPv6 address. - * - * @param bytes 16-byte array - * @return An Ipv6Address object - * @throws IllegalArgumentException if bytes has length different from 16 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv6AddressNoZone ipv6AddressFor(final byte @NonNull[] bytes) { - return V6NZ_FACTORY.newInstance(addressStringV6(bytes)); - } - - /** - * Create an Ipv6Address by interpreting an {@link Inet6Address}. - * - * @param addr An {@link Inet6Address} - * @return An Ipv6Address object - * @throws IllegalArgumentException if addr is not an {@link Inet6Address} - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv6AddressNoZone ipv6AddressFor(final @NonNull InetAddress addr) { - return V6NZ_FACTORY.newInstance(addressStringV6(addr)); - } - - /** - * Create an Ipv6AddressNoZone by interpreting an Ipv6Address. - * - * @param addr An Ipv6Address - * @return An Ipv6AddressNoZone object - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv6AddressNoZone ipv6AddressNoZoneFor(final @NonNull Ipv6Address addr) { - requireAddress(addr); - return addr instanceof Ipv6AddressNoZone noZone ? noZone - : V6NZ_FACTORY.newInstance(stripZone(addr.getValue())); - } - - public final @NonNull Ipv6AddressNoZone ipv6AddressFrom(final @NonNull Ipv6Prefix prefix) { - return prefixToAddress(V6NZ_FACTORY, prefix.getValue()); - } - - public final byte @NonNull[] ipv6AddressBytes(final @NonNull Ipv6Address addr) { - final var str = addr.getValue(); - final int percent = str.indexOf('%'); - return ipv6StringBytes(str, percent == -1 ? str.length() : percent); - } - - public final byte @NonNull[] ipv6AddressNoZoneBytes(final @NonNull Ipv6Address addr) { - final var str = addr.getValue(); - return ipv6StringBytes(str, str.length()); - } - - private static byte @NonNull[] ipv6StringBytes(final @NonNull String str, final int limit) { - final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH]; - Ipv6Utils.fillIpv6Bytes(bytes, str, limit); - return bytes; - } - - /** - * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address. - * - * @param bytes four-byte array - * @return An Ipv6Prefix object - * @throws IllegalArgumentException if bytes has length different from 16 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] bytes) { - return P6_FACTORY.newInstance(addressStringV6(bytes) + "/128"); - } - - /** - * Create a Ipv6Prefix by combining the address with a mask. The address - * bytes are interpreted as an address and the specified mask is concatenated to - * it. The address bytes are not masked. - * - * @param address Input address as a 16-byte array - * @param mask Prefix mask - * @return An Ipv6Prefix object - * @throws IllegalArgumentException if bytes has length different from 16 or if mask is not in range 0-128 - * @throws NullPointerException if bytes is null - */ - public final @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] address, final int mask) { - checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); - return P6_FACTORY.newInstance(addressStringV6(address) + '/' + mask); - } - - /** - * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address. - * - * @param addr an {@link Inet6Address} - * @return An Ipv6Prefix object - * @throws IllegalArgumentException if addr is not an Inet6Address - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr) { - return P6_FACTORY.newInstance(addressStringV6(addr) + "/128"); - } - - /** - * Create a Ipv6Prefix by combining the address with a mask. The address - * bytes are interpreted as an address and the specified mask is concatenated to - * it. The address bytes are not masked. - * - * @param addr Input address - * @param mask Prefix mask - * @return An Ipv6Prefix object - * @throws IllegalArgumentException if addr is not an Inet6Address or if mask is not in range 0-128 - * @throws NullPointerException if addr is null - */ - public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr, final int mask) { - checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); - return P6_FACTORY.newInstance(addressStringV6(addr) + '/' + mask); - } - - public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr) { - return P6_FACTORY.newInstance(stripZone(addr.getValue()) + "/128"); - } - - public final @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr, final int mask) { - return newIpv6Prefix(stripZone(addr.getValue()), mask); - } - - public final @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr) { - return P6_FACTORY.newInstance(addr.getValue() + "/128"); - } - - public final @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr, final int mask) { - return newIpv6Prefix(addr.getValue(), mask); - } - - public final @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] address, final int mask) { - return ipv6PrefixForShort(address, 0, mask); - } - - public final @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] array, final int startOffset, - final int mask) { - if (mask == 0) { - // Easy case, reuse the template - return P6_FACTORY.getTemplate(); - } - - checkArgument(mask > 0 && mask <= 128, "Invalid mask %s", mask); - final int size = mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1); - - // Until we can instantiate an IPv6 address for a partial array, use a temporary buffer - byte[] tmp = new byte[Ipv6Utils.INET6_LENGTH]; - System.arraycopy(array, startOffset, tmp, 0, size); - return ipv6PrefixFor(tmp, mask); - } - - private Ipv6Prefix newIpv6Prefix(final String addr, final int mask) { - checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); - return P6_FACTORY.newInstance(addr + '/' + mask); - } - - public final @NonNull Entry splitIpv6Prefix(final @NonNull Ipv6Prefix prefix) { - return splitPrefix(V6NZ_FACTORY, prefix.getValue()); - } - - private static @NonNull T prefixToAddress(final StringValueObjectFactory factory, final String str) { - return factory.newInstance(str.substring(0, str.lastIndexOf('/'))); - } - - private static @NonNull Entry splitPrefix(final StringValueObjectFactory factory, - final String str) { - final int slash = str.lastIndexOf('/'); - return new SimpleImmutableEntry<>(factory.newInstance(str.substring(0, slash)), - Integer.valueOf(str.substring(slash + 1))); - } - - public final byte @NonNull[] ipv6PrefixToBytes(final @NonNull Ipv6Prefix prefix) { - final var str = prefix.getValue(); - final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH + 1]; - final int slash = str.lastIndexOf('/'); - Ipv6Utils.fillIpv6Bytes(bytes, str, slash); - bytes[Ipv6Utils.INET6_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10); - return bytes; - } - - private static @NonNull String addressStringV4(final InetAddress addr) { - requireAddress(addr); - checkArgument(addr instanceof Inet4Address, "Address has to be an Inet4Address"); - return addr.getHostAddress(); - } - - private static String addressStringV6(final byte @NonNull[] bytes) { - checkArgument(bytes.length == Ipv6Utils.INET6_LENGTH, "IPv6 address length is 16 bytes"); - - try { - return addressStringV6(Inet6Address.getByAddress(null, bytes, null)); - } catch (UnknownHostException e) { - throw new IllegalArgumentException(String.format("Invalid input %s", bytes), e); - } - } - - private static String addressStringV6(final InetAddress addr) { - requireAddress(addr); - checkArgument(addr instanceof Inet6Address, "Address has to be an Inet6Address"); - return addressStringV6((Inet6Address) addr); - } - - private static String addressStringV6(final Inet6Address addr) { - return InetAddresses.toAddrString(addr); - } - - private static String prefixStringV4(final byte @NonNull[] bytes) { - final StringBuilder sb = new StringBuilder(18); - Ipv4Utils.appendIpv4String(sb, bytes); - return sb.append("/32").toString(); - } - - private static String prefixStringV4(final byte @NonNull[] bytes, final int mask) { - checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); - - final StringBuilder sb = new StringBuilder(18); - Ipv4Utils.appendIpv4String(sb, bytes); - return sb.append('/').append(mask).toString(); - } - - private @NonNull Ipv4Prefix v4PrefixForShort(final byte @NonNull[] array, final int startOffset, final int size, - final int mask) { - if (startOffset == 0 && size == Ipv4Utils.INET4_LENGTH && array.length == Ipv4Utils.INET4_LENGTH) { - // Easy case, fall back to non-short - return ipv4PrefixFor(array, mask); - } - - final StringBuilder sb = new StringBuilder(18); - - // Add from address - sb.append(Byte.toUnsignedInt(array[startOffset])); - for (int i = 1; i < size; i++) { - sb.append('.').append(Byte.toUnsignedInt(array[startOffset + i])); - } - - // Add zeros - for (int i = size; i < Ipv4Utils.INET4_LENGTH; i++) { - sb.append(".0"); - } - - // Add mask - checkArgument(mask > 0 && mask <= 32, "Invalid mask %s", mask); - sb.append('/').append(mask); - - return P4_FACTORY.newInstance(sb.toString()); - } - - private static @NonNull Ipv6Address coerceIpv6Address(final @NonNull IpAddress addr) { - final var ret = addr.getIpv6Address(); - checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr); - return ret; - } - - private static @NonNull Ipv6AddressNoZone coerceIpv6AddressNoZone(final @NonNull IpAddressNoZone addr) { - final var ret = addr.getIpv6AddressNoZone(); - checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr); - return ret; - } -} diff --git a/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtil.java b/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtil.java index ae7943f2f9..5060ed7322 100644 --- a/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtil.java +++ b/model/ietf/rfc6991-ietf-inet-types/src/main/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtil.java @@ -7,22 +7,39 @@ */ package org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Verify.verify; +import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; +import com.google.common.net.InetAddresses; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.AbstractMap.SimpleImmutableEntry; import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.mdsal.binding.spec.reflect.StringValueObjectFactory; +import org.opendaylight.mdsal.model.ietf.util.Ipv4Utils; +import org.opendaylight.mdsal.model.ietf.util.Ipv6Utils; /** - * A set of utility methods to efficiently instantiate various ietf-inet-types DTOs. + * A set of utility methods to efficiently instantiate various {@code ietf-inet-types} DTOs. */ -@Beta -public final class IetfInetUtil extends AbstractIetfInetUtil { - public static final @NonNull IetfInetUtil INSTANCE = new IetfInetUtil(); - +public final class IetfInetUtil { + private static final StringValueObjectFactory V4NZ_FACTORY = + StringValueObjectFactory.create(Ipv4AddressNoZone.class, "0.0.0.0"); + private static final StringValueObjectFactory P4_FACTORY = + StringValueObjectFactory.create(Ipv4Prefix.class, "0.0.0.0/0"); + private static final StringValueObjectFactory V6NZ_FACTORY = + StringValueObjectFactory.create(Ipv6AddressNoZone.class, "::0"); + private static final StringValueObjectFactory P6_FACTORY = + StringValueObjectFactory.create(Ipv6Prefix.class, "::0/0"); private static final Pattern HOST_IPV4_PATTERN = Pattern.compile( "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])" + "(%[\\p{N}\\p{L}]+)?"); @@ -50,10 +67,6 @@ public final class IetfInetUtil extends AbstractIetfInetUtil { IPPREFIX_IPV4_PATTERN = Pattern.compile(Ipv4Prefix.PATTERN_CONSTANTS.get(0)); } - private IetfInetUtil() { - // Hidden on purpose - } - @Beta public static Host hostFor(final String str) { final Matcher ipv4Matcher = HOST_IPV4_PATTERN.matcher(str); @@ -115,4 +128,605 @@ public final class IetfInetUtil extends AbstractIetfInetUtil { return IPPREFIX_IPV4_PATTERN.matcher(defaultValue).matches() ? new IpPrefix(new Ipv4Prefix(defaultValue)) : new IpPrefix(new Ipv6Prefix(defaultValue)); } + + /** + * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length. + * + * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array + * @return An IpAddress object + * @throws IllegalArgumentException if bytes has length different from 4 or 6 + * @throws NullPointerException if bytes is null + */ + public static @NonNull IpAddress ipAddressFor(final byte @NonNull[] bytes) { + return switch (bytes.length) { + case Ipv4Utils.INET4_LENGTH -> new IpAddress(ipv4AddressFor(bytes)); + case Ipv6Utils.INET6_LENGTH -> new IpAddress(ipv6AddressFor(bytes)); + default -> throwInvalidArray(bytes); + }; + } + + public static @NonNull IpAddress ipAddressFor(final @NonNull InetAddress addr) { + requireAddress(addr); + if (addr instanceof Inet4Address) { + return new IpAddress(ipv4AddressFor(addr)); + } else if (addr instanceof Inet6Address) { + return new IpAddress(ipv6AddressFor(addr)); + } else { + throw unhandledAddress(addr); + } + } + + private static @NonNull T requireAddress(final T addr) { + return requireNonNull(addr, "Address must not be null"); + } + + /** + * Create an IpAddress by interpreting input bytes as an IPv4 or IPv6 address, based on array length. + * + * @param bytes 4-byte (IPv4) or 6-byte (IPv6) array + * @return A no-zone IpAddress object + * @throws IllegalArgumentException if bytes has length different from 4 or 6 + * @throws NullPointerException if bytes is null + */ + public static @NonNull IpAddressNoZone ipAddressNoZoneFor(final byte @NonNull[] bytes) { + return switch (bytes.length) { + case Ipv4Utils.INET4_LENGTH -> new IpAddressNoZone(ipv4AddressFor(bytes)); + case Ipv6Utils.INET6_LENGTH -> new IpAddressNoZone(ipv6AddressFor(bytes)); + default -> throwInvalidArray(bytes); + }; + } + + public static @NonNull IpAddressNoZone ipAddressNoZoneFor(final @NonNull InetAddress addr) { + requireAddress(addr); + if (addr instanceof Inet4Address) { + return new IpAddressNoZone(ipv4AddressFor(addr)); + } else if (addr instanceof Inet6Address) { + return new IpAddressNoZone(ipv6AddressFor(addr)); + } else { + throw unhandledAddress(addr); + } + } + + private static T throwInvalidArray(final byte[] bytes) { + throw new IllegalArgumentException("Invalid array length " + bytes.length); + } + + private static IllegalArgumentException unhandledAddress(final InetAddress addr) { + return new IllegalArgumentException("Unhandled address " + addr); + } + + /** + * Create an IpPrefix by combining the address with a mask. The address + * bytes are interpreted as an address and the specified mask is concatenated to + * it. The address bytes are not masked. + * + * @param bytes Input address as a 4-byte (IPv4) or 16-byte (IPv6) array + * @param mask Prefix mask + * @return An IpPrefix object + * @throws IllegalArgumentException if bytes has length different from 4 or 16 or if mask is not + * in range 0-32 or 0-128 respectively + * @throws NullPointerException if bytes is null + */ + public static @NonNull IpPrefix ipPrefixFor(final byte @NonNull[] bytes, final int mask) { + return switch (bytes.length) { + case Ipv4Utils.INET4_LENGTH -> new IpPrefix(ipv4PrefixFor(bytes, mask)); + case Ipv6Utils.INET6_LENGTH -> new IpPrefix(ipv6PrefixFor(bytes, mask)); + default -> throwInvalidArray(bytes); + }; + } + + public static @NonNull IpPrefix ipPrefixFor(final @NonNull InetAddress addr, final int mask) { + requireAddress(addr); + if (addr instanceof Inet4Address) { + return new IpPrefix(ipv4PrefixFor(addr, mask)); + } else if (addr instanceof Inet6Address) { + return new IpPrefix(ipv6PrefixFor(addr, mask)); + } else { + throw unhandledAddress(addr); + } + } + + public static @NonNull IpPrefix ipPrefixFor(final @NonNull IpAddress addr) { + final var v4 = addr.getIpv4Address(); + return v4 != null ? new IpPrefix(ipv4PrefixFor(v4)) : new IpPrefix(ipv6PrefixFor(coerceIpv6Address(addr))); + } + + public static @NonNull IpPrefix ipPrefixForNoZone(final @NonNull IpAddressNoZone addr) { + final var v4 = addr.getIpv4AddressNoZone(); + return v4 != null ? new IpPrefix(ipv4PrefixFor(inet4AddressForNoZone(v4))) + : new IpPrefix(ipv6PrefixFor(coerceIpv6AddressNoZone(addr))); + } + + public static @NonNull InetAddress inetAddressFor(final @NonNull IpAddress addr) { + final var v4 = addr.getIpv4Address(); + return v4 != null ? inet4AddressFor(v4) : inet6AddressFor(coerceIpv6Address(addr)); + } + + public static @NonNull InetAddress inetAddressForNoZone(final @NonNull IpAddressNoZone addr) { + final var v4 = addr.getIpv4AddressNoZone(); + return v4 != null ? inet4AddressForNoZone(v4) : inet6AddressForNoZone(coerceIpv6AddressNoZone(addr)); + } + + public static @NonNull Inet4Address inet4AddressFor(final @NonNull Ipv4Address addr) { + try { + return (Inet4Address) InetAddress.getByAddress(ipv4AddressBytes(addr)); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid address " + addr, e); + } + } + + public static @NonNull Inet4Address inet4AddressForNoZone(final @NonNull Ipv4AddressNoZone addr) { + try { + return (Inet4Address) InetAddress.getByAddress(ipv4AddressNoZoneBytes(addr)); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid address " + addr, e); + } + } + + public static @NonNull Inet6Address inet6AddressFor(final @NonNull Ipv6Address addr) { + try { + return (Inet6Address) InetAddress.getByAddress(ipv6AddressBytes(addr)); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid address " + addr, e); + } + } + + public static @NonNull Inet6Address inet6AddressForNoZone(final @NonNull Ipv6AddressNoZone addr) { + try { + return (Inet6Address) InetAddress.getByAddress(ipv6AddressNoZoneBytes(addr)); + } catch (UnknownHostException e) { + throw new IllegalArgumentException("Invalid address " + addr, e); + } + } + + /** + * Create an Ipv4AddressNoZone by interpreting input bytes as an IPv4 address. + * + * @param bytes 4-byte array + * @return An Ipv4AddressNoZone object + * @throws IllegalArgumentException if bytes has length different from 4 + * @throws NullPointerException if bytes is null + */ + public static @NonNull Ipv4AddressNoZone ipv4AddressFor(final byte @NonNull[] bytes) { + return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bytes)); + } + + /** + * Create an Ipv4AddressNoZone by interpreting an {@link Inet4Address}. + * + * @param addr An {@link Inet4Address} + * @return An Ipv4AddressNoZone object + * @throws IllegalArgumentException if addr is not an {@link Inet4Address} + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv4AddressNoZone ipv4AddressFor(final @NonNull InetAddress addr) { + return V4NZ_FACTORY.newInstance(addressStringV4(addr)); + } + + /** + * Create an Ipv4AddressNoZone by interpreting input 32 bits as an IPv4 address in big-endian format. + * + * @param bits 32 bits, big endian + * @return An Ipv4AddressNoZone object + */ + public static @NonNull Ipv4AddressNoZone ipv4AddressFor(final int bits) { + return V4NZ_FACTORY.newInstance(Ipv4Utils.addressString(bits)); + } + + /** + * Create an Ipv4AddressNoZone by interpreting an Ipv4Address. + * + * @param addr An Ipv4Address + * @return An Ipv4AddressNoZone object + * @throws NullPointerException if {@code addr} is {@code null} + */ + public static @NonNull Ipv4AddressNoZone ipv4AddressNoZoneFor(final @NonNull Ipv4Address addr) { + requireAddress(addr); + return addr instanceof Ipv4AddressNoZone noZone ? noZone + : V4NZ_FACTORY.newInstance(stripZone(addr.getValue())); + } + + public static @NonNull Ipv4AddressNoZone ipv4AddressFrom(final @NonNull Ipv4Prefix prefix) { + return prefixToAddress(V4NZ_FACTORY, prefix.getValue()); + } + + public static byte @NonNull[] ipv4AddressBytes(final @NonNull Ipv4Address addr) { + /* + * This implementation relies heavily on the input string having been validated to comply with + * the Ipv4Address pattern, which may include a zone index. + */ + final var str = addr.getValue(); + final int percent = str.indexOf('%'); + return Ipv4Utils.addressBytes(str, percent == -1 ? str.length() : percent); + } + + public static int ipv4AddressBits(final @NonNull Ipv4Address addr) { + final var str = addr.getValue(); + final int percent = str.indexOf('%'); + return Ipv4Utils.addressBits(str, percent == -1 ? str.length() : percent); + } + + public static byte @NonNull[] ipv4AddressNoZoneBytes(final @NonNull Ipv4AddressNoZone addr) { + /* + * This implementation relies heavily on the input string having been validated to comply with + * the Ipv4AddressNoZone pattern, which must not include a zone index. + */ + final String str = addr.getValue(); + return Ipv4Utils.addressBytes(str, str.length()); + } + + public static int ipv4AddressNoZoneBits(final @NonNull Ipv4AddressNoZone addr) { + final var str = addr.getValue(); + return Ipv4Utils.addressBits(str, str.length()); + } + + /** + * Create a /32 Ipv4Prefix by interpreting input bytes as an IPv4 address. + * + * @param bytes four-byte array + * @return An Ipv4Prefix object + * @throws IllegalArgumentException if bytes has length different from 4 + * @throws NullPointerException if bytes is null + */ + public static @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] bytes) { + return P4_FACTORY.newInstance(prefixStringV4(bytes)); + } + + /** + * Create a Ipv4Prefix by combining the address with a mask. The address + * bytes are interpreted as an address and the specified mask is concatenated to + * it. The address bytes are not masked, hence input address = { 1, 2, 3, 4 } + * and mask=24 will result in 1.2.3.4/24. + * + * @param address Input address as a 4-byte array + * @param mask Prefix mask + * @return An Ipv4Prefix object + * @throws IllegalArgumentException if bytes has length different from 4 or if mask is not in range 0-32 + * @throws NullPointerException if bytes is null + */ + public static @NonNull Ipv4Prefix ipv4PrefixFor(final byte @NonNull[] address, final int mask) { + return P4_FACTORY.newInstance(prefixStringV4(address, mask)); + } + + /** + * Create a /32 Ipv4Prefix for an {@link Inet4Address}. + * + * @param addr An {@link Inet4Address} + * @return An Ipv4Prefix object + * @throws IllegalArgumentException if addr is not an Inet4Address + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr) { + return P4_FACTORY.newInstance(addressStringV4(addr) + "/32"); + } + + /** + * Create a Ipv4Prefix by combining the address with a mask. The address bytes are not masked. + * + * @param addr An {@link Inet4Address} + * @param mask Prefix mask + * @return An Ipv4Prefix object + * @throws IllegalArgumentException if addr is not an Inet4Address or if mask is not in range 0-32 + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull InetAddress addr, final int mask) { + return newIpv4Prefix(addressStringV4(addr), mask); + } + + public static @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr) { + return P4_FACTORY.newInstance(stripZone(addr.getValue()) + "/32"); + } + + public static @NonNull Ipv4Prefix ipv4PrefixFor(final @NonNull Ipv4Address addr, final int mask) { + return newIpv4Prefix(stripZone(addr.getValue()), mask); + } + + public static @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr) { + return P4_FACTORY.newInstance(addr.getValue() + "/32"); + } + + public static @NonNull Ipv4Prefix ipv4PrefixForNoZone(final @NonNull Ipv4AddressNoZone addr, final int mask) { + return newIpv4Prefix(addr.getValue(), mask); + } + + public static @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] address, final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return P4_FACTORY.getTemplate(); + } + + return v4PrefixForShort(address, 0, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); + } + + public static @NonNull Ipv4Prefix ipv4PrefixForShort(final byte @NonNull[] array, final int startOffset, + final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return P4_FACTORY.getTemplate(); + } + + return v4PrefixForShort(array, startOffset, mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1), mask); + } + + private static String stripZone(final String str) { + final int percent = str.indexOf('%'); + return percent == -1 ? str : str.substring(0, percent); + } + + private static @NonNull Ipv4Prefix newIpv4Prefix(final String addr, final int mask) { + checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); + return P4_FACTORY.newInstance(addr + '/' + mask); + } + + public static @NonNull Entry splitIpv4Prefix(final @NonNull Ipv4Prefix prefix) { + return splitPrefix(V4NZ_FACTORY, prefix.getValue()); + } + + public static byte @NonNull[] ipv4PrefixToBytes(final @NonNull Ipv4Prefix prefix) { + final var str = prefix.getValue(); + final int slash = str.lastIndexOf('/'); + + final byte[] bytes = new byte[Ipv4Utils.INET4_LENGTH + 1]; + Ipv4Utils.fillIpv4Bytes(bytes, 0, str, 0, slash); + bytes[Ipv4Utils.INET4_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10); + return bytes; + } + + /** + * Create an Ipv6Address by interpreting input bytes as an IPv6 address. + * + * @param bytes 16-byte array + * @return An Ipv6Address object + * @throws IllegalArgumentException if bytes has length different from 16 + * @throws NullPointerException if {@code bytes} is {@code null} + */ + public static @NonNull Ipv6AddressNoZone ipv6AddressFor(final byte @NonNull[] bytes) { + return V6NZ_FACTORY.newInstance(addressStringV6(bytes)); + } + + /** + * Create an Ipv6Address by interpreting an {@link Inet6Address}. + * + * @param addr An {@link Inet6Address} + * @return An Ipv6Address object + * @throws IllegalArgumentException if @{code addr} is not an {@link Inet6Address} + * @throws NullPointerException if {@code addr} is {@code null} + */ + public static @NonNull Ipv6AddressNoZone ipv6AddressFor(final @NonNull InetAddress addr) { + return V6NZ_FACTORY.newInstance(addressStringV6(addr)); + } + + /** + * Create an Ipv6AddressNoZone by interpreting an Ipv6Address. + * + * @param addr An Ipv6Address + * @return An Ipv6AddressNoZone object + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv6AddressNoZone ipv6AddressNoZoneFor(final @NonNull Ipv6Address addr) { + requireAddress(addr); + return addr instanceof Ipv6AddressNoZone noZone ? noZone + : V6NZ_FACTORY.newInstance(stripZone(addr.getValue())); + } + + public static @NonNull Ipv6AddressNoZone ipv6AddressFrom(final @NonNull Ipv6Prefix prefix) { + return prefixToAddress(V6NZ_FACTORY, prefix.getValue()); + } + + public static byte @NonNull[] ipv6AddressBytes(final @NonNull Ipv6Address addr) { + final var str = addr.getValue(); + final int percent = str.indexOf('%'); + return ipv6StringBytes(str, percent == -1 ? str.length() : percent); + } + + public static byte @NonNull[] ipv6AddressNoZoneBytes(final @NonNull Ipv6Address addr) { + final var str = addr.getValue(); + return ipv6StringBytes(str, str.length()); + } + + private static byte @NonNull[] ipv6StringBytes(final @NonNull String str, final int limit) { + final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH]; + Ipv6Utils.fillIpv6Bytes(bytes, str, limit); + return bytes; + } + + /** + * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address. + * + * @param bytes four-byte array + * @return An Ipv6Prefix object + * @throws IllegalArgumentException if bytes has length different from 16 + * @throws NullPointerException if bytes is null + */ + public static @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] bytes) { + return P6_FACTORY.newInstance(addressStringV6(bytes) + "/128"); + } + + /** + * Create a Ipv6Prefix by combining the address with a mask. The address + * bytes are interpreted as an address and the specified mask is concatenated to + * it. The address bytes are not masked. + * + * @param address Input address as a 16-byte array + * @param mask Prefix mask + * @return An Ipv6Prefix object + * @throws IllegalArgumentException if bytes has length different from 16 or if mask is not in range 0-128 + * @throws NullPointerException if bytes is null + */ + public static @NonNull Ipv6Prefix ipv6PrefixFor(final byte @NonNull[] address, final int mask) { + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); + return P6_FACTORY.newInstance(addressStringV6(address) + '/' + mask); + } + + /** + * Create a /128 Ipv6Prefix by interpreting input bytes as an IPv6 address. + * + * @param addr an {@link Inet6Address} + * @return An Ipv6Prefix object + * @throws IllegalArgumentException if addr is not an Inet6Address + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr) { + return P6_FACTORY.newInstance(addressStringV6(addr) + "/128"); + } + + /** + * Create a Ipv6Prefix by combining the address with a mask. The address + * bytes are interpreted as an address and the specified mask is concatenated to + * it. The address bytes are not masked. + * + * @param addr Input address + * @param mask Prefix mask + * @return An Ipv6Prefix object + * @throws IllegalArgumentException if addr is not an Inet6Address or if mask is not in range 0-128 + * @throws NullPointerException if addr is null + */ + public static @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull InetAddress addr, final int mask) { + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); + return P6_FACTORY.newInstance(addressStringV6(addr) + '/' + mask); + } + + public static @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr) { + return P6_FACTORY.newInstance(stripZone(addr.getValue()) + "/128"); + } + + public static @NonNull Ipv6Prefix ipv6PrefixFor(final @NonNull Ipv6Address addr, final int mask) { + return newIpv6Prefix(stripZone(addr.getValue()), mask); + } + + public static @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr) { + return P6_FACTORY.newInstance(addr.getValue() + "/128"); + } + + public static @NonNull Ipv6Prefix ipv6PrefixForNoZone(final @NonNull Ipv6AddressNoZone addr, final int mask) { + return newIpv6Prefix(addr.getValue(), mask); + } + + public static @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] address, final int mask) { + return ipv6PrefixForShort(address, 0, mask); + } + + public static @NonNull Ipv6Prefix ipv6PrefixForShort(final byte @NonNull[] array, final int startOffset, + final int mask) { + if (mask == 0) { + // Easy case, reuse the template + return P6_FACTORY.getTemplate(); + } + + checkArgument(mask > 0 && mask <= 128, "Invalid mask %s", mask); + final int size = mask / Byte.SIZE + (mask % Byte.SIZE == 0 ? 0 : 1); + + // Until we can instantiate an IPv6 address for a partial array, use a temporary buffer + byte[] tmp = new byte[Ipv6Utils.INET6_LENGTH]; + System.arraycopy(array, startOffset, tmp, 0, size); + return ipv6PrefixFor(tmp, mask); + } + + private static Ipv6Prefix newIpv6Prefix(final String addr, final int mask) { + checkArgument(mask >= 0 && mask <= 128, "Invalid mask %s", mask); + return P6_FACTORY.newInstance(addr + '/' + mask); + } + + public static @NonNull Entry splitIpv6Prefix(final @NonNull Ipv6Prefix prefix) { + return splitPrefix(V6NZ_FACTORY, prefix.getValue()); + } + + private static @NonNull T prefixToAddress(final StringValueObjectFactory factory, final String str) { + return factory.newInstance(str.substring(0, str.lastIndexOf('/'))); + } + + private static @NonNull Entry splitPrefix(final StringValueObjectFactory factory, + final String str) { + final int slash = str.lastIndexOf('/'); + return new SimpleImmutableEntry<>(factory.newInstance(str.substring(0, slash)), + Integer.valueOf(str.substring(slash + 1))); + } + + public static byte @NonNull[] ipv6PrefixToBytes(final @NonNull Ipv6Prefix prefix) { + final var str = prefix.getValue(); + final byte[] bytes = new byte[Ipv6Utils.INET6_LENGTH + 1]; + final int slash = str.lastIndexOf('/'); + Ipv6Utils.fillIpv6Bytes(bytes, str, slash); + bytes[Ipv6Utils.INET6_LENGTH] = (byte)Integer.parseInt(str.substring(slash + 1), 10); + return bytes; + } + + private static @NonNull String addressStringV4(final InetAddress addr) { + requireAddress(addr); + checkArgument(addr instanceof Inet4Address, "Address has to be an Inet4Address"); + return addr.getHostAddress(); + } + + private static String addressStringV6(final byte @NonNull[] bytes) { + checkArgument(bytes.length == Ipv6Utils.INET6_LENGTH, "IPv6 address length is 16 bytes"); + + try { + return addressStringV6(Inet6Address.getByAddress(null, bytes, null)); + } catch (UnknownHostException e) { + throw new IllegalArgumentException(String.format("Invalid input %s", bytes), e); + } + } + + private static String addressStringV6(final InetAddress addr) { + requireAddress(addr); + checkArgument(addr instanceof Inet6Address, "Address has to be an Inet6Address"); + return addressStringV6((Inet6Address) addr); + } + + private static String addressStringV6(final Inet6Address addr) { + return InetAddresses.toAddrString(addr); + } + + private static String prefixStringV4(final byte @NonNull[] bytes) { + final StringBuilder sb = new StringBuilder(18); + Ipv4Utils.appendIpv4String(sb, bytes); + return sb.append("/32").toString(); + } + + private static String prefixStringV4(final byte @NonNull[] bytes, final int mask) { + checkArgument(mask >= 0 && mask <= 32, "Invalid mask %s", mask); + + final StringBuilder sb = new StringBuilder(18); + Ipv4Utils.appendIpv4String(sb, bytes); + return sb.append('/').append(mask).toString(); + } + + private static @NonNull Ipv4Prefix v4PrefixForShort(final byte @NonNull[] array, final int startOffset, + final int size, final int mask) { + if (startOffset == 0 && size == Ipv4Utils.INET4_LENGTH && array.length == Ipv4Utils.INET4_LENGTH) { + // Easy case, fall back to non-short + return ipv4PrefixFor(array, mask); + } + + final StringBuilder sb = new StringBuilder(18); + + // Add from address + sb.append(Byte.toUnsignedInt(array[startOffset])); + for (int i = 1; i < size; i++) { + sb.append('.').append(Byte.toUnsignedInt(array[startOffset + i])); + } + + // Add zeros + for (int i = size; i < Ipv4Utils.INET4_LENGTH; i++) { + sb.append(".0"); + } + + // Add mask + checkArgument(mask > 0 && mask <= 32, "Invalid mask %s", mask); + sb.append('/').append(mask); + + return P4_FACTORY.newInstance(sb.toString()); + } + + private static @NonNull Ipv6Address coerceIpv6Address(final @NonNull IpAddress addr) { + final var ret = addr.getIpv6Address(); + checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr); + return ret; + } + + private static @NonNull Ipv6AddressNoZone coerceIpv6AddressNoZone(final @NonNull IpAddressNoZone addr) { + final var ret = addr.getIpv6AddressNoZone(); + checkArgument(ret != null, "Address %s is neither IPv4 nor IPv6", addr); + return ret; + } } diff --git a/model/ietf/rfc6991-ietf-inet-types/src/test/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtilTest.java b/model/ietf/rfc6991-ietf-inet-types/src/test/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtilTest.java index 6d7f1a8078..85c124d71f 100644 --- a/model/ietf/rfc6991-ietf-inet-types/src/test/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtilTest.java +++ b/model/ietf/rfc6991-ietf-inet-types/src/test/java/org/opendaylight/yang/gen/v1/urn/ietf/params/xml/ns/yang/ietf/inet/types/rev130715/IetfInetUtilTest.java @@ -17,7 +17,6 @@ import static org.junit.Assert.assertThrows; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil.INSTANCE; import com.google.common.net.InetAddresses; import java.net.Inet4Address; @@ -52,32 +51,32 @@ public class IetfInetUtilTest { @Test public void testAddressToString() { - assertEquals(new Ipv4Prefix("1.2.3.4/8"), INSTANCE.ipv4PrefixFor(new Ipv4Address("1.2.3.4%1"), 8)); - assertEquals(new Ipv6Prefix("ff00::/8"), INSTANCE.ipv6PrefixFor(new Ipv6Address("ff00::%bar"), 8)); + assertEquals(new Ipv4Prefix("1.2.3.4/8"), IetfInetUtil.ipv4PrefixFor(new Ipv4Address("1.2.3.4%1"), 8)); + assertEquals(new Ipv6Prefix("ff00::/8"), IetfInetUtil.ipv6PrefixFor(new Ipv6Address("ff00::%bar"), 8)); } @Test public void testIpv4ZoneStripping() { final Ipv4AddressNoZone noZone = new Ipv4AddressNoZone("1.2.3.4"); - assertSame(noZone, INSTANCE.ipv4AddressNoZoneFor(noZone)); + assertSame(noZone, IetfInetUtil.ipv4AddressNoZoneFor(noZone)); final Ipv4Address withoutZone = new Ipv4Address(noZone); - final Ipv4AddressNoZone stripped = INSTANCE.ipv4AddressNoZoneFor(withoutZone); + final Ipv4AddressNoZone stripped = IetfInetUtil.ipv4AddressNoZoneFor(withoutZone); assertSame(withoutZone.getValue(), stripped.getValue()); - assertEquals(noZone, INSTANCE.ipv4AddressNoZoneFor(new Ipv4Address("1.2.3.4%1"))); + assertEquals(noZone, IetfInetUtil.ipv4AddressNoZoneFor(new Ipv4Address("1.2.3.4%1"))); } @Test public void testIpv6ZoneStripping() { final Ipv6AddressNoZone noZone = new Ipv6AddressNoZone("ff00::"); - assertSame(noZone, INSTANCE.ipv6AddressNoZoneFor(noZone)); + assertSame(noZone, IetfInetUtil.ipv6AddressNoZoneFor(noZone)); final Ipv6Address withoutZone = new Ipv6Address(noZone); - final Ipv6AddressNoZone stripped = INSTANCE.ipv6AddressNoZoneFor(withoutZone); + final Ipv6AddressNoZone stripped = IetfInetUtil.ipv6AddressNoZoneFor(withoutZone); assertSame(withoutZone.getValue(), stripped.getValue()); - assertEquals(noZone, INSTANCE.ipv6AddressNoZoneFor(new Ipv6Address("ff00::%1"))); + assertEquals(noZone, IetfInetUtil.ipv6AddressNoZoneFor(new Ipv6Address("ff00::%1"))); } @Test @@ -93,32 +92,32 @@ public class IetfInetUtilTest { assertV4Equals("128.16.0.127", "%5"); assertEquals(new IpAddress(new Ipv4Address("1.2.3.4")), - INSTANCE.ipAddressFor(INSTANCE.ipv4AddressBytes(new Ipv4Address("1.2.3.4")))); + IetfInetUtil.ipAddressFor(IetfInetUtil.ipv4AddressBytes(new Ipv4Address("1.2.3.4")))); assertNotEquals(new IpAddress(new Ipv4Address("2.3.4.5")), - INSTANCE.ipAddressFor(INSTANCE.ipv4AddressBytes(new Ipv4Address("1.2.3.4")))); + IetfInetUtil.ipAddressFor(IetfInetUtil.ipv4AddressBytes(new Ipv4Address("1.2.3.4")))); assertEquals(new IpAddress(new Ipv6Address("fe80::2002:b3ff:fe1e:8329")), - INSTANCE.ipAddressFor(INSTANCE.ipv6AddressBytes(new Ipv6Address("FE80::2002:B3FF:FE1E:8329")))); + IetfInetUtil.ipAddressFor(IetfInetUtil.ipv6AddressBytes(new Ipv6Address("FE80::2002:B3FF:FE1E:8329")))); assertNotEquals(new IpAddress(new Ipv6Address("feff::2002:b3ff:fe1e:8329")), - INSTANCE.ipAddressFor(INSTANCE.ipv6AddressBytes(new Ipv6Address("FE80::2002:B3FF:FE1E:8329")))); + IetfInetUtil.ipAddressFor(IetfInetUtil.ipv6AddressBytes(new Ipv6Address("FE80::2002:B3FF:FE1E:8329")))); assertEquals(new IpAddress(new Ipv4Address("1.2.3.4")), - INSTANCE.ipAddressFor(INSTANCE.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))))); + IetfInetUtil.ipAddressFor(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))))); assertNotEquals(new IpAddress(new Ipv4Address("2.3.4.5")), - INSTANCE.ipAddressFor(INSTANCE.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))))); + IetfInetUtil.ipAddressFor(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))))); assertEquals(new IpAddress(new Ipv6Address("fe80::2002:b3ff:fe1e:8329")), - INSTANCE.ipAddressFor(INSTANCE.inetAddressFor( + IetfInetUtil.ipAddressFor(IetfInetUtil.inetAddressFor( new IpAddress(new Ipv6Address("FE80::2002:B3FF:FE1E:8329"))))); assertNotEquals(new IpAddress(new Ipv6Address("FEFF::2002:B3FF:FE1E:8329")), - INSTANCE.ipAddressFor(INSTANCE.inetAddressFor( + IetfInetUtil.ipAddressFor(IetfInetUtil.inetAddressFor( new IpAddress(new Ipv6Address("FE80::2002:B3FF:FE1E:8329"))))); } @Test public void illegalArrayLengthForAddressTest() { final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.ipAddressFor(new byte[] { 0, 0, 0 })); + () -> IetfInetUtil.ipAddressFor(new byte[] { 0, 0, 0 })); assertEquals("Invalid array length 3", ex.getMessage()); } @@ -127,14 +126,14 @@ public class IetfInetUtilTest { final InetAddress adr = mock(InetAddress.class); doReturn("testAddress").when(adr).toString(); final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.ipAddressFor(adr)); + () -> IetfInetUtil.ipAddressFor(adr)); assertEquals("Unhandled address testAddress", ex.getMessage()); } @Test public void illegalArrayLengthforPrefixTest() { final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.ipPrefixFor(new byte[] { 0, 0, 0 }, 0)); + () -> IetfInetUtil.ipPrefixFor(new byte[] { 0, 0, 0 }, 0)); assertEquals("Invalid array length 3", ex.getMessage()); } @@ -144,56 +143,63 @@ public class IetfInetUtilTest { doReturn("testAddress").when(adr).toString(); final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.ipPrefixFor(adr, 0)); + () -> IetfInetUtil.ipPrefixFor(adr, 0)); assertEquals("Unhandled address testAddress", ex.getMessage()); } @Test public void ipv4Tests() { - assertEquals("1.2.3.4", INSTANCE.ipv4AddressFrom(new Ipv4Prefix("1.2.3.4/16")).getValue()); + assertEquals("1.2.3.4", IetfInetUtil.ipv4AddressFrom(new Ipv4Prefix("1.2.3.4/16")).getValue()); final var ipv4address = new Ipv4Address("1.2.3.4"); final var ipAddress = new IpAddress(ipv4address); - assertEquals("1.2.3.4/32", INSTANCE.ipv4PrefixFor(INSTANCE.ipv4AddressBytes(ipv4address)).getValue()); - assertEquals("1.2.3.4/32", INSTANCE.ipv4PrefixFor(INSTANCE.inetAddressFor(ipAddress)).getValue()); - assertEquals("1.2.3.4/32", INSTANCE.ipv4PrefixFor(ipv4address).getValue()); - assertEquals("1.2.3.4/16", INSTANCE.ipv4PrefixFor(ipv4address, 16).getValue()); - - assertEquals("0.0.0.0/0", INSTANCE.ipv4PrefixForShort(INSTANCE.ipv4AddressBytes(ipv4address), 0).getValue()); - assertEquals("1.2.3.4/32", INSTANCE.ipv4PrefixForShort(INSTANCE.ipv4AddressBytes(ipv4address), 32).getValue()); - assertEquals("0.0.0.0/0", INSTANCE.ipv4PrefixForShort(INSTANCE.ipv4AddressBytes(ipv4address), 0, 0).getValue()); + assertEquals("1.2.3.4/32", IetfInetUtil.ipv4PrefixFor(IetfInetUtil.ipv4AddressBytes(ipv4address)).getValue()); + assertEquals("1.2.3.4/32", IetfInetUtil.ipv4PrefixFor(IetfInetUtil.inetAddressFor(ipAddress)).getValue()); + assertEquals("1.2.3.4/32", IetfInetUtil.ipv4PrefixFor(ipv4address).getValue()); + assertEquals("1.2.3.4/16", IetfInetUtil.ipv4PrefixFor(ipv4address, 16).getValue()); + + assertEquals("0.0.0.0/0", + IetfInetUtil.ipv4PrefixForShort(IetfInetUtil.ipv4AddressBytes(ipv4address), 0).getValue()); + assertEquals("1.2.3.4/32", + IetfInetUtil.ipv4PrefixForShort(IetfInetUtil.ipv4AddressBytes(ipv4address), 32).getValue()); + assertEquals("0.0.0.0/0", + IetfInetUtil.ipv4PrefixForShort(IetfInetUtil.ipv4AddressBytes(ipv4address), 0, 0).getValue()); assertEquals("1.2.3.4/32", - INSTANCE.ipv4PrefixForShort(INSTANCE.ipv4AddressBytes(ipv4address), 0, 32).getValue()); - assertEquals("2.3.4.5/32", INSTANCE.ipv4PrefixForShort(new byte[] { 1, 2, 3, 4, 5 }, 1, 32).getValue()); - assertEquals("1.0.0.0/1", INSTANCE.ipv4PrefixForShort(new byte[] { 1, 2, 3, 4, 5 }, 0, 1).getValue()); + IetfInetUtil.ipv4PrefixForShort(IetfInetUtil.ipv4AddressBytes(ipv4address), 0, 32).getValue()); + assertEquals("2.3.4.5/32", IetfInetUtil.ipv4PrefixForShort(new byte[] { 1, 2, 3, 4, 5 }, 1, 32).getValue()); + assertEquals("1.0.0.0/1", IetfInetUtil.ipv4PrefixForShort(new byte[] { 1, 2, 3, 4, 5 }, 0, 1).getValue()); final var ipv4Prefix = new Ipv4Prefix("1.2.3.4/16"); - assertEquals("1.2.3.4", INSTANCE.splitIpv4Prefix(ipv4Prefix).getKey().getValue()); - assertEquals((Integer) 16, INSTANCE.splitIpv4Prefix(ipv4Prefix).getValue()); - assertArrayEquals(new byte[] { 1,2,3,4,16 }, INSTANCE.ipv4PrefixToBytes(ipv4Prefix)); + assertEquals("1.2.3.4", IetfInetUtil.splitIpv4Prefix(ipv4Prefix).getKey().getValue()); + assertEquals((Integer) 16, IetfInetUtil.splitIpv4Prefix(ipv4Prefix).getValue()); + assertArrayEquals(new byte[] { 1,2,3,4,16 }, IetfInetUtil.ipv4PrefixToBytes(ipv4Prefix)); } @Test public void ipv6Tests() { - assertEquals("::0", INSTANCE.ipv6AddressFrom(new Ipv6Prefix("::0/128")).getValue()); + assertEquals("::0", IetfInetUtil.ipv6AddressFrom(new Ipv6Prefix("::0/128")).getValue()); final var ipv6address = new Ipv6Address("::0"); final var ipAddress = new IpAddress(ipv6address); - assertEquals("::/128", INSTANCE.ipv6PrefixFor(INSTANCE.ipv6AddressBytes(ipv6address)).getValue()); - assertEquals("::/128", INSTANCE.ipv6PrefixFor(INSTANCE.inetAddressFor(ipAddress)).getValue()); - assertEquals("::0/128", INSTANCE.ipv6PrefixFor(ipv6address).getValue()); - assertEquals("::0/16", INSTANCE.ipv6PrefixFor(ipv6address, 16).getValue()); - - assertEquals("::0/0", INSTANCE.ipv6PrefixForShort(INSTANCE.ipv6AddressBytes(ipv6address), 0).getValue()); - assertEquals("::/64", INSTANCE.ipv6PrefixForShort(INSTANCE.ipv6AddressBytes(ipv6address), 64).getValue()); - assertEquals("::0/0", INSTANCE.ipv6PrefixForShort(INSTANCE.ipv6AddressBytes(ipv6address), 0, 0).getValue()); - assertEquals("::/32", INSTANCE.ipv6PrefixForShort(INSTANCE.ipv6AddressBytes(ipv6address), 0, 32).getValue()); - - assertEquals(Map.entry(new Ipv6Address("::"), 32), INSTANCE.splitIpv6Prefix(new Ipv6Prefix("::/32"))); + assertEquals("::/128", IetfInetUtil.ipv6PrefixFor(IetfInetUtil.ipv6AddressBytes(ipv6address)).getValue()); + assertEquals("::/128", IetfInetUtil.ipv6PrefixFor(IetfInetUtil.inetAddressFor(ipAddress)).getValue()); + assertEquals("::0/128", IetfInetUtil.ipv6PrefixFor(ipv6address).getValue()); + assertEquals("::0/16", IetfInetUtil.ipv6PrefixFor(ipv6address, 16).getValue()); + + assertEquals("::0/0", + IetfInetUtil.ipv6PrefixForShort(IetfInetUtil.ipv6AddressBytes(ipv6address), 0).getValue()); + assertEquals("::/64", + IetfInetUtil.ipv6PrefixForShort(IetfInetUtil.ipv6AddressBytes(ipv6address), 64).getValue()); + assertEquals("::0/0", + IetfInetUtil.ipv6PrefixForShort(IetfInetUtil.ipv6AddressBytes(ipv6address), 0, 0).getValue()); + assertEquals("::/32", + IetfInetUtil.ipv6PrefixForShort(IetfInetUtil.ipv6AddressBytes(ipv6address), 0, 32).getValue()); + + assertEquals(Map.entry(new Ipv6Address("::"), 32), IetfInetUtil.splitIpv6Prefix(new Ipv6Prefix("::/32"))); assertArrayEquals(new byte[] { 0, 10, 0, 0, 0, 0, 0, 0, 0, 11, 0, 12, 0, 13, 0, 14, 64 }, - INSTANCE.ipv6PrefixToBytes(new Ipv6Prefix("A::B:C:D:E/64"))); + IetfInetUtil.ipv6PrefixToBytes(new Ipv6Prefix("A::B:C:D:E/64"))); // verify that an IPv4-mapped IPv6 address gets parsed as an IPv6 address - assertEquals("::ffff:ab0:eb", INSTANCE.ipv6AddressFor( + assertEquals("::ffff:ab0:eb", IetfInetUtil.ipv6AddressFor( new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0xff, (byte) 0xff, 0x0a, (byte) 0xb0, 0, (byte) 0xeb}) .getValue()); } @@ -201,21 +207,21 @@ public class IetfInetUtilTest { @Test public void prefixTest() { assertEquals(new IpPrefix(new Ipv4Prefix("0.0.0.0/16")), - INSTANCE.ipPrefixFor(INSTANCE.inetAddressFor(new IpAddress(new Ipv4Address("0.0.0.0"))), 16)); + IetfInetUtil.ipPrefixFor(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv4Address("0.0.0.0"))), 16)); assertEquals(new IpPrefix(new Ipv6Prefix("::/64")), - INSTANCE.ipPrefixFor(INSTANCE.inetAddressFor(new IpAddress(new Ipv6Address("::"))), 64)); + IetfInetUtil.ipPrefixFor(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv6Address("::"))), 64)); assertEquals(new IpPrefix(new Ipv4Prefix("0.0.0.0/16")), - INSTANCE.ipPrefixFor(new byte[] { 0, 0, 0, 0 }, 16)); + IetfInetUtil.ipPrefixFor(new byte[] { 0, 0, 0, 0 }, 16)); assertEquals(new IpPrefix(new Ipv6Prefix("::/64")), - INSTANCE.ipPrefixFor(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 64)); + IetfInetUtil.ipPrefixFor(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 64)); } @Test public void inetAddressTest() { - assertThat(INSTANCE.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))), + assertThat(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv4Address("1.2.3.4"))), instanceOf(Inet4Address.class)); - assertThat(INSTANCE.inetAddressFor(new IpAddress(new Ipv6Address("FE80::2002:B3FF:FE1E:8329"))), + assertThat(IetfInetUtil.inetAddressFor(new IpAddress(new Ipv6Address("FE80::2002:B3FF:FE1E:8329"))), instanceOf(Inet6Address.class)); } @@ -228,7 +234,7 @@ public class IetfInetUtilTest { }).when(ipClass).getValue(); final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.inet4AddressFor(ipClass)); + () -> IetfInetUtil.inet4AddressFor(ipClass)); assertEquals("Invalid address testClass", ex.getMessage()); } @@ -241,36 +247,35 @@ public class IetfInetUtilTest { }).when(ipClass).getValue(); final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, - () -> INSTANCE.inet6AddressFor(ipClass)); + () -> IetfInetUtil.inet6AddressFor(ipClass)); assertEquals("Invalid address testClass", ex.getMessage()); } @Test public void testIpv4AddressForBits() { - assertEquals("1.2.3.4", INSTANCE.ipv4AddressFor(0x01020304).getValue()); - assertEquals("255.255.255.255", INSTANCE.ipv4AddressFor(0xFFFFFFFF).getValue()); + assertEquals("1.2.3.4", IetfInetUtil.ipv4AddressFor(0x01020304).getValue()); + assertEquals("255.255.255.255", IetfInetUtil.ipv4AddressFor(0xFFFFFFFF).getValue()); } @Test public void testIpv4AddressBits() { - assertEquals(0x01020304, INSTANCE.ipv4AddressBits(new Ipv4Address("1.2.3.4"))); - assertEquals(0xFFFFFFFF, INSTANCE.ipv4AddressBits(new Ipv4Address("255.255.255.255"))); + assertEquals(0x01020304, IetfInetUtil.ipv4AddressBits(new Ipv4Address("1.2.3.4"))); + assertEquals(0xFFFFFFFF, IetfInetUtil.ipv4AddressBits(new Ipv4Address("255.255.255.255"))); } @Test public void testIpv4AddressNoZoneBits() { - assertEquals(0x01020304, INSTANCE.ipv4AddressNoZoneBits(new Ipv4AddressNoZone("1.2.3.4"))); - assertEquals(0xFFFFFFFF, INSTANCE.ipv4AddressNoZoneBits(new Ipv4AddressNoZone("255.255.255.255"))); + assertEquals(0x01020304, IetfInetUtil.ipv4AddressNoZoneBits(new Ipv4AddressNoZone("1.2.3.4"))); + assertEquals(0xFFFFFFFF, IetfInetUtil.ipv4AddressNoZoneBits(new Ipv4AddressNoZone("255.255.255.255"))); } private static void assertV4Equals(final String literal, final String append) { final byte[] expected = InetAddresses.forString(literal).getAddress(); - final byte[] actual = INSTANCE.ipv4AddressBytes(new Ipv4Address(literal + append)); + final byte[] actual = IetfInetUtil.ipv4AddressBytes(new Ipv4Address(literal + append)); assertArrayEquals(expected, actual); } private static void assertV4Equals(final String literal) { assertV4Equals(literal, ""); } - } -- 2.36.6