diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2016-08-31 07:46:41 +0200 |
---|---|---|
committer | Maros Marsalek <mmarsale@cisco.com> | 2016-08-31 12:41:23 +0200 |
commit | 293ef1967dc6b523f8cf2ea4618bd39ca9a70b56 (patch) | |
tree | 5166ab138511cf4188d789cfd714889a5d6da26b | |
parent | 6d43491e197a5cb5a70adbbd7c63f458f852c38b (diff) |
HONEYCOMB-75 - Lisp implemetation
Rebased on final minimal distro
Change-Id: Ib71fc59e62dda4633f4f79c5c7417a4aaf02a177
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
68 files changed, 6330 insertions, 5 deletions
diff --git a/lisp/Readme.adoc b/lisp/Readme.adoc new file mode 100755 index 000000000..b3a01c6d3 --- /dev/null +++ b/lisp/Readme.adoc @@ -0,0 +1,3 @@ += Honeycomb translation layer SPI implementation for VPP's LISP APIs + +Provides customizers translating lisp.yang model into VPP's LISP API calls
\ No newline at end of file diff --git a/lisp/api/pom.xml b/lisp/api/pom.xml index c19b1125f..df5b7b3ba 100644..100755 --- a/lisp/api/pom.xml +++ b/lisp/api/pom.xml @@ -17,9 +17,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>io.fd.honeycomb.common</groupId> - <artifactId>impl-parent</artifactId> + <artifactId>api-parent</artifactId> <version>1.16.9-SNAPSHOT</version> - <relativePath>../../common/impl-parent</relativePath> + <relativePath>../../common/api-parent</relativePath> </parent> <modelVersion>4.0.0</modelVersion> diff --git a/lisp/api/src/main/yang/eid-mapping-context.yang b/lisp/api/src/main/yang/eid-mapping-context.yang new file mode 100644 index 000000000..3fb6d893a --- /dev/null +++ b/lisp/api/src/main/yang/eid-mapping-context.yang @@ -0,0 +1,44 @@ +module eid-mapping-context { + yang-version 1; + namespace "urn:honeycomb:params:xml:ns:yang:eid:mapping:context"; + prefix "eid-mapping-context"; + + description + "This module contains mappings stored for local-mappings id to actual eid"; + + revision "2016-08-01" { + description + "Initial revision."; + } + + import lisp {prefix "lisp";} + import ietf-lisp-address-types {prefix "lisp-types";} + + container contexts { + list eid-mapping-context { + + key "name"; + + leaf name { + type string; + } + + container mappings{ + list mapping { + + key "id"; + + leaf id { + type lisp:mapping-id; + description "Id that uniquely identifies a mapping"; + } + + container eid { + uses lisp-types:lisp-address; + description "EID address"; + } + } + } + } + } +}
\ No newline at end of file diff --git a/lisp/lisp2vpp/pom.xml b/lisp/lisp2vpp/pom.xml new file mode 100755 index 000000000..a606527b9 --- /dev/null +++ b/lisp/lisp2vpp/pom.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2015 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. +--> +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <groupId>io.fd.honeycomb.common</groupId> + <artifactId>impl-parent</artifactId> + <version>1.16.9-SNAPSHOT</version> + <relativePath>../../common/impl-parent</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <groupId>io.fd.honeycomb.lisp</groupId> + <artifactId>lisp2vpp</artifactId> + <version>1.16.9-SNAPSHOT</version> + <packaging>bundle</packaging> + + <properties> + <project.vpp.groupId>io.fd.honeycomb.vpp</project.vpp.groupId> + <project.honeycomb.groupId>io.fd.honeycomb</project.honeycomb.groupId> + </properties> + + <dependencies> + <dependency> + <groupId>${project.honeycomb.groupId}</groupId> + <artifactId>translate-spi</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.vpp.groupId}</groupId> + <artifactId>vpp-translate-utils</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>lisp-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.honeycomb.groupId}</groupId> + <artifactId>translate-impl</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.honeycomb.groupId}</groupId> + <artifactId>cfg-init</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.fd.vpp</groupId> + <artifactId>jvpp-core</artifactId> + <version>16.09-SNAPSHOT</version> + </dependency> + + <!-- DI --> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>${guice.version}</version> + </dependency> + <dependency> + <groupId>net.jmob</groupId> + <artifactId>guice.conf</artifactId> + <version>${guice.config.version}</version> + </dependency> + <dependency> + <groupId>com.google.inject.extensions</groupId> + <artifactId>guice-multibindings</artifactId> + <version>${guice.version}</version> + </dependency> + + <!-- Testing Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-all</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java new file mode 100644 index 000000000..ce95f12b7 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/LispModule.java @@ -0,0 +1,92 @@ +/* + * 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.lisp; + + +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT_PREFIX; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.AbstractModule; +import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; +import io.fd.honeycomb.data.init.DataTreeInitializer; +import io.fd.honeycomb.lisp.cfgattrs.LispConfiguration; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.initializers.LispInitializer; +import io.fd.honeycomb.lisp.translate.read.factory.LispStateReaderFactory; +import io.fd.honeycomb.lisp.translate.write.factory.LispWriterFactory; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import net.jmob.guice.conf.core.ConfigurationModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LispModule extends AbstractModule { + + private static final Logger LOG = LoggerFactory.getLogger(LispModule.class); + + @Override + protected void configure() { + LOG.info("Installing configuration module"); + install(ConfigurationModule.create()); + + LOG.info("Injecting Lisp configuration"); + requestInjection(LispConfiguration.class); + + LOG.info("Binding Naming context[{}]", LOCATOR_SET_CONTEXT); + bind(NamingContext.class) + .annotatedWith(Names.named(LOCATOR_SET_CONTEXT)) + .toInstance(new NamingContext(LOCATOR_SET_CONTEXT_PREFIX, LOCATOR_SET_CONTEXT)); + + LOG.info("Binding Eid context[{}]", LOCAL_MAPPING_CONTEXT); + bind(EidMappingContext.class) + .annotatedWith(Names.named(LOCAL_MAPPING_CONTEXT)) + .toInstance(new EidMappingContext(LOCAL_MAPPING_CONTEXT)); + + LOG.info("Binding Eid context[{}]", REMOTE_MAPPING_CONTEXT); + bind(EidMappingContext.class) + .annotatedWith(Names.named(REMOTE_MAPPING_CONTEXT)) + .toInstance(new EidMappingContext(REMOTE_MAPPING_CONTEXT)); + + LOG.info("Binding reader factories"); + final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + + LOG.info("Binding [{}]", LispStateReaderFactory.class.getName()); + readerFactoryBinder.addBinding().to(LispStateReaderFactory.class); + LOG.info("Reader factories binded"); + + LOG.info("Binding writer factories"); + final Multibinder<WriterFactory> writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + + LOG.info("Binding [{}]", LispWriterFactory.class.getName()); + writerFactoryBinder.addBinding().to(LispWriterFactory.class); + LOG.info("Writer factories binded"); + + LOG.info("Binding initializers"); + final Multibinder<DataTreeInitializer> initializerBinder = + Multibinder.newSetBinder(binder(), DataTreeInitializer.class); + + LOG.info("Binding [{}]", LispInitializer.class.getName()); + initializerBinder.addBinding().to(LispInitializer.class); + LOG.info("Initializers binded"); + + LOG.info("Module Lisp successfully configured"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java new file mode 100644 index 000000000..c38ca602f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/cfgattrs/LispConfiguration.java @@ -0,0 +1,64 @@ +/* + * 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.lisp.cfgattrs; + +import net.jmob.guice.conf.core.BindConfig; +import net.jmob.guice.conf.core.Syntax; + +/** + * Class containing static configuration for Lisp module,<br> + * either loaded from property file or statically typed + */ +@BindConfig(value = "lisp", syntax = Syntax.JSON) +public class LispConfiguration { + + //TODO - this constant should be part of V3po plugin + /** + * Interface index to name mapping + */ + public static final String INTERFACE_CONTEXT = "interface-context"; + + /** + * Locator set index to name mapping + */ + public static final String LOCATOR_SET_CONTEXT = "locator-set-context"; + + /** + * Local mappings's eid to name mapping + */ + public static final String LOCAL_MAPPING_CONTEXT = "local-mapping-context"; + + /** + * Remote mappings's eid to name mapping + */ + public static final String REMOTE_MAPPING_CONTEXT = "remote-mapping-context"; + + /** + * Central honeycomb initializer + */ + public static final String HONEYCOMB_INITIALIZER = "honeycomb-initializer"; + + /** + * Unique prefix for naming context of interfaces + **/ + public static final String INTERFACE_CONTEXT_PREFIX = "interface-"; + + /** + * Unique prefix for naming context of locator sets + **/ + public static final String LOCATOR_SET_CONTEXT_PREFIX = "locator-set-"; +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/EidMappingContext.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/EidMappingContext.java new file mode 100644 index 000000000..0c2e2180f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/context/util/EidMappingContext.java @@ -0,0 +1,235 @@ +/* + * 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.lisp.context.util; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.util.EidConverter; +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.eid.mapping.context.rev160801.Contexts; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.EidMappingContextKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.Mappings; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.Mapping; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.MappingBuilder; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.MappingKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.EidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +/** + * Utility class allowing {@link MappingId} to {@link Eid} mapping + */ +public class EidMappingContext { + + private static final Collector<Mapping, ?, Mapping> SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); + + private final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.EidMappingContext, EidMappingContextKey> + namingContextIid; + + /** + * Create new naming context + * + * @param instanceName name of this context instance. Will be used as list item identifier within context data tree + */ + public EidMappingContext(@Nonnull final String instanceName) { + namingContextIid = InstanceIdentifier.create(Contexts.class).child( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.EidMappingContext.class, + new EidMappingContextKey(instanceName)); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. + * + * @param eid eid of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized MappingId getId( + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + //dont create artificial name as naming context, to not create refference to some artificial(in vpp non-existing)eid + checkArgument(read.isPresent(), "No mapping stored for eid: %s", eid); + + return read.get().getMapping().stream() + .filter(mapping -> EidConverter.compareEids(mapping.getEid(), eid)) + .collect(SINGLE_ITEM_COLLECTOR).getId(); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. + * + * @param eid eid of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized MappingId getId( + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + //dont create artificial name as naming context, to not create refference to some artificial(in vpp non-existing)eid + checkArgument(read.isPresent(), "No mapping stored for eid: %s", eid); + + //this kind of comparing is needed ,because yang generated containers does not override equals,unless they are defined as types + //in this hierarchy the first that define proper equals is Ipv4Address/Ipv6Address/MacAddress + // + // From official javadoc + // The equals method for class Object implements the most discriminating possible equivalence relation on objects; + // that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object + // (x == y has the value true). + return read.get().getMapping().stream() + .filter(mapping -> EidConverter.compareEids(mapping.getEid(), eid)) + .collect(SINGLE_ITEM_COLLECTOR).getId(); + } + + /** + * Check whether mapping is present for index. + * + * @param eid eid of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsId( + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + //dont create artificial name as naming context, to not create refference to some artificial(in vpp non-existing)eid + checkArgument(read.isPresent(), "No mapping stored for eid: %s", eid); + + return read.isPresent() + ? read.get().getMapping().stream().anyMatch(mapping -> EidConverter.compareEids(mapping.getEid(), eid)) + : false; + } + + /** + * Check whether mapping is present for index. + * + * @param eid eid of a mapped item + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsId( + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + checkArgument(read.isPresent(), "No mapping stored for eid: %s", eid); + + return read.isPresent() + ? read.get().getMapping().stream().anyMatch(mapping -> EidConverter.compareEids(mapping.getEid(), eid)) + : false; + } + + + /** + * Add mapping to current context + * + * @param index index of a mapped item + * @param eid eid data + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void addEid( + @Nonnull final MappingId index, + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid eid, + final MappingContext mappingContext) { + + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(index); + //this copy is needed (type of eid in mapping is different that in local mapping,they only have same ancestor) + mappingContext.put(mappingIid, new MappingBuilder().setId(index).setEid(copyEid(eid)).build()); + } + + /** + * Add mapping to current context + * + * @param index index of a mapped item + * @param eid eid data + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void addEid( + @Nonnull final MappingId index, + @Nonnull final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid eid, + final MappingContext mappingContext) { + + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(index); + mappingContext.put(mappingIid, new MappingBuilder().setId(index).setEid(copyEid(eid)).build()); + } + + private KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final MappingId index) { + return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(index)); + } + + private Eid copyEid( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid eid) { + return new EidBuilder().setAddress(eid.getAddress()).setAddressType(eid.getAddressType()) + .setVirtualNetworkId(eid.getVirtualNetworkId()).build(); + } + + private Eid copyEid( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid eid) { + return new EidBuilder().setAddress(eid.getAddress()).setAddressType(eid.getAddressType()) + .setVirtualNetworkId(eid.getVirtualNetworkId()).build(); + } + + /** + * Remove mapping from current context + * + * @param index identificator of a mapped item + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void removeEid(@Nonnull final MappingId index, final MappingContext mappingContext) { + mappingContext.delete(getMappingIid(index)); + } + + /** + * Returns index value associated with the given name. + * + * @param index index whitch should value sits on + * @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 Eid getEid(@Nonnull final MappingId index, final MappingContext mappingContext) { + final Optional<Mapping> read = mappingContext.read(getMappingIid(index)); + checkArgument(read.isPresent(), "No mapping stored for index: %s", index); + return mappingContext.read(getMappingIid(index)).get().getEid(); + } + + /** + * Check whether mapping is present for name. + * + * @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 containsEid(@Nonnull final MappingId index, + @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getMappingIid(index)).isPresent(); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/initializers/LispInitializer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/initializers/LispInitializer.java new file mode 100755 index 000000000..105ee0aec --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/initializers/LispInitializer.java @@ -0,0 +1,68 @@ +/* + * 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.lisp.translate.initializers; + + +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.HONEYCOMB_INITIALIZER; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.data.init.AbstractDataTreeConverter; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Initializes vpp node in config data tree based on operational state + */ +public class LispInitializer extends AbstractDataTreeConverter<LispState, Lisp> { + + private static final Logger LOG = LoggerFactory.getLogger(LispInitializer.class); + + @Inject + public LispInitializer(@Named(HONEYCOMB_INITIALIZER) final DataBroker bindingDataBroker) { + super(bindingDataBroker, InstanceIdentifier.create(LispState.class), InstanceIdentifier.create(Lisp.class)); + } + + @Override + protected Lisp convert(final LispState operationalData) { + LOG.debug("LispInitializer started"); + final LispBuilder lispBuilder = new LispBuilder(); + + // set everything from LispState to LispBuilder + // this is necessary in cases, when HC connects to a running VPP with some LISP configuration. HC needs to + // reconstruct configuration based on what's present in VPP in order to support subsequent configuration changes + // without any issues + + // the other reason this should work is HC persistence, so that HC after restart only performs diff (only push + // configuration that is not currently in VPP, but is persisted. If they are equal skip any VPP calls) + // updates to VPP. If this is not fully implemented (depending on VPP implementation, restoration of persisted + // configuration can fail) + + return lispBuilder.setEnable(operationalData.isEnable()) + .setEidTable(operationalData.getEidTable()) + .setLocatorSets(operationalData.getLocatorSets()) + .setMapResolvers(operationalData.getMapResolvers()) + .setPitrCfg(operationalData.getPitrCfg()) + .build(); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java new file mode 100755 index 000000000..1a9721ca0 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/AdjacencyCustomizer.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2015 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.lisp.translate.read; + + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import java.util.Collections; +import java.util.List; +import javax.annotation.Nonnull; +import javax.naming.OperationNotSupportedException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.AdjacenciesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.AdjacencyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.AdjacencyKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class AdjacencyCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Adjacency, AdjacencyKey, AdjacencyBuilder> { + + public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Nonnull + @Override + public List<AdjacencyKey> getAllIds(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final ReadContext context) throws ReadFailedException { + + //does not throw exception to not disturb lisp state reading + return Collections.emptyList(); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Adjacency> readData) { + ((AdjacenciesBuilder) builder).setAdjacency(readData); + } + + @Nonnull + @Override + public AdjacencyBuilder getBuilder(@Nonnull final InstanceIdentifier<Adjacency> id) { + return new AdjacencyBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final AdjacencyBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + //TODO - finish after https://jira.fd.io/browse/VPP-362 + throw new ReadFailedException(id, new OperationNotSupportedException("Operation not supported")); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java new file mode 100755 index 000000000..6d5abae8b --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/InterfaceCustomizer.java @@ -0,0 +1,157 @@ +/* + * 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.lisp.translate.read; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.read.dump.check.LocatorDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.LocatorDumpExecutor; +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.LocatorDumpParams; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispLocatorDetails; +import org.openvpp.jvpp.core.dto.LispLocatorDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for reading {@code Interface}<br> Currently not supported by jvpp + */ +public class InterfaceCustomizer + extends FutureJVppCustomizer + implements ListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(InterfaceCustomizer.class); + private static final String KEY_BASE = InterfaceCustomizer.class.getName(); + + private final NamingContext interfaceContext; + private final NamingContext locatorSetContext; + private final DumpCacheManager<LispLocatorDetailsReplyDump, LocatorDumpParams> dumpCacheManager; + + public InterfaceCustomizer( + @Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext) { + super(futureJvpp); + this.interfaceContext = checkNotNull(interfaceContext, "Interface context cannot be null"); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator set context cannot be null"); + this.dumpCacheManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorDetailsReplyDump, LocatorDumpParams>() + .withExecutor(new LocatorDumpExecutor(futureJvpp)) + .withNonEmptyPredicate(new LocatorDumpCheck()) + .build(); + } + + @Override + public InterfaceBuilder getBuilder(InstanceIdentifier<Interface> id) { + return new InterfaceBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Interface> id, InterfaceBuilder builder, ReadContext ctx) + throws ReadFailedException { + checkState(id.firstKeyOf(LocatorSet.class) != null, "Cannot find reference to parent locator set"); + final String name = id.firstKeyOf(LocatorSet.class).getName(); + + checkState(locatorSetContext.containsIndex(name, ctx.getMappingContext())); + final int interfaceIndex = locatorSetContext.getIndex(name, ctx.getMappingContext()); + final LocatorDumpParams params = new LocatorDumpParams.LocatorDumpParamsBuilder() + .setFilter(LocatorDumpParams.LocatorDumpFilter.LOCAL) + .setLocatorSetIndex(interfaceIndex) + .build(); + + Optional<LispLocatorDetailsReplyDump> reply; + try { + reply = dumpCacheManager.getDump(KEY_BASE, ctx.getModificationCache(), params); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (reply.isPresent()) { + final LispLocatorDetails details = reply.get() + .lispLocatorDetails + .stream() + .filter(a -> a.swIfIndex == interfaceIndex) + .collect(RWUtils.singleItemCollector()); + + builder.setPriority(Byte.valueOf(details.priority).shortValue()); + builder.setWeight(Byte.valueOf(details.weight).shortValue()); + builder.setInterfaceRef(name); + builder.setKey(new InterfaceKey(name)); + } + } + + @Override + public List<InterfaceKey> getAllIds(InstanceIdentifier<Interface> id, ReadContext context) + throws ReadFailedException { + + checkState(id.firstKeyOf(LocatorSet.class) != null, "Cannot find reference to parent locator set"); + final String name = id.firstKeyOf(LocatorSet.class).getName(); + + checkState(locatorSetContext.containsIndex(name, context.getMappingContext()), "No mapping for %s", name); + final LocatorDumpParams params = new LocatorDumpParams.LocatorDumpParamsBuilder() + .setFilter(LocatorDumpParams.LocatorDumpFilter.LOCAL) + .setLocatorSetIndex(locatorSetContext.getIndex(name, context.getMappingContext())) + .build(); + + + Optional<LispLocatorDetailsReplyDump> reply; + try { + reply = dumpCacheManager.getDump(KEY_BASE, context.getModificationCache(), params); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (reply.isPresent()) { + return reply.get() + .lispLocatorDetails + .stream() + .map(a -> new InterfaceKey(interfaceContext.getName(a.swIfIndex, context.getMappingContext()))) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<Interface> readData) { + ((LocatorSetBuilder) builder).setInterface(readData); + } +}
\ No newline at end of file diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LispStateCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LispStateCustomizer.java new file mode 100755 index 000000000..90e0a491a --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LispStateCustomizer.java @@ -0,0 +1,75 @@ +/* + * 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.lisp.translate.read; + + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispStateBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.ShowLispStatus; +import org.openvpp.jvpp.core.dto.ShowLispStatusReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer that handles reads of {@code LispState} + */ +public class LispStateCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer<LispState, LispStateBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(LispStateCustomizer.class); + + public LispStateCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public LispStateBuilder getBuilder(InstanceIdentifier<LispState> id) { + return new LispStateBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<LispState> id, LispStateBuilder builder, ReadContext ctx) + throws ReadFailedException { + + ShowLispStatusReply reply; + try { + reply = TranslateUtils.getReply(getFutureJVpp().showLispStatus(new ShowLispStatus()).toCompletableFuture()); + } catch (TimeoutException | VppBaseCallException e) { + throw new ReadFailedException(id, e); + } + + builder.setEnable(TranslateUtils.byteToBoolean(reply.featureStatus)); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, @Nonnull final LispState readValue) { + LOG.warn("Merge is unsupported for data roots"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.java new file mode 100755 index 000000000..0381df05d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocalMappingCustomizer.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.honeycomb.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.valueOf; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.FilterType; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.MappingsDumpParamsBuilder; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.QuantityType; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.compareAddresses; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.getArrayAsEidLocal; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.getEidAsByteArray; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.getEidType; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.getPrefixLength; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.read.dump.check.MappingsDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.MappingsDumpExecutor; +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.LocalMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMappingKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispEidTableDetails; +import org.openvpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for reading {@code LocalMapping}<br> Currently unsupported by jvpp + */ +public class LocalMappingCustomizer + extends FutureJVppCustomizer + implements ListReaderCustomizer<LocalMapping, LocalMappingKey, LocalMappingBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(LocalMappingCustomizer.class); + private static final String KEY = LocalMappingCustomizer.class.getName(); + + private final DumpCacheManager<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; + private final MappingsDumpExecutor dumpExecutor; + private final NamingContext locatorSetContext; + private final EidMappingContext localMappingContext; + + public LocalMappingCustomizer(@Nonnull FutureJVppCore futureJvpp, @Nonnull NamingContext locatorSetContext, + @Nonnull EidMappingContext localMappingsContext) { + super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator Set Mapping Context cannot be null"); + this.localMappingContext = checkNotNull(localMappingsContext, "Local mappings context cannot be null"); + this.dumpExecutor = new MappingsDumpExecutor(futureJvpp); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableDetailsReplyDump, MappingsDumpParams>() + .withExecutor(dumpExecutor) + .withNonEmptyPredicate(new MappingsDumpCheck()) + .build(); + } + + + @Override + public LocalMappingBuilder getBuilder(InstanceIdentifier<LocalMapping> id) { + return new LocalMappingBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<LocalMapping> id, LocalMappingBuilder builder, + ReadContext ctx) throws ReadFailedException { + checkState(id.firstKeyOf(LocalMapping.class) != null, "No key present for id({})", id); + checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified"); + + //checks whether there is an existing mapping + final MappingId mappingId = id.firstKeyOf(LocalMapping.class).getId(); + checkState(localMappingContext.containsEid(mappingId, ctx.getMappingContext())); + + final long vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier(); + + final String localMappingId = id.firstKeyOf(LocalMapping.class).getId().getValue(); + final Eid eid = localMappingContext.getEid(mappingId, ctx.getMappingContext()); + + //Requesting for specific mapping dump,only from local mappings with specified eid/vni/eid type + final MappingsDumpParams dumpParams = new MappingsDumpParams.MappingsDumpParamsBuilder() + .setEidSet(QuantityType.SPECIFIC) + .setVni(Long.valueOf(vni).intValue()) + .setEid(getEidAsByteArray(eid)) + .setEidType(getEidType(eid)) + .setPrefixLength(getPrefixLength(eid)) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + Optional<LispEidTableDetailsReplyDump> replyOptional; + + try { + replyOptional = + dumpManager.getDump(bindKey("SPECIFIC_" + localMappingId), ctx.getModificationCache(), dumpParams); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (replyOptional.isPresent()) { + LOG.debug("Valid dump loaded"); + + LispEidTableDetails details = replyOptional.get().lispEidTableDetails.stream() + .filter(a -> compareAddresses(eid.getAddress(), + getArrayAsEidLocal(valueOf(a.eidType), a.eid).getAddress())) + .collect( + RWUtils.singleItemCollector()); + + //in case of local mappings,locator_set_index stands for interface index + checkState(locatorSetContext.containsName(details.locatorSetIndex, ctx.getMappingContext())); + builder.setLocatorSet(locatorSetContext.getName(details.locatorSetIndex, ctx.getMappingContext())); + builder.setKey(new LocalMappingKey(new MappingId(id.firstKeyOf(LocalMapping.class).getId()))); + builder.setEid(getArrayAsEidLocal(valueOf(details.eidType), details.eid)); + } else { + LOG.debug("No data dumped"); + } + } + + @Override + public List<LocalMappingKey> getAllIds(InstanceIdentifier<LocalMapping> id, ReadContext context) + throws ReadFailedException { + + checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified"); + + //request for all local mappings + final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder() + .setVni(Long.valueOf(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()).intValue()) + .setFilter(FilterType.LOCAL) + .setEidSet(QuantityType.ALL) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + Optional<LispEidTableDetailsReplyDump> replyOptional; + try { + replyOptional = dumpManager.getDump(bindKey("ALL_LOCAL"), context.getModificationCache(), dumpParams); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (replyOptional.isPresent()) { + LOG.debug("Valid dump loaded"); + return replyOptional.get().lispEidTableDetails.stream().map(a -> new LocalMappingKey( + new MappingId( + localMappingContext.getId( + getArrayAsEidLocal(valueOf(a.eidType), a.eid), + context.getMappingContext())))) + .collect(Collectors.toList()); + } else { + LOG.debug("No data dumped"); + return Collections.emptyList(); + } + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<LocalMapping> readData) { + ((LocalMappingsBuilder) builder).setLocalMapping(readData); + } + + private static String bindKey(String prefix) { + return prefix + "_" + KEY; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java new file mode 100755 index 000000000..f8da94f1a --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/LocatorSetCustomizer.java @@ -0,0 +1,130 @@ +/* + * 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.lisp.translate.read; + +import static io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.read.dump.check.LocatorSetsDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.LocatorSetsDumpExecutor; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetails; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LocatorSetCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<LocatorSet, LocatorSetKey, LocatorSetBuilder> { + + //TODO - temporary as public because of hack in write customizer in *.write.LocatorSetCustomizer + public static final String LOCATOR_SETS_CACHE_ID = LocatorSetCustomizer.class.getName(); + private static final Logger LOG = LoggerFactory.getLogger(LocatorSetCustomizer.class); + + private final DumpCacheManager<LispLocatorSetDetailsReplyDump, Void> dumpManager; + + public LocatorSetCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorSetDetailsReplyDump, Void>() + .withExecutor(new LocatorSetsDumpExecutor(futureJvpp)) + .withNonEmptyPredicate(new LocatorSetsDumpCheck()) + .build(); + } + + @Override + public LocatorSetBuilder getBuilder(InstanceIdentifier<LocatorSet> id) { + return new LocatorSetBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<LocatorSet> id, LocatorSetBuilder builder, ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes for Locator Set {}", id); + + Optional<LispLocatorSetDetailsReplyDump> dumpOptional; + + try { + dumpOptional = dumpManager.getDump(LOCATOR_SETS_CACHE_ID, ctx.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + if (!dumpOptional.isPresent()) { + LOG.warn("No dump present for Locator Set {}", id); + return; + } + + String keyName = id.firstKeyOf(LocatorSet.class).getName(); + LispLocatorSetDetailsReplyDump dump = dumpOptional.get(); + + java.util.Optional<LispLocatorSetDetails> details = dump.lispLocatorSetDetails.stream() + .filter(n -> keyName.equals(TranslateUtils.toString(n.locatorSetName))) + .findFirst(); + + if (details.isPresent()) { + final String name = TranslateUtils.toString(details.get().locatorSetName); + + builder.setName(name); + builder.setKey(new LocatorSetKey(name)); + } else { + LOG.warn("Locator Set {} not found in dump", id); + } + } + + @Override + public List<LocatorSetKey> getAllIds(InstanceIdentifier<LocatorSet> id, ReadContext context) + throws ReadFailedException { + LOG.debug("Dumping Locator Set {}", id); + + Optional<LispLocatorSetDetailsReplyDump> dumpOptional = null; + try { + dumpOptional = dumpManager.getDump(LOCATOR_SETS_CACHE_ID, context.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + LOG.error("Error dumping Locator Set {}", e, id); + return Collections.emptyList(); + } + + if (dumpOptional.isPresent()) { + return dumpOptional.get().lispLocatorSetDetails.stream() + .map(set -> new LocatorSetKey(TranslateUtils.toString(set.locatorSetName))) + .collect(Collectors.toList()); + } else { + LOG.warn("No data dumped for Locator Set {}", id); + return Collections.emptyList(); + } + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<LocatorSet> readData) { + ((LocatorSetsBuilder) builder).setLocatorSet(readData); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java new file mode 100755 index 000000000..0b1269648 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/MapResolverCustomizer.java @@ -0,0 +1,132 @@ +/* + * 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.lisp.translate.read; + +import static io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.read.dump.check.MapResolverDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.MapResolversDumpExecutor; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.MapResolversBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolverBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolverKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispMapResolverDetails; +import org.openvpp.jvpp.core.dto.LispMapResolverDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MapResolverCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<MapResolver, MapResolverKey, MapResolverBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(MapResolverCustomizer.class); + private static final String MAP_RESOLVERS_CACHE_ID = MapResolverCustomizer.class.getName(); + + private final DumpCacheManager<LispMapResolverDetailsReplyDump, Void> dumpManager; + + public MapResolverCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispMapResolverDetailsReplyDump, Void>() + .withExecutor(new MapResolversDumpExecutor((futureJvpp))) + .withNonEmptyPredicate(new MapResolverDumpCheck()) + .build(); + } + + @Override + public MapResolverBuilder getBuilder(InstanceIdentifier<MapResolver> id) { + return new MapResolverBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<MapResolver> id, MapResolverBuilder builder, ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading attributes..."); + + Optional<LispMapResolverDetailsReplyDump> dumpOptional = null; + try { + dumpOptional = dumpManager.getDump(MAP_RESOLVERS_CACHE_ID, ctx.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (!dumpOptional.isPresent()) { + LOG.warn("No data dumped"); + return; + } + + MapResolverKey key = id.firstKeyOf(MapResolver.class); + LispMapResolverDetailsReplyDump dump = dumpOptional.get(); + + //cannot use RWUtils.singleItemCollector(),there is some problem with generic params binding + java.util.Optional<LispMapResolverDetails> mapResolverOptional = + dump.lispMapResolverDetails.stream().filter(key::equals).findFirst(); + + if (mapResolverOptional.isPresent()) { + LispMapResolverDetails details = mapResolverOptional.get(); + + builder.setKey(key); + builder.setIpAddress( + TranslateUtils.arrayToIpAddress(TranslateUtils.byteToBoolean(details.isIpv6), details.ipAddress)); + } else { + LOG.warn("No data found with matching key"); + } + + } + + @Override + public List<MapResolverKey> getAllIds(InstanceIdentifier<MapResolver> id, ReadContext context) + throws ReadFailedException { + LOG.debug("Dumping MapResolver..."); + + Optional<LispMapResolverDetailsReplyDump> dumpOptional = null; + try { + dumpOptional = dumpManager.getDump(MAP_RESOLVERS_CACHE_ID, context.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (!dumpOptional.isPresent()) { + LOG.warn("No data dumped"); + return Collections.emptyList(); + } + + return dumpOptional.get().lispMapResolverDetails.stream() + .map(resolver -> new MapResolverKey( + TranslateUtils + .arrayToIpAddress(TranslateUtils.byteToBoolean(resolver.isIpv6), resolver.ipAddress))) + .collect(Collectors.toList()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<MapResolver> readData) { + ((MapResolversBuilder) builder).setMapResolver(readData); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/PitrCfgCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/PitrCfgCustomizer.java new file mode 100755 index 000000000..effeb9674 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/PitrCfgCustomizer.java @@ -0,0 +1,83 @@ +/* + * 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.lisp.translate.read; + + +import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.getReply; + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import java.util.concurrent.TimeoutException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfgBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.ShowLispPitr; +import org.openvpp.jvpp.core.dto.ShowLispPitrReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for reading {@link PitrCfg}<br> Currently unsupported in jvpp + */ +public class PitrCfgCustomizer extends FutureJVppCustomizer implements ReaderCustomizer<PitrCfg, PitrCfgBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(PitrCfgCustomizer.class); + + public PitrCfgCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public PitrCfgBuilder getBuilder(InstanceIdentifier<PitrCfg> id) { + return new PitrCfgBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<PitrCfg> id, PitrCfgBuilder builder, ReadContext ctx) + throws ReadFailedException { + LOG.debug("Reading status for Lisp Pitr node {}", id); + + ShowLispPitrReply reply; + + try { + reply = getPitrStatus(); + } catch (TimeoutException | VppBaseCallException e) { + throw new ReadFailedException(id, e); + } + + builder.setLocatorSet(TranslateUtils.toString(reply.locatorSetName)); + LOG.debug("Reading status for Lisp Pitr node {} successfull", id); + } + + @Override + public void merge(Builder<? extends DataObject> parentBuilder, PitrCfg readValue) { + ((LispStateBuilder) parentBuilder).setPitrCfg(readValue); + } + + public ShowLispPitrReply getPitrStatus() throws TimeoutException, VppBaseCallException { + return getReply(getFutureJVpp().showLispPitr(new ShowLispPitr()).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java new file mode 100755 index 000000000..81405ecec --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/RemoteMappingCustomizer.java @@ -0,0 +1,203 @@ +/* + * 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.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.valueOf; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.FilterType; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.MappingsDumpParamsBuilder; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.compareAddresses; +import static io.fd.honeycomb.lisp.translate.util.EidConverter.getArrayAsEidLocal; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.read.dump.check.MappingsDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.MappingsDumpExecutor; +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.QuantityType; +import io.fd.honeycomb.lisp.translate.util.EidConverter; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.RemoteMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispEidTableDetails; +import org.openvpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for reading {@code RemoteMapping}<br> + */ +public class RemoteMappingCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<RemoteMapping, RemoteMappingKey, RemoteMappingBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(RemoteMappingCustomizer.class); + private static final String KEY = RemoteMappingCustomizer.class.getName(); + + private final DumpCacheManager<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; + private final EidMappingContext remoteMappingContext; + + public RemoteMappingCustomizer(@Nonnull FutureJVppCore futureJvpp, + @Nonnull EidMappingContext remoteMappingContext) { + super(futureJvpp); + this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mappings not present"); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableDetailsReplyDump, MappingsDumpParams>() + .withExecutor(new MappingsDumpExecutor(futureJvpp)) + .withNonEmptyPredicate(new MappingsDumpCheck()) + .build(); + } + + + @Override + public RemoteMappingBuilder getBuilder(InstanceIdentifier<RemoteMapping> id) { + return new RemoteMappingBuilder(); + } + + private Eid copyEid( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid eid) { + return new EidBuilder().setAddress(eid.getAddress()).setAddressType(eid.getAddressType()) + .setVirtualNetworkId(eid.getVirtualNetworkId()).build(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<RemoteMapping> id, RemoteMappingBuilder builder, + ReadContext ctx) + throws ReadFailedException { + checkState(id.firstKeyOf(RemoteMapping.class) != null, "No key present for id({})", id); + checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified"); + + final MappingId mappingId = id.firstKeyOf(RemoteMapping.class).getId(); + checkState(remoteMappingContext.containsEid(mappingId, ctx.getMappingContext()), + "No mapping stored for id %s", mappingId); + + final long vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier(); + final String remoteMappingId = id.firstKeyOf(RemoteMapping.class).getId().getValue(); + final Eid eid = copyEid(remoteMappingContext.getEid(mappingId, ctx.getMappingContext())); + final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder() + .setVni(Long.valueOf(vni).intValue()) + .setEidSet(QuantityType.SPECIFIC) + .setEidType(EidConverter.getEidType(eid)) + .setEid(EidConverter.getEidAsByteArray(eid)) + .setPrefixLength(EidConverter.getPrefixLength(eid)) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + Optional<LispEidTableDetailsReplyDump> replyOptional; + try { + replyOptional = + dumpManager.getDump(bindKey("SPECIFIC_" + remoteMappingId), ctx.getModificationCache(), dumpParams); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (replyOptional.isPresent()) { + LOG.debug("Valid dump loaded"); + + LispEidTableDetails details = replyOptional.get().lispEidTableDetails.stream() + .filter(a -> compareAddresses(eid.getAddress(), + getArrayAsEidLocal(valueOf(a.eidType), a.eid).getAddress())) + .collect( + RWUtils.singleItemCollector()); + + builder.setEid(EidConverter.getArrayAsEidRemote(valueOf(details.eidType), details.eid)); + builder.setKey(new RemoteMappingKey(new MappingId(id.firstKeyOf(RemoteMapping.class).getId()))); + builder.setTtl(resolveTtl(details.ttl)); + builder.setAuthoritative( + new RemoteMapping.Authoritative(TranslateUtils.byteToBoolean(details.authoritative))); + + } else { + LOG.debug("No data dumped"); + } + } + + //compensate ~0 as default value of ttl + private static long resolveTtl(final int ttlValue) { + return ttlValue == -1 + ? Integer.MAX_VALUE + : ttlValue; + } + + @Override + public List<RemoteMappingKey> getAllIds(InstanceIdentifier<RemoteMapping> id, ReadContext context) + throws ReadFailedException { + + checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified"); + + //requesting all remote with specific vni + final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder() + .setVni(Long.valueOf(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()).intValue()) + .setEidSet(QuantityType.ALL) + .setFilter(FilterType.REMOTE) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + Optional<LispEidTableDetailsReplyDump> replyOptional; + try { + replyOptional = dumpManager.getDump(bindKey("ALL_REMOTE"), context.getModificationCache(), dumpParams); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (replyOptional.isPresent()) { + LOG.debug("Valid dump loaded"); + return replyOptional.get() + .lispEidTableDetails + .stream() + .map(detail -> new RemoteMappingKey( + new MappingId( + remoteMappingContext.getId( + EidConverter.getArrayAsEidRemote( + valueOf(detail.eidType), detail.eid), + context.getMappingContext())))) + .collect(Collectors.toList()); + } else { + LOG.debug("No data dumped"); + return Collections.emptyList(); + } + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<RemoteMapping> readData) { + ((RemoteMappingsBuilder) builder).setRemoteMapping(readData); + } + + private String bindKey(String prefix) { + return prefix + "_" + KEY; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java new file mode 100755 index 000000000..60d6b9dc3 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/VniTableCustomizer.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2015 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.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.read.dump.check.VniTableDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.VniTableDumpExecutor; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispEidTableMapDetails; +import org.openvpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handles the reads of {@link VniTable} nodes + */ +public class VniTableCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<VniTable, VniTableKey, VniTableBuilder> { + + private static final Logger LOG = LoggerFactory.getLogger(VniTableCustomizer.class); + + private static final String LISP_TABLE_ID_DUMP = VniTableCustomizer.class.getName(); + private final DumpCacheManager<LispEidTableMapDetailsReplyDump, Void> dumpManager; + + public VniTableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableMapDetailsReplyDump, Void>() + .withExecutor(new VniTableDumpExecutor(futureJvpp)) + .withNonEmptyPredicate(new VniTableDumpCheck()) + .build(); + } + + private static VniTableKey detailsToKey(final LispEidTableMapDetails lispEidTableMapDetails) { + return new VniTableKey(Integer.valueOf(lispEidTableMapDetails.vni).longValue()); + + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<VniTable> readData) { + ((EidTableBuilder) builder).setVniTable(readData); + } + + @Nonnull + @Override + public VniTableBuilder getBuilder(@Nonnull final InstanceIdentifier<VniTable> id) { + return new VniTableBuilder(); + } + + @Nonnull + @Override + public List<VniTableKey> getAllIds(@Nonnull final InstanceIdentifier<VniTable> id, + @Nonnull final ReadContext context) + throws ReadFailedException { + LOG.trace("Reading all IDS..."); + + Optional<LispEidTableMapDetailsReplyDump> optionalReply; + try { + optionalReply = dumpManager.getDump(LISP_TABLE_ID_DUMP, context.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (!optionalReply.isPresent()) { + return Collections.emptyList(); + } + + LispEidTableMapDetailsReplyDump reply = optionalReply.get(); + LOG.debug("Dumped ..."); + + // Just transform received details into a list of keys + final List<VniTableKey> collect = reply.lispEidTableMapDetails.stream().map(VniTableCustomizer::detailsToKey) + .collect(Collectors.toList()); + LOG.debug("All IDs found: {} ...", collect); + return collect; + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VniTable> id, + @Nonnull final VniTableBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + + checkState(id.firstKeyOf(VniTable.class) != null, "No VNI present"); + VniTableKey key = new VniTableKey(id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier()); + + Optional<LispEidTableMapDetailsReplyDump> optionalReply; + try { + optionalReply = dumpManager.getDump(LISP_TABLE_ID_DUMP, ctx.getModificationCache(), NO_PARAMS); + } catch (DumpExecutionFailedException e) { + throw new ReadFailedException(id, e); + } + + if (!optionalReply.isPresent()) { + return; + } + + //transforming right away to single detail(specific request should do the magic) + LispEidTableMapDetails details = + optionalReply.get().lispEidTableMapDetails.stream().filter(a -> detailsToKey(a).equals(key)) + .collect(RWUtils.singleItemCollector()); + + builder.setVirtualNetworkIdentifier((long) details.vni); + builder.setTableId((long) details.vrf); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorDumpCheck.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorDumpCheck.java new file mode 100644 index 000000000..530be98ed --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorDumpCheck.java @@ -0,0 +1,37 @@ +/* + * 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.lisp.translate.read.dump.check; + +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.LispLocatorDetailsReplyDump; + +public class LocatorDumpCheck implements EntityDumpNonEmptyCheck<LispLocatorDetailsReplyDump> { + + @Override + public void assertNotEmpty(final LispLocatorDetailsReplyDump data) throws DumpCheckFailedException { + + if (data == null) { + throw new DumpEmptyException("Locator dump is null"); + } + + if (data.lispLocatorDetails == null) { + throw new DumpEmptyException("Locator dump is empty"); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorSetsDumpCheck.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorSetsDumpCheck.java new file mode 100755 index 000000000..eac757d50 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/LocatorSetsDumpCheck.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.honeycomb.lisp.translate.read.dump.check; + + +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; + +public class LocatorSetsDumpCheck implements EntityDumpNonEmptyCheck<LispLocatorSetDetailsReplyDump> { + + @Override + public void assertNotEmpty(final LispLocatorSetDetailsReplyDump data) throws DumpCheckFailedException { + + if (data == null) { + throw new DumpEmptyException("Locator sets dump is null"); + } + + if (data.lispLocatorSetDetails == null) { + throw new DumpEmptyException("Locator sets dump is empty"); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MapResolverDumpCheck.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MapResolverDumpCheck.java new file mode 100755 index 000000000..e018702ee --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MapResolverDumpCheck.java @@ -0,0 +1,37 @@ +/* + * 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.lisp.translate.read.dump.check; + + +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.LispMapResolverDetailsReplyDump; + +public class MapResolverDumpCheck implements EntityDumpNonEmptyCheck<LispMapResolverDetailsReplyDump> { + + @Override + public void assertNotEmpty(final LispMapResolverDetailsReplyDump data) throws DumpCheckFailedException { + if (data == null) { + throw new DumpEmptyException("Map resolvers dump is null"); + } + + if (data.lispMapResolverDetails == null) { + throw new DumpEmptyException("Map resolvers dump is empty"); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MappingsDumpCheck.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MappingsDumpCheck.java new file mode 100755 index 000000000..f34ea1b8e --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/MappingsDumpCheck.java @@ -0,0 +1,40 @@ +/* + * 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.lisp.translate.read.dump.check; + + +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.LispEidTableDetailsReplyDump; + +/** + * Common dump check for both local and remote mappings + */ +public class MappingsDumpCheck implements EntityDumpNonEmptyCheck<LispEidTableDetailsReplyDump> { + + @Override + public void assertNotEmpty(final LispEidTableDetailsReplyDump data) throws DumpCheckFailedException { + if (data == null) { + throw new DumpEmptyException("Mappings dump is null"); + } + + if (data.lispEidTableDetails == null) { + throw new DumpEmptyException("Mappings dump is empty"); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/VniTableDumpCheck.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/VniTableDumpCheck.java new file mode 100755 index 000000000..942d974e6 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/check/VniTableDumpCheck.java @@ -0,0 +1,37 @@ +/* + * 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.lisp.translate.read.dump.check; + + +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpNonEmptyCheck; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.DumpCheckFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.check.i.DumpEmptyException; +import org.openvpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; + +public class VniTableDumpCheck implements EntityDumpNonEmptyCheck<LispEidTableMapDetailsReplyDump> { + + @Override + public void assertNotEmpty(final LispEidTableMapDetailsReplyDump data) throws DumpCheckFailedException { + if (data == null) { + throw new DumpEmptyException("Vni table dump is null"); + } + + if (data.lispEidTableMapDetails == null) { + throw new DumpEmptyException("Bni table dump is empty"); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/AbstractDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/AbstractDumpExecutor.java new file mode 100644 index 000000000..fbd2003e8 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/AbstractDumpExecutor.java @@ -0,0 +1,35 @@ +/* + * 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.lisp.translate.read.dump.executor; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Nonnull; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Abstract holder for jvpp refference + */ +public abstract class AbstractDumpExecutor { + + protected final FutureJVppCore vppApi; + + protected AbstractDumpExecutor(@Nonnull final FutureJVppCore vppApi) { + this.vppApi = checkNotNull(vppApi, "VPP Api refference cannot be null"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorDumpExecutor.java new file mode 100644 index 000000000..16e6deaab --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorDumpExecutor.java @@ -0,0 +1,64 @@ +/* + * 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.lisp.translate.read.dump.executor; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.LocatorDumpParams; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpTimeoutException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispLocatorDetailsReplyDump; +import org.openvpp.jvpp.core.dto.LispLocatorDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Executor for dumping of locators + */ +public class LocatorDumpExecutor extends AbstractDumpExecutor + implements EntityDumpExecutor<LispLocatorDetailsReplyDump, LocatorDumpParams> { + + + public LocatorDumpExecutor(@Nonnull final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public LispLocatorDetailsReplyDump executeDump(final LocatorDumpParams params) throws DumpExecutionFailedException { + checkNotNull(params, "Params for dump request not present"); + + LispLocatorDump request = new LispLocatorDump(); + request.locatorSetIndex = params.getLocatorSetIndex(); + request.filter = params.getFilter(); + + try { + return TranslateUtils.getReply(vppApi.lispLocatorDump(request).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException + .wrapTimeoutException("Locator dump ended in timeout with params" + params.toString(), e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException + .wrapFailedCallException("Locator dump failed with params" + params.toString(), e); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorSetsDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorSetsDumpExecutor.java new file mode 100755 index 000000000..d074bae52 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/LocatorSetsDumpExecutor.java @@ -0,0 +1,55 @@ +/* + * 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.lisp.translate.read.dump.executor; + + +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpTimeoutException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import org.openvpp.jvpp.core.dto.LispLocatorSetDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class LocatorSetsDumpExecutor extends AbstractDumpExecutor + implements EntityDumpExecutor<LispLocatorSetDetailsReplyDump, Void> { + + public LocatorSetsDumpExecutor(@Nonnull FutureJVppCore api) { + super(api); + } + + @Override + public LispLocatorSetDetailsReplyDump executeDump(final Void params) throws DumpExecutionFailedException { + + LispLocatorSetDump request = new LispLocatorSetDump(); + request.filter = 0; + + try { + return TranslateUtils + .getReply(vppApi.lispLocatorSetDump(request).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException.wrapTimeoutException("Locator sets dump ended in timeout", e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException.wrapFailedCallException("Locator sets dump failed", e); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MapResolversDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MapResolversDumpExecutor.java new file mode 100755 index 000000000..ec1cabd54 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MapResolversDumpExecutor.java @@ -0,0 +1,51 @@ +/* + * 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.lisp.translate.read.dump.executor; + + +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpTimeoutException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispMapResolverDetailsReplyDump; +import org.openvpp.jvpp.core.dto.LispMapResolverDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class MapResolversDumpExecutor extends AbstractDumpExecutor + implements EntityDumpExecutor<LispMapResolverDetailsReplyDump, Void> { + + public MapResolversDumpExecutor(@Nonnull FutureJVppCore api) { + super(api); + } + + @Override + public LispMapResolverDetailsReplyDump executeDump(final Void params) throws DumpExecutionFailedException { + try { + return TranslateUtils.getReply(vppApi.lispMapResolverDump(new LispMapResolverDump()).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException + .wrapTimeoutException("Map resolver dump execution ended in timeout", e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException.wrapFailedCallException("Map resolver dump execution failed", e); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MappingsDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MappingsDumpExecutor.java new file mode 100755 index 000000000..d43713967 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/MappingsDumpExecutor.java @@ -0,0 +1,70 @@ +/* + * 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.lisp.translate.read.dump.executor; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpTimeoutException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import org.openvpp.jvpp.core.dto.LispEidTableDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Common dump executor for both local and remote mappings + */ +public class MappingsDumpExecutor extends AbstractDumpExecutor + implements EntityDumpExecutor<LispEidTableDetailsReplyDump, MappingsDumpParams> { + + public MappingsDumpExecutor(@Nonnull FutureJVppCore vppApi) { + super(vppApi); + } + + + @Override + public LispEidTableDetailsReplyDump executeDump(final MappingsDumpParams params) + throws DumpExecutionFailedException { + checkNotNull(params, "Params for dump request not present"); + + LispEidTableDump request = new LispEidTableDump(); + request.eid = params.getEid(); + request.eidSet = params.getEidSet(); + request.eidType = params.getEidType(); + request.prefixLength = params.getPrefixLength(); + request.vni = params.getVni(); + request.filter = params.getFilter(); + + try { + return TranslateUtils.getReply(vppApi.lispEidTableDump(request).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException + .wrapTimeoutException("Mappings dump execution timed out with params " + params.toString(), e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException + .wrapFailedCallException("Mappings dump execution failed with params " + params.toString(), e); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/VniTableDumpExecutor.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/VniTableDumpExecutor.java new file mode 100755 index 000000000..cb5f06393 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/VniTableDumpExecutor.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.honeycomb.lisp.translate.read.dump.executor; + + +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpCallFailedException; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.i.DumpTimeoutException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; +import org.openvpp.jvpp.core.dto.LispEidTableMapDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class VniTableDumpExecutor extends AbstractDumpExecutor + implements EntityDumpExecutor<LispEidTableMapDetailsReplyDump, Void> { + + public VniTableDumpExecutor(@Nonnull FutureJVppCore api) { + super(api); + } + + @Override + public LispEidTableMapDetailsReplyDump executeDump(Void params) throws DumpExecutionFailedException { + try { + return TranslateUtils.getReply(vppApi.lispEidTableMapDump(new LispEidTableMapDump()).toCompletableFuture()); + } catch (TimeoutException e) { + throw DumpTimeoutException.wrapTimeoutException("Eid table map dump ended in timeout", e); + } catch (VppBaseCallException e) { + throw DumpCallFailedException.wrapFailedCallException("Eid table map dump failed", e); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/LocatorDumpParams.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/LocatorDumpParams.java new file mode 100644 index 000000000..eda1e9771 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/LocatorDumpParams.java @@ -0,0 +1,82 @@ +/* + * 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.lisp.translate.read.dump.executor.params; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Params for dumping locators + */ +public final class LocatorDumpParams { + + private final int locatorSetIndex; + private final byte filter; + + private LocatorDumpParams(LocatorDumpParamsBuilder builder) { + this.locatorSetIndex = builder.locatorSetIndex; + this.filter = builder.filter; + } + + public int getLocatorSetIndex() { + return locatorSetIndex; + } + + public byte getFilter() { + return filter; + } + + /** + * Enum for filtering which locators to dump + */ + public enum LocatorDumpFilter { + + ALL(0), + LOCAL(1), + REMOTE(2); + + private final int value; + + private LocatorDumpFilter(int value) { + this.value = value; + } + + public final int getValue() { + return value; + } + } + + public static final class LocatorDumpParamsBuilder { + + public int locatorSetIndex; + public byte filter; + + + public LocatorDumpParamsBuilder setLocatorSetIndex(final int locatorSetIndex) { + this.locatorSetIndex = locatorSetIndex; + return this; + } + + public LocatorDumpParamsBuilder setFilter(final LocatorDumpFilter filter) { + this.filter = Integer.valueOf(checkNotNull(filter, "Cannot set null filter").getValue()).byteValue(); + return this; + } + + public LocatorDumpParams build() { + return new LocatorDumpParams(this); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/MappingsDumpParams.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/MappingsDumpParams.java new file mode 100755 index 000000000..1f7990c9b --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/dump/executor/params/MappingsDumpParams.java @@ -0,0 +1,192 @@ +/* + * 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.lisp.translate.read.dump.executor.params; + +import io.fd.honeycomb.lisp.translate.read.dump.executor.MappingsDumpExecutor; +import java.util.Arrays; + +/** + * Parameters for executing {@link MappingsDumpExecutor} + */ +public final class MappingsDumpParams { + + private final byte eidSet; + private final byte prefixLength; + private final int vni; + private final byte eidType; + private final byte[] eid; + private final byte filter; + + private MappingsDumpParams(MappingsDumpParamsBuilder builder) { + this.eidSet = builder.eidSet; + this.prefixLength = builder.prefixLength; + this.vni = builder.vni; + this.eidType = builder.eidType; + this.eid = builder.eid; + this.filter = builder.filter; + } + + + public byte getEidSet() { + return eidSet; + } + + public byte getPrefixLength() { + return prefixLength; + } + + public int getVni() { + return vni; + } + + public byte getEidType() { + return eidType; + } + + public byte[] getEid() { + return eid; + } + + public final byte getFilter() { + return filter; + } + + @Override + public String toString() { + return "MappingsDumpParams{" + + "eidSet=" + eidSet + + ", prefixLength=" + prefixLength + + ", vni=" + vni + + ", eidType=" + eidType + + ", eid=" + Arrays.toString(eid) + + ", filter=" + filter + + '}'; + } + + /** + * Type of requested mapping eid + */ + public enum EidType { + IPV4(0), + IPV6(1), + MAC(2); + + private final int value; + + private EidType(final int value) { + this.value = value; + } + + public static final EidType valueOf(int value) { + switch (value) { + case 0: + return IPV4; + case 1: + return IPV6; + case 2: + return MAC; + default: + throw new IllegalArgumentException("Illegal value"); + } + } + + public final int getValue() { + return this.value; + } + } + + /** + * Type of requested mapping + */ + public enum FilterType { + ALL(0), + LOCAL(1), + REMOTE(2); + + private final int value; + + private FilterType(final int value) { + this.value = value; + } + + public final int getValue() { + return this.value; + } + } + + public enum QuantityType { + ALL(0), + SPECIFIC(1); + + private final int value; + + private QuantityType(final int value) { + this.value = value; + } + + public final int getValue() { + return this.value; + } + } + + public static final class MappingsDumpParamsBuilder { + private byte eidSet; + private byte prefixLength; + private int vni; + private byte eidType; + private byte[] eid; + private byte filter; + + public static final MappingsDumpParamsBuilder newInstance() { + return new MappingsDumpParamsBuilder(); + } + + public MappingsDumpParamsBuilder setEidSet(final QuantityType quantityType) { + this.eidSet = (byte) quantityType.getValue(); + return this; + } + + public MappingsDumpParamsBuilder setPrefixLength(final byte prefixLength) { + this.prefixLength = prefixLength; + return this; + } + + public MappingsDumpParamsBuilder setVni(final int vni) { + this.vni = vni; + return this; + } + + public MappingsDumpParamsBuilder setEidType(final EidType eidType) { + this.eidType = (byte) eidType.getValue(); + return this; + } + + public MappingsDumpParamsBuilder setEid(final byte[] eid) { + this.eid = eid; + return this; + } + + public MappingsDumpParamsBuilder setFilter(final FilterType filterType) { + this.filter = (byte) filterType.getValue(); + return this; + } + + public MappingsDumpParams build() { + return new MappingsDumpParams(this); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java new file mode 100644 index 000000000..318b6f2f1 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2015 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.lisp.translate.read.factory; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Basic attributes for lisp reader factories + */ +abstract class AbstractLispReaderFactoryBase { + + protected final InstanceIdentifier<LispState> lispStateId; + protected final FutureJVppCore vppApi; + protected NamingContext interfaceContext; + protected NamingContext locatorSetContext; + protected EidMappingContext localMappingContext; + protected EidMappingContext remoteMappingContext; + + protected AbstractLispReaderFactoryBase(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi) { + this.lispStateId = checkNotNull(lispStateId, "Lisp state identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP api refference is null"); + } + + protected AbstractLispReaderFactoryBase(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext) { + this.lispStateId = checkNotNull(lispStateId, "Lisp state identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP api reference is null"); + this.interfaceContext = checkNotNull(interfaceContext, + "Interface naming context is null,for readers that don't need this dependency,use different constructor"); + this.localMappingContext = checkNotNull(localMappingContext, + "Local mappings reference is null,for readers that don't need this dependency use different constructor"); + this.remoteMappingContext = checkNotNull(remoteMappingContext, + "Remote mappings reference is null,for readers that don't need this dependency use different constructor"); + } + + protected AbstractLispReaderFactoryBase(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext) { + this.lispStateId = checkNotNull(lispStateId, "Lisp state identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP api reference is null"); + this.interfaceContext = checkNotNull(interfaceContext, + "Interface naming context is null,for readers that don't need this dependency,use different constructor"); + this.locatorSetContext = checkNotNull(locatorSetContext, + "Locator set naming context is null,for readers that don't need this dependency,use different constructor"); + this.localMappingContext = checkNotNull(localMappingContext, + "Local mappings reference is null,for readers that don't need this dependency use different constructor"); + this.remoteMappingContext = checkNotNull(remoteMappingContext, + "Remote mappings reference is null,for readers that don't need this dependency use different constructor"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java new file mode 100755 index 000000000..905d0faff --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/EidTableReaderFactory.java @@ -0,0 +1,112 @@ +/* + * 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.lisp.translate.read.factory; + + +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.read.AdjacencyCustomizer; +import io.fd.honeycomb.lisp.translate.read.LocalMappingCustomizer; +import io.fd.honeycomb.lisp.translate.read.RemoteMappingCustomizer; +import io.fd.honeycomb.lisp.translate.read.VniTableCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.Adjacencies; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.AdjacenciesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.LocalMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.LocalMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.RemoteMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMapping; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Factory that produces {@code Reader} for {@code EidTable}<br> with all its inhired child readers + */ +final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + private EidTableReaderFactory(final InstanceIdentifier<LispState> lispStateId, + final FutureJVppCore vppApi, + final NamingContext interfaceContext, + final NamingContext locatorSetContext, + final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext) { + super(lispStateId, vppApi,interfaceContext, locatorSetContext, localMappingContext, remoteMappingContext); + } + + public static EidTableReaderFactory newInstance(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext) { + return new EidTableReaderFactory(lispStateId, vppApi, interfaceContext, locatorSetContext, localMappingContext, + remoteMappingContext); + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + InstanceIdentifier<EidTable> eidTableInstanceIdentifier = lispStateId.child(EidTable.class); + InstanceIdentifier<VniTable> vniTableInstanceIdentifier = eidTableInstanceIdentifier.child(VniTable.class); + InstanceIdentifier<LocalMappings> localMappingsInstanceIdentifier = + vniTableInstanceIdentifier.child(LocalMappings.class); + InstanceIdentifier<RemoteMappings> remoteMappingsInstanceIdentifier = + vniTableInstanceIdentifier.child(RemoteMappings.class); + InstanceIdentifier<Adjacencies> adjacenciesInstanceIdentifier = + vniTableInstanceIdentifier.child(Adjacencies.class); + + registry.addStructuralReader(eidTableInstanceIdentifier, EidTableBuilder.class); + registry.add(new GenericListReader<>(vniTableInstanceIdentifier, new VniTableCustomizer(vppApi))); + + registry.addStructuralReader(localMappingsInstanceIdentifier, LocalMappingsBuilder.class); + + final InstanceIdentifier<LocalMapping> localMappingSubtreeId = InstanceIdentifier.create(LocalMapping.class); + registry.subtreeAdd(ImmutableSet.of(localMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid.class)), + new GenericListReader<>(localMappingsInstanceIdentifier.child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, locatorSetContext, localMappingContext))); + + registry.addStructuralReader(remoteMappingsInstanceIdentifier, RemoteMappingsBuilder.class); + + final InstanceIdentifier<RemoteMapping> remoteMappingSubtreeId = InstanceIdentifier.create(RemoteMapping.class); + registry.subtreeAdd(ImmutableSet.of(remoteMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid.class)), + new GenericListReader<>(remoteMappingsInstanceIdentifier.child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + + registry.addStructuralReader(adjacenciesInstanceIdentifier, AdjacenciesBuilder.class); + + final InstanceIdentifier<Adjacency> adjacencySubtreeId = InstanceIdentifier.create(Adjacency.class); + registry.subtreeAdd( + ImmutableSet.of(adjacencySubtreeId.child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListReader<>(adjacenciesInstanceIdentifier.child(Adjacency.class), + new AdjacencyCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java new file mode 100755 index 000000000..8444066d7 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LispStateReaderFactory.java @@ -0,0 +1,71 @@ +/* + * 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.lisp.translate.read.factory; + +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.read.LispStateCustomizer; +import io.fd.honeycomb.lisp.translate.read.PitrCfgCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Initialize readers for {@link LispState} + */ +public class LispStateReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + @Inject + public LispStateReaderFactory(final FutureJVppCore vppApi, + @Named(INTERFACE_CONTEXT) final NamingContext interfaceContext, + @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, + @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext) { + super(InstanceIdentifier.create(LispState.class), vppApi, interfaceContext, locatorSetContext, + localMappingContext, + remoteMappingContext); + } + + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + + registry.add(new GenericReader<>(lispStateId, new LispStateCustomizer(vppApi))); + + LocatorSetsReaderFactory.newInstance(lispStateId, vppApi, interfaceContext, locatorSetContext).init(registry); + MapResolversReaderFactory.newInstance(lispStateId, vppApi).init(registry); + EidTableReaderFactory + .newInstance(lispStateId, vppApi, interfaceContext, locatorSetContext, localMappingContext, + remoteMappingContext) + .init(registry); + + registry.add(new GenericReader<>(lispStateId.child(PitrCfg.class), new PitrCfgCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LocatorSetsReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LocatorSetsReaderFactory.java new file mode 100755 index 000000000..053f3d858 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/LocatorSetsReaderFactory.java @@ -0,0 +1,70 @@ +/* + * 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.lisp.translate.read.factory; + + +import io.fd.honeycomb.lisp.translate.read.InterfaceCustomizer; +import io.fd.honeycomb.lisp.translate.read.LocatorSetCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Produces reader for {@link LocatorSets} <br> and all its inhired child readers + */ +public class LocatorSetsReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + + private LocatorSetsReaderFactory(final InstanceIdentifier<LispState> lispStateId, + final FutureJVppCore vppApi, + final NamingContext interfaceContext, + final NamingContext locatorSetContext + ) { + super(lispStateId, vppApi); + this.interfaceContext=interfaceContext; + this.locatorSetContext = locatorSetContext; + } + + public static final LocatorSetsReaderFactory newInstance(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext) { + return new LocatorSetsReaderFactory(lispStateId, vppApi, interfaceContext,locatorSetContext); + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + InstanceIdentifier<LocatorSets> locatorSetsInstanceIdentifier = lispStateId.child(LocatorSets.class); + InstanceIdentifier<LocatorSet> locatorSetInstanceIdentifier = + locatorSetsInstanceIdentifier.child(LocatorSet.class); + + registry.addStructuralReader(locatorSetsInstanceIdentifier, LocatorSetsBuilder.class); + registry.add(new GenericListReader<>(locatorSetInstanceIdentifier, new LocatorSetCustomizer(vppApi))); + registry.add(new GenericListReader<>(locatorSetInstanceIdentifier.child(Interface.class), + new InterfaceCustomizer(vppApi, interfaceContext, locatorSetContext))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/MapResolversReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/MapResolversReaderFactory.java new file mode 100755 index 000000000..c26f17234 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/read/factory/MapResolversReaderFactory.java @@ -0,0 +1,56 @@ +/* + * 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.lisp.translate.read.factory; + + +import io.fd.honeycomb.lisp.translate.read.MapResolverCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.MapResolvers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.MapResolversBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Builds reader for {@link MapResolvers}<br> and all its inhired child readers + */ +public class MapResolversReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + private MapResolversReaderFactory(final InstanceIdentifier<LispState> lispStateId, final FutureJVppCore vppApi) { + super(lispStateId, vppApi); + } + + public static MapResolversReaderFactory newInstance(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi) { + return new MapResolversReaderFactory(lispStateId, vppApi); + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + + InstanceIdentifier<MapResolvers> mapResolversInstanceIdentifier = lispStateId.child(MapResolvers.class); + + registry.addStructuralReader(mapResolversInstanceIdentifier, MapResolversBuilder.class); + registry.add(new GenericListReader<>(mapResolversInstanceIdentifier.child(MapResolver.class), + new MapResolverCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidConverter.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidConverter.java new file mode 100755 index 000000000..4c8fa691b --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/util/EidConverter.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2015 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.lisp.translate.util; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.MAC; + +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import java.util.Arrays; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Mac; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.MacBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.EidBuilder; + + +/** + * Helper class that converts {@code SimpleAddress} to eid format for vpp + */ +public final class EidConverter { + + private EidConverter() { + throw new UnsupportedOperationException("Cannot instantiate utility class " + EidConverter.class.getName()); + } + + public static byte getPrefixLength( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid address) { + return resolverPrefixLength(address.getAddress()); + } + + public static byte getPrefixLength( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid address) { + return resolverPrefixLength(address.getAddress()); + } + + public static byte getPrefixLength( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid address) { + return resolverPrefixLength(address.getAddress()); + } + + private static byte resolverPrefixLength(Address address) { + + switch (resolveType(address)) { + case IPV4: + return 32; + case IPV6: + return (byte) 128; + case MAC: + return 0; + default: + throw new IllegalArgumentException("Illegal type"); + } + } + + public static Eid getArrayAsEidLocal(EidType type, byte[] address) { + + switch (type) { + case IPV4: { + return new EidBuilder().setAddress( + new Ipv4Builder().setIpv4(TranslateUtils.arrayToIpv4AddressNoZoneReversed(address)).build()) + .build(); + } + case IPV6: { + return new EidBuilder().setAddress( + new Ipv6Builder().setIpv6(TranslateUtils.arrayToIpv6AddressNoZoneReversed(address)).build()) + .build(); + } + case MAC: { + return new EidBuilder().setAddress( + new MacBuilder().setMac(new MacAddress(TranslateUtils.byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + public static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid getArrayAsEidRemote( + EidType type, byte[] address) { + + switch (type) { + case IPV4: { + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new Ipv4Builder().setIpv4(TranslateUtils.arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new Ipv6Builder().setIpv6(TranslateUtils.arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new MacBuilder().setMac(new MacAddress(TranslateUtils.byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + public static String getArrayAsEidString( + EidType type, byte[] address) { + switch (type) { + case IPV4: { + return TranslateUtils.arrayToIpv4AddressNoZoneReversed(address).getValue(); + } + case IPV6: { + return TranslateUtils.arrayToIpv6AddressNoZoneReversed(address).getValue(); + } + case MAC: { + //as wrong as it looks ,its right(second param is not end index,but count) + return TranslateUtils.byteArrayToMacSeparated(Arrays.copyOfRange(address, 0, 6)); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + + public static EidType getEidType( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid address) { + checkNotNull(address, "SimpleAddress cannot be null"); + + return resolveType(address.getAddress()); + } + + public static EidType getEidType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid address) { + checkNotNull(address, "SimpleAddress cannot be null"); + + return resolveType(address.getAddress()); + } + + + public static EidType getEidType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + + public static EidType getEidType(final LocalEid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + public static EidType getEidType(final RemoteEid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + private static EidType resolveType( + Address address) { + + if (address instanceof Ipv4) { + return IPV4; + } else if (address instanceof Ipv6) { + return IPV6; + } else if (address instanceof Mac) { + return MAC; + } else { + //TODO - other types + throw new IllegalStateException("Unknown type detected"); + } + } + + public static byte[] getEidAsByteArray( + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + public static byte[] getEidAsByteArray( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + public static byte[] getEidAsByteArray( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + public static byte[] getEidAsByteArray(final LocalEid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + + public static byte[] getEidAsByteArray(final RemoteEid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + private static byte[] resolveByteArray(EidType type, Address address) { + switch (type) { + case IPV4: + return TranslateUtils + .ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(((Ipv4) address).getIpv4())); + case IPV6: + return TranslateUtils + .ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(((Ipv6) address).getIpv6())); + case MAC: + return TranslateUtils.parseMac(((Mac) address).getMac().getValue()); + default: + //TODO - other types + throw new IllegalArgumentException("Unsupported type"); + } + } + + public static boolean compareEids( + LispAddress first, + LispAddress second) { + + return compareAddresses(checkNotNull(first, "First eid is null").getAddress(), + checkNotNull(second, "Second eid is null").getAddress()); + } + + public static boolean compareAddresses(Address firstAddress, Address secondAddress) { + + checkNotNull(firstAddress, "First address is null"); + checkNotNull(secondAddress, "Second address is null"); + + if (firstAddress instanceof Ipv4 && secondAddress instanceof Ipv4) { + return ((Ipv4) firstAddress).getIpv4().getValue().equals(((Ipv4) secondAddress).getIpv4().getValue()); + } + + if (firstAddress instanceof Ipv6 && secondAddress instanceof Ipv6) { + return ((Ipv6) firstAddress).getIpv6().getValue().equals(((Ipv6) secondAddress).getIpv6().getValue()); + } + + if (firstAddress instanceof Mac && secondAddress instanceof Mac) { + return ((Mac) firstAddress).getMac().getValue().equals(((Mac) secondAddress).getMac().getValue()); + } + + throw new IllegalArgumentException("Unsupported eid type " + firstAddress.getClass()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java new file mode 100755 index 000000000..d321510be --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/AdjacencyCustomizer.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType; + +import io.fd.honeycomb.lisp.translate.util.EidConverter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.AdjacencyKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelAdjacency; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class AdjacencyCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Adjacency, AdjacencyKey> { + + public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final Adjacency dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + try { + addDelAdjacency(true, id, dataAfter); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final Adjacency dataBefore, @Nonnull final Adjacency dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final Adjacency dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + try { + addDelAdjacency(false, id, dataBefore); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + } + + private void addDelAdjacency(boolean add, final InstanceIdentifier<Adjacency> id, Adjacency data) + throws TimeoutException, VppBaseCallException { + + checkState(id.firstKeyOf(VniTable.class) != null, "Unable to find parent VNI for {}", id); + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + EidType localEidType = EidConverter.getEidType(data.getLocalEid()); + EidType remoteEidType = EidConverter.getEidType(data.getRemoteEid()); + + checkArgument(localEidType == + remoteEidType, "Local[%s] and Remote[%s] eid types must be the same", localEidType, remoteEidType); + + LispAddDelAdjacency request = new LispAddDelAdjacency(); + + request.isAdd = TranslateUtils.booleanToByte(add); + request.seid = EidConverter.getEidAsByteArray(data.getLocalEid()); + request.seidLen = (byte) request.seid.length; + request.deid = EidConverter.getEidAsByteArray(data.getRemoteEid()); + request.seidLen = (byte) request.deid.length; + request.eidType = (byte) localEidType.getValue(); + request.vni = vni; + + TranslateUtils.getReply(getFutureJVpp().lispAddDelAdjacency(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizer.java new file mode 100755 index 000000000..c26bbf377 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizer.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelLocator; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for updating {@link Interface} + * + * @see Interface + */ +public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> { + + private final NamingContext interfaceContext; + + public InterfaceCustomizer(@Nonnull FutureJVppCore futureJvpp, @Nonnull NamingContext interfaceContext) { + super(futureJvpp); + this.interfaceContext = checkNotNull(interfaceContext, "Naming context is null"); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<Interface> id, Interface dataAfter, WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataAfter, "Interface is null"); + checkNotNull(dataAfter.getPriority(), "Priority is null"); + checkNotNull(dataAfter.getWeight(), "Weight is null"); + checkState(id.firstKeyOf(Interface.class) != null, "Parent interface not found"); + checkState(id.firstKeyOf(LocatorSet.class) != null, "Parent locator set not found"); + + String interfaceName = id.firstKeyOf(Interface.class).getInterfaceRef(); + String locatorSetName = id.firstKeyOf(LocatorSet.class).getName(); + + checkState(interfaceContext.containsIndex(interfaceName, writeContext.getMappingContext()), + "No mapping stored for interface %s", interfaceName); + + try { + addDelInterfaceAndReply(true, dataAfter, + interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()), locatorSetName); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<Interface> id, Interface dataBefore, Interface dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<Interface> id, Interface dataBefore, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataBefore, "Interface is null"); + checkNotNull(dataBefore.getPriority(), "Priority is null"); + checkNotNull(dataBefore.getWeight(), "Weight is null"); + checkState(id.firstKeyOf(Interface.class) != null, "Parent interface not found"); + checkState(id.firstKeyOf(LocatorSet.class) != null, "Parent locator set not found"); + + String interfaceName = id.firstKeyOf(Interface.class).getInterfaceRef(); + String locatorSetName = id.firstKeyOf(LocatorSet.class).getName(); + + checkState(interfaceContext.containsIndex(interfaceName, writeContext.getMappingContext()), + "No mapping stored for interface %s", interfaceName); + try { + addDelInterfaceAndReply(false, dataBefore, + interfaceContext.getIndex(interfaceName, writeContext.getMappingContext()), locatorSetName); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private void addDelInterfaceAndReply(boolean add, Interface data, int interfaceIndex, String locatorSetName) + throws VppBaseCallException, TimeoutException, UnsupportedEncodingException { + LispAddDelLocator request = new LispAddDelLocator(); + + request.isAdd = TranslateUtils.booleanToByte(add); + request.priority = data.getPriority().byteValue(); + request.weight = data.getWeight().byteValue(); + request.swIfIndex = interfaceIndex; + request.locatorSetName = locatorSetName.getBytes(UTF_8); + + TranslateUtils.getReply(getFutureJVpp().lispAddDelLocator(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LispCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LispCustomizer.java new file mode 100755 index 000000000..05c162d0c --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LispCustomizer.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispEnableDisable; +import org.openvpp.jvpp.core.dto.LispEnableDisableReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Handles updates of {@link Lisp} node. Takes care of LISP enable/disable + */ +public class LispCustomizer extends FutureJVppCustomizer implements WriterCustomizer<Lisp> { + + public LispCustomizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Lisp> id, @Nonnull final Lisp dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + Preconditions.checkNotNull(dataAfter, "Lisp is null"); + + try { + enableDisableLisp(dataAfter.isEnable()); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Lisp> id, @Nonnull final Lisp dataBefore, + @Nonnull final Lisp dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + Preconditions.checkNotNull(dataAfter, "Lisp is null"); + + try { + enableDisableLisp(dataAfter.isEnable()); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Lisp> id, @Nonnull final Lisp dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + Preconditions.checkNotNull(dataBefore, "Lisp is null"); + + try { + enableDisableLisp(false); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + } + + + private void enableDisableLisp(final boolean enable) throws VppBaseCallException, TimeoutException { + final CompletionStage<LispEnableDisableReply> lispEnableDisableReplyCompletionStage = + getFutureJVpp().lispEnableDisable(getRequest(enable)); + TranslateUtils.getReply(lispEnableDisableReplyCompletionStage.toCompletableFuture()); + } + + private LispEnableDisable getRequest(final boolean enable) { + final LispEnableDisable lispEnableDisable = new LispEnableDisable(); + lispEnableDisable.isEn = TranslateUtils.booleanToByte(enable); + return lispEnableDisable; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizer.java new file mode 100755 index 000000000..eec4b8269 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizer.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.util.EidConverter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMappingKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelLocalEid; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer that writes changes for {@link LocalMapping} + */ +public class LocalMappingCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<LocalMapping, LocalMappingKey> { + + private final EidMappingContext localMappingsContext; + + public LocalMappingCustomizer(@Nonnull FutureJVppCore futureJvpp, @Nonnull EidMappingContext localMappingsContext) { + super(futureJvpp); + this.localMappingsContext = checkNotNull(localMappingsContext, "No local mappings context defined"); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<LocalMapping> id, LocalMapping dataAfter, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataAfter, "Mapping is null"); + checkNotNull(dataAfter.getEid(), "Eid is null"); + checkNotNull(dataAfter.getLocatorSet(), "Locator set is null"); + checkState(id.firstKeyOf(VniTable.class) != null, "Parent vni table not found"); + + //checks whether value with specified mapping-id does not exist in mapping allready + MappingId mappingId = id.firstKeyOf(LocalMapping.class).getId(); + checkState(!localMappingsContext + .containsEid(mappingId, writeContext.getMappingContext()), + "Local mapping with id %s already defined", id); + + + try { + addDelMappingAndReply(true, dataAfter, + id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue()); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + //adds mapping for id and eid + localMappingsContext.addEid(mappingId, dataAfter.getEid(), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<LocalMapping> id, LocalMapping dataBefore, + LocalMapping dataAfter, WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<LocalMapping> id, LocalMapping dataBefore, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataBefore, "Mapping is null"); + checkNotNull(dataBefore.getEid(), "Eid is null"); + checkNotNull(dataBefore.getLocatorSet(), "LocatorSet is null"); + checkState(id.firstKeyOf(VniTable.class) != null, "Parent vni table not found"); + + //checks whether value with specified mapping-id does exist in mapping,so there is something to delete + MappingId mappingId = id.firstKeyOf(LocalMapping.class).getId(); + checkState(localMappingsContext + .containsEid(mappingId, writeContext.getMappingContext()), + "Local mapping with id %s not present in mapping", id); + + try { + addDelMappingAndReply(false, dataBefore, + id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue()); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + //removes value also from mapping + localMappingsContext.removeEid(mappingId, writeContext.getMappingContext()); + } + + private void addDelMappingAndReply(boolean add, LocalMapping data, int vni) throws VppBaseCallException, + TimeoutException, UnsupportedEncodingException { + + LispAddDelLocalEid request = new LispAddDelLocalEid(); + + request.isAdd = TranslateUtils.booleanToByte(add); + request.eid = EidConverter.getEidAsByteArray(data.getEid()); + request.eidType = (byte) EidConverter.getEidType(data.getEid()).getValue(); + request.locatorSetName = data.getLocatorSet().getBytes(UTF_8); + request.vni = vni; + + //default prefixes + if (request.eidType == IPV4.getValue()) { + request.prefixLen = 32; + } else if (request.eidType == IPV6.getValue()) { + request.prefixLen = (byte) 128; + } + + TranslateUtils.getReply(getFutureJVpp().lispAddDelLocalEid(request).toCompletableFuture()); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java new file mode 100755 index 000000000..c2db3b845 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizer.java @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.translate.v3po.util.TranslateUtils.getReply; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.base.Optional; +import io.fd.honeycomb.lisp.translate.read.dump.check.LocatorSetsDumpCheck; +import io.fd.honeycomb.lisp.translate.read.dump.executor.LocatorSetsDumpExecutor; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.v3po.util.cache.DumpCacheManager; +import io.fd.honeycomb.translate.v3po.util.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.v3po.util.cache.exceptions.execution.DumpExecutionFailedException; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.io.UnsupportedEncodingException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelLocatorSet; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for {@link LocatorSet} entity + * + * @see LocatorSet + */ +public class LocatorSetCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<LocatorSet, LocatorSetKey> { + + private final NamingContext locatorSetContext; + private final DumpCacheManager<LispLocatorSetDetailsReplyDump, Void> dumpManager; + + public LocatorSetCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext locatorSetContext) { + super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator set context cannot be null"); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorSetDetailsReplyDump, Void>() + .withExecutor(new LocatorSetsDumpExecutor(futureJvpp)) + .withNonEmptyPredicate(new LocatorSetsDumpCheck()) + .build(); + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + + checkNotNull(dataAfter, "LocatorSet is null"); + + final String locatorSetName = dataAfter.getName(); + checkNotNull(locatorSetName, "LocatorSet name is null"); + + //TODO check and fill mapping when api returns index of created locator set + // checkState(!locatorSetContext.containsIndex(locatorSetName, writeContext.getMappingContext()), + // "Locator set with name %s allready defined", locatorSetName); + + try { + addDelLocatorSetAndReply(true, dataAfter.getName()); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + //TODO - REMOVE FROM MASTER AFTER VPP-323 + try { + locatorSetContext + .addName(getLocatorSetIndex(locatorSetName, writeContext.getModificationCache()), locatorSetName, + writeContext.getMappingContext()); + } catch (DumpExecutionFailedException e) { + throw new WriteFailedException(id, + new IllegalStateException("Unable to create mapping for locator set " + locatorSetName, e)); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataBefore, + @Nonnull LocatorSet dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataBefore, + @Nonnull WriteContext writeContext) throws WriteFailedException { + + checkNotNull(dataBefore, "LocatorSet is null"); + + final String locatorSetName = dataBefore.getName(); + checkNotNull(locatorSetName, "LocatorSet name is null"); + + try { + addDelLocatorSetAndReply(false, dataBefore.getName()); + } catch (VppBaseCallException | TimeoutException | UnsupportedEncodingException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + //removes mapping after successful delete + locatorSetContext.removeName(locatorSetName, writeContext.getMappingContext()); + } + + private void addDelLocatorSetAndReply(boolean add, String name) + throws VppBaseCallException, TimeoutException, UnsupportedEncodingException { + + LispAddDelLocatorSet addDelSet = new LispAddDelLocatorSet(); + + addDelSet.isAdd = TranslateUtils.booleanToByte(add); + addDelSet.locatorSetName = name.getBytes(UTF_8); + + + getReply(getFutureJVpp().lispAddDelLocatorSet(addDelSet).toCompletableFuture()); + } + + //TODO - REMOVE FROM MASTER AFTER VPP-323 + // total hack + public int getLocatorSetIndex(final String name, final ModificationCache cache) + throws DumpExecutionFailedException { + + Optional<LispLocatorSetDetailsReplyDump> reply = dumpManager + .getDump(io.fd.honeycomb.lisp.translate.read.LocatorSetCustomizer.LOCATOR_SETS_CACHE_ID, cache, + EntityDumpExecutor.NO_PARAMS); + + if (reply.isPresent()) { + return reply.get().lispLocatorSetDetails.stream() + .filter(a -> name.equals(TranslateUtils.toString(a.locatorSetName))) + .collect(RWUtils.singleItemCollector()) + .locatorSetIndex; + } else { + throw new IllegalStateException("Unable to find index of locator set " + name); + } + } + + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizer.java new file mode 100755 index 000000000..02c9f4255 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizer.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolverKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelMapResolver; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Handles updates of {@link MapResolver} list + */ +public class MapResolverCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<MapResolver, MapResolverKey> { + + public MapResolverCustomizer(final FutureJVppCore vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<MapResolver> id, + @Nonnull final MapResolver dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataAfter, "Data is null"); + checkNotNull(dataAfter.getIpAddress(), "Address is null"); + + try { + addDelMapResolverAndReply(true, dataAfter); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<MapResolver> id, + @Nonnull final MapResolver dataBefore, @Nonnull final MapResolver dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<MapResolver> id, + @Nonnull final MapResolver dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataBefore, "Data is null"); + checkNotNull(dataBefore.getIpAddress(), "Address is null"); + + try { + addDelMapResolverAndReply(false, dataBefore); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + } + + private void addDelMapResolverAndReply(boolean add, MapResolver data) throws VppBaseCallException, + TimeoutException { + + LispAddDelMapResolver request = new LispAddDelMapResolver(); + request.isAdd = TranslateUtils.booleanToByte(add); + + + boolean ipv6 = TranslateUtils.isIpv6(data.getIpAddress()); + + request.isIpv6 = TranslateUtils.booleanToByte(ipv6); + request.ipAddress = TranslateUtils.ipAddressToArray(ipv6, data.getIpAddress()); + + TranslateUtils.getReply(getFutureJVpp().lispAddDelMapResolver(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizer.java new file mode 100755 index 000000000..ab3be2add --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizer.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.TimeoutException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispPitrSetLocatorSet; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for {@code PitrCfg} + */ +public class PitrCfgCustomizer extends FutureJVppCustomizer implements WriterCustomizer<PitrCfg> { + + public PitrCfgCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<PitrCfg> id, PitrCfg dataAfter, WriteContext writeContext) + throws WriteFailedException { + checkNotNull(dataAfter, "PitrCfg is null"); + checkNotNull(dataAfter.getLocatorSet(), "Locator set name is null"); + + try { + addDelPitrSetLocatorSetAndReply(true, dataAfter); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<PitrCfg> id, PitrCfg dataBefore, PitrCfg dataAfter, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataAfter, "PitrCfg is null"); + checkNotNull(dataAfter.getLocatorSet(), "Locator set name is null"); + + try { + addDelPitrSetLocatorSetAndReply(true, dataAfter); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<PitrCfg> id, PitrCfg dataBefore, WriteContext writeContext) + throws WriteFailedException { + checkNotNull(dataBefore, "PitrCfg is null"); + checkNotNull(dataBefore.getLocatorSet(), "Locator set name is null"); + + try { + addDelPitrSetLocatorSetAndReply(false, dataBefore); + } catch (VppBaseCallException | TimeoutException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + } + + private void addDelPitrSetLocatorSetAndReply(boolean add, PitrCfg data) + throws VppBaseCallException, TimeoutException { + + LispPitrSetLocatorSet request = new LispPitrSetLocatorSet(); + request.isAdd = TranslateUtils.booleanToByte(add); + request.lsName = data.getLocatorSet().getBytes(UTF_8); + + TranslateUtils.getReply(getFutureJVpp().lispPitrSetLocatorSet(request).toCompletableFuture()); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizer.java new file mode 100755 index 000000000..e8e37969e --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizer.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + + +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 static io.fd.honeycomb.lisp.translate.write.RemoteMappingCustomizer.LocatorListType.NEGATIVE; +import static io.fd.honeycomb.lisp.translate.write.RemoteMappingCustomizer.LocatorListType.POSITIVE; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.util.EidConverter; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeoutException; +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.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MapReplyAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.LocatorList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.NegativeMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.PositiveMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.Rlocs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.dto.LispAddDelRemoteMapping; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for {@link RemoteMapping} + */ +public class RemoteMappingCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<RemoteMapping, RemoteMappingKey> { + + private final EidMappingContext remoteMappingContext; + + public RemoteMappingCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final EidMappingContext remoteMappingContext) { + super(futureJvpp); + this.remoteMappingContext = remoteMappingContext; + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<RemoteMapping> id, RemoteMapping dataAfter, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataAfter, "Mapping is null"); + checkNotNull(dataAfter.getEid(), "Eid is null"); + checkState(id.firstKeyOf(VniTable.class) != null, "Parent vni table not found"); + + //checks whether mapping not already contains such key + MappingId mappingId = id.firstKeyOf(RemoteMapping.class).getId(); + checkState(!remoteMappingContext.containsEid(mappingId, writeContext.getMappingContext()), + "Mapping for id %s already defined", mappingId); + + try { + addDelRemoteMappingAndReply(true, dataAfter, + id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue()); + } catch (VppBaseCallException | TimeoutException | IOException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + //after successfull adition adds mapping + remoteMappingContext.addEid(mappingId, dataAfter.getEid(), writeContext.getMappingContext()); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<RemoteMapping> id, RemoteMapping dataBefore, + RemoteMapping dataAfter, WriteContext writeContext) + throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<RemoteMapping> id, RemoteMapping dataBefore, + WriteContext writeContext) throws WriteFailedException { + checkNotNull(dataBefore, "Mapping is null"); + checkNotNull(dataBefore.getEid(), "Eid is null"); + + //checks whether mapping already contains such key + MappingId mappingId = id.firstKeyOf(RemoteMapping.class).getId(); + checkState(remoteMappingContext.containsEid(mappingId, writeContext.getMappingContext()), + "Mapping for id %s is not existing,nothing to remove", mappingId); + + try { + addDelRemoteMappingAndReply(false, dataBefore, + id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue()); + } catch (VppBaseCallException | TimeoutException | IOException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + + //remote mapping after successfull remove of data + remoteMappingContext.removeEid(mappingId, writeContext.getMappingContext()); + } + + private void addDelRemoteMappingAndReply(boolean add, RemoteMapping data, int vni) + throws VppBaseCallException, TimeoutException, IOException { + + LispAddDelRemoteMapping request = new LispAddDelRemoteMapping(); + + request.isAdd = TranslateUtils.booleanToByte(add); + request.vni = vni; + request.eidType = (byte) EidConverter.getEidType(data.getEid()).getValue(); + request.eid = EidConverter.getEidAsByteArray(data.getEid()); + + //this is not length of eid array,but prefix length(bad naming by vpp) + request.eidLen = EidConverter.getPrefixLength(data.getEid()); + + if (LocatorListType.NEGATIVE + .equals(resolveType(data.getLocatorList()))) { + request.action = (byte) extractAction(data.getLocatorList()).getIntValue(); + } else { + Rlocs rlocs = extractRemoteLocators(data.getLocatorList()); + + checkArgument(rlocs != null, "No remote locators set for Positive mapping"); + + request.rlocs = locatorsToBinaryData(rlocs.getLocator()); + request.rlocNum = Integer.valueOf(rlocs.getLocator().size()).byteValue(); + } + + TranslateUtils.getReply(getFutureJVpp().lispAddDelRemoteMapping(request).toCompletableFuture()); + } + + private static LocatorListType resolveType(LocatorList locatorList) { + checkNotNull(locatorList, "Locator List cannot be null"); + + if (locatorList instanceof PositiveMapping) { + return POSITIVE; + } else { + return NEGATIVE; + } + } + + private static MapReplyAction extractAction(LocatorList locatorList) { + checkNotNull(locatorList, "Locator List cannot be null"); + Preconditions.checkArgument(NEGATIVE.equals(resolveType(locatorList)), + "Action can be extracted only from Negative Mapping"); + + return ((NegativeMapping) locatorList).getMapReplyAction(); + } + + private static Rlocs extractRemoteLocators(LocatorList locatorList) { + checkNotNull(locatorList, "Locator List cannot be null"); + Preconditions.checkArgument(POSITIVE.equals(resolveType(locatorList)), + "RLocs can be extracted only from Positive Mapping"); + + return ((PositiveMapping) locatorList).getRlocs(); + } + + private static byte[] locatorsToBinaryData(List<Locator> locators) throws IOException { + checkNotNull(locators, "Cannot convert null list"); + + ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); + + DataOutputStream out = new DataOutputStream(byteArrayOut); + + + for (Locator locator : locators) { + boolean isIpv4; + byte[] address; + + //first byte says that its v4/v6 + isIpv4 = !TranslateUtils.isIpv6(locator.getAddress()); + out.writeByte(TranslateUtils.booleanToByte(isIpv4)); + + //then writes priority + out.write(locator.getPriority()); + + //and weight + out.write(locator.getWeight()); + + if (isIpv4) { + //vpp in this case needs address as 16 byte array,regardless if it is ivp4 or ipv6 + address = Arrays.copyOf( + TranslateUtils + .ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(locator.getAddress().getIpv4Address())), + 16); + + out.write(address); + } else { + out.write(TranslateUtils + .ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(locator.getAddress().getIpv6Address()))); + } + } + + return byteArrayOut.toByteArray(); + } + + public enum LocatorListType { + + /** + * Represents locator list as negative mapping + */ + NEGATIVE, + + /** + * Represents locator list as positive mapping + */ + POSITIVE + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/VniTableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/VniTableCustomizer.java new file mode 100755 index 000000000..ad1d41de9 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/VniTableCustomizer.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.v3po.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.TimeoutException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.VppBaseCallException; +import org.openvpp.jvpp.core.future.FutureJVppCore; +import org.openvpp.jvpp.core.dto.LispEidTableAddDelMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer for {@code TableId} + */ +public class VniTableCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<VniTable, VniTableKey> { + + private static final Logger LOG = LoggerFactory.getLogger(VniTableCustomizer.class); + + public VniTableCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public void writeCurrentAttributes(InstanceIdentifier<VniTable> id, VniTable dataAfter, WriteContext writeContext) + throws WriteFailedException { + + checkNotNull(dataAfter.getTableId(), "VRF cannot be null"); + checkNotNull(dataAfter.getVirtualNetworkIdentifier(), "VNI cannot be null"); + + LOG.debug("Writing {}", id); + + try { + addDelMap(true, dataAfter.getVirtualNetworkIdentifier().intValue(), dataAfter.getTableId().intValue()); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + LOG.debug("Write of {} successful", id); + } + + @Override + public void updateCurrentAttributes(InstanceIdentifier<VniTable> id, VniTable dataBefore, VniTable dataAfter, + WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(InstanceIdentifier<VniTable> id, VniTable dataBefore, WriteContext writeContext) + throws WriteFailedException { + checkNotNull(dataBefore.getTableId(), "VRF cannot be null"); + checkNotNull(dataBefore.getVirtualNetworkIdentifier(), "VNI cannot be null"); + + LOG.debug("Removing {}", id); + + try { + addDelMap(false, dataBefore.getVirtualNetworkIdentifier().intValue(), dataBefore.getTableId().intValue()); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + + LOG.debug("Remove of {} successful", id); + } + + private void addDelMap(boolean isAdd, int vni, int vrf) throws TimeoutException, VppBaseCallException { + + LispEidTableAddDelMap request = new LispEidTableAddDelMap(); + + request.isAdd = TranslateUtils.booleanToByte(isAdd); + request.vni = vni; + request.dpTable = vrf; + request.isL2 = 0; + + TranslateUtils.getReply(getFutureJVpp().lispEidTableAddDelMap(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java new file mode 100644 index 000000000..fed1cf64d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write.factory; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Basic attributes for lisp writer factories + */ +abstract class AbstractLispWriterFactoryBase { + + protected final InstanceIdentifier<Lisp> lispInstanceIdentifier; + protected final FutureJVppCore vppApi; + protected NamingContext interfaceContext; + protected NamingContext locatorSetContext; + protected EidMappingContext localMappingContext; + protected EidMappingContext remoteMappingContext; + + protected AbstractLispWriterFactoryBase(@Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + NamingContext interfaceContext) { + this.lispInstanceIdentifier = checkNotNull(lispInstanceIdentifier, "Lisp identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP Api refference is null"); + this.interfaceContext = interfaceContext; + } + + protected AbstractLispWriterFactoryBase(@Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + NamingContext interfaceContext, + NamingContext locatorSetContext) { + this.lispInstanceIdentifier = checkNotNull(lispInstanceIdentifier, "Lisp identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP Api refference is null"); + this.interfaceContext = interfaceContext; + this.locatorSetContext = locatorSetContext; + } + + protected AbstractLispWriterFactoryBase(@Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + EidMappingContext localMappingContext, + EidMappingContext remoteMappingContext) { + this.lispInstanceIdentifier = checkNotNull(lispInstanceIdentifier, "Lisp identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP Api refference is null"); + this.localMappingContext = localMappingContext; + this.remoteMappingContext = remoteMappingContext; + } + + protected AbstractLispWriterFactoryBase(@Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + NamingContext interfaceContext, + NamingContext locatorSetContext, + EidMappingContext localMappingContext, + EidMappingContext remoteMappingContext) { + this.lispInstanceIdentifier = checkNotNull(lispInstanceIdentifier, "Lisp identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP Api refference is null"); + this.interfaceContext = interfaceContext; + this.locatorSetContext = locatorSetContext; + this.localMappingContext = localMappingContext; + this.remoteMappingContext = remoteMappingContext; + } + + protected AbstractLispWriterFactoryBase(@Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + NamingContext interfaceContext, + EidMappingContext localMappingContext, + EidMappingContext remoteMappingContext) { + this.lispInstanceIdentifier = checkNotNull(lispInstanceIdentifier, "Lisp identifier is null"); + this.vppApi = checkNotNull(vppApi, "VPP Api refference is null"); + this.interfaceContext = interfaceContext; + this.localMappingContext = localMappingContext; + this.remoteMappingContext = remoteMappingContext; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java new file mode 100755 index 000000000..ec95afc5e --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LispWriterFactory.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write.factory; + + +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.honeycomb.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.write.LispCustomizer; +import io.fd.honeycomb.lisp.translate.write.PitrCfgCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Initialize writers for {@link Lisp} + */ +public final class LispWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + @Inject + public LispWriterFactory(final FutureJVppCore vppApi, + @Named(INTERFACE_CONTEXT) final NamingContext interfaceContext, + @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, + @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext) { + super(InstanceIdentifier.create(Lisp.class), vppApi, interfaceContext, locatorSetContext, localMappingContext, + remoteMappingContext); + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + registry.add(new GenericWriter<>(lispInstanceIdentifier, new LispCustomizer(vppApi))); + + VniTableWriterFactory.newInstance(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext) + .init(registry); + LocatorSetsWriterFactory.newInstance(lispInstanceIdentifier, vppApi, interfaceContext, locatorSetContext) + .init(registry); + MapResolversWriterFactory.newInstance(lispInstanceIdentifier, vppApi).init(registry); + + registry.add(new GenericWriter<>(lispInstanceIdentifier.child(PitrCfg.class), new PitrCfgCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LocatorSetsWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LocatorSetsWriterFactory.java new file mode 100755 index 000000000..2139eaf26 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/LocatorSetsWriterFactory.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write.factory; + +import io.fd.honeycomb.lisp.translate.write.InterfaceCustomizer; +import io.fd.honeycomb.lisp.translate.write.LocatorSetCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Factory producing writers for {@code LocatorSets} + */ +final class LocatorSetsWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + private LocatorSetsWriterFactory(final InstanceIdentifier<Lisp> lispInstanceIdentifier, + final FutureJVppCore vppApi, + final NamingContext interfaceContext, + final NamingContext locatorSetContext) { + super(lispInstanceIdentifier, vppApi, interfaceContext, locatorSetContext); + } + + public static LocatorSetsWriterFactory newInstance( + @Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext) { + return new LocatorSetsWriterFactory(lispInstanceIdentifier, vppApi, interfaceContext, locatorSetContext); + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + InstanceIdentifier<LocatorSet> locatorSetId = + lispInstanceIdentifier.child(LocatorSets.class).child(LocatorSet.class); + + registry.add(new GenericListWriter<>(locatorSetId, new LocatorSetCustomizer(vppApi, locatorSetContext))); + registry.add(new GenericListWriter<>(locatorSetId.child(Interface.class), + new InterfaceCustomizer(vppApi, interfaceContext))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/MapResolversWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/MapResolversWriterFactory.java new file mode 100755 index 000000000..00fa959d5 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/MapResolversWriterFactory.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write.factory; + + +import io.fd.honeycomb.lisp.translate.write.MapResolverCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.MapResolvers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Factory responsible for producing writers for {@code MapResolvers} + */ +final class MapResolversWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + private MapResolversWriterFactory(final InstanceIdentifier<Lisp> lispInstanceIdentifier, + final FutureJVppCore vppApi) { + super(lispInstanceIdentifier, vppApi, null); + } + + public static MapResolversWriterFactory newInstance( + @Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi) { + return new MapResolversWriterFactory(lispInstanceIdentifier, vppApi); + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + registry.add(new GenericListWriter<>(lispInstanceIdentifier.child(MapResolvers.class).child(MapResolver.class), + new MapResolverCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java new file mode 100755 index 000000000..4a78fb819 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/honeycomb/lisp/translate/write/factory/VniTableWriterFactory.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write.factory; + +import com.google.common.collect.ImmutableSet; +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.lisp.translate.write.AdjacencyCustomizer; +import io.fd.honeycomb.lisp.translate.write.LocalMappingCustomizer; +import io.fd.honeycomb.lisp.translate.write.RemoteMappingCustomizer; +import io.fd.honeycomb.lisp.translate.write.VniTableCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.Adjacencies; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.LocalMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.Rlocs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +/** + * Factory for producing writers for {@code EidTable} + */ +final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + private VniTableWriterFactory(final InstanceIdentifier<Lisp> lispInstanceIdentifier, + final FutureJVppCore vppApi, + final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext) { + super(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext); + } + + public static VniTableWriterFactory newInstance( + @Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext) { + return new VniTableWriterFactory(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext); + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + final InstanceIdentifier<VniTable> vniTableId = + lispInstanceIdentifier.child(EidTable.class).child(VniTable.class); + + registry.add(new GenericListWriter<>(vniTableId, new VniTableCustomizer(vppApi))); + + + final InstanceIdentifier<LocalMapping> localMappingSubtreeId = InstanceIdentifier.create(LocalMapping.class); + registry.subtreeAdd(ImmutableSet.of(localMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid.class)), + new GenericListWriter<>(vniTableId.child(LocalMappings.class).child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, localMappingContext))); + + final InstanceIdentifier<RemoteMapping> remoteMappingSubtreeId = InstanceIdentifier.create(RemoteMapping.class); + registry.subtreeAdd(ImmutableSet.of(remoteMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid.class), + remoteMappingSubtreeId.child(Rlocs.class), + remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class)), + new GenericListWriter<>(vniTableId.child(RemoteMappings.class).child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + + final InstanceIdentifier<Adjacency> adjacencySubtreeId = InstanceIdentifier.create(Adjacency.class); + registry.subtreeAdd(ImmutableSet.of(adjacencySubtreeId + .child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListWriter<>(vniTableId.child(Adjacencies.class).child(Adjacency.class), + new AdjacencyCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/resources/honeycomb-minimal-resources/config/lisp.json b/lisp/lisp2vpp/src/main/resources/honeycomb-minimal-resources/config/lisp.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/lisp/lisp2vpp/src/main/resources/honeycomb-minimal-resources/config/lisp.json @@ -0,0 +1,2 @@ +{ +}
\ No newline at end of file diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.java new file mode 100644 index 000000000..710477a70 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/context/util/EidMappingContextTest.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.honeycomb.lisp.context.util; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.MappingBuilder; +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.lisp.address.types.rev151105.lisp.address.address.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.EidBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EidMappingContextTest { + + private EidMappingContext eidMappingContext; + + @Mock + private MappingContext mappingContext; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + eidMappingContext = new EidMappingContext("eid-eidMappingContext"); + } + + @Test + public void testStoreAndGet() { + Eid eid = + new EidBuilder().setAddress(new Ipv4Builder().setIpv4(new Ipv4Address("192.168.2.1")).build()).build(); + MappingId id = new MappingId("first"); + + eidMappingContext.addEid(id, eid, mappingContext); + when(mappingContext.read(Mockito.any(InstanceIdentifier.class))) + .thenReturn(Optional.of( + new MappingBuilder().setId(id).setEid(copyEid(eid)).build() + )); + + Eid sameEid = + new EidBuilder().setAddress(new Ipv4Builder().setIpv4(new Ipv4Address("192.168.2.1")).build()).build(); + MappingId sameId = new MappingId("first"); + + assertTrue(eidMappingContext.containsEid(sameId, mappingContext)); + + org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid + loadedEid = eidMappingContext.getEid(sameId, mappingContext); + + assertEquals("192.168.2.1", ((Ipv4) (loadedEid.getAddress())).getIpv4().getValue()); + } + + private org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.Eid copyEid( + Eid eid) { + return new org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.eid.mapping.context.rev160801.contexts.eid.mapping.context.mappings.mapping.EidBuilder() + .setAddress(eid.getAddress()) + .setAddressType(eid.getAddressType()) + .setVirtualNetworkId(eid.getVirtualNetworkId()) + .build(); + } +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/util/EidConverterTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/util/EidConverterTest.java new file mode 100755 index 000000000..15087ef24 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/util/EidConverterTest.java @@ -0,0 +1,49 @@ +package io.fd.honeycomb.lisp.translate.util; + +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static io.fd.honeycomb.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.MAC; +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.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv6Builder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.MacBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; + +public class EidConverterTest { + + @Test + public void testGetEidType() { + assertEquals(IPV4, EidConverter + .getEidType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new Ipv4Builder().setIpv4( + new Ipv4Address("192.168.2.1")) + .build()) + .build())); + + assertEquals(IPV6, EidConverter + .getEidType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new Ipv6Builder().setIpv6( + new Ipv6Address("2001:0db8:0a0b:12f0:0000:0000:0000:0001")) + .build()) + .build())); + + assertEquals(MAC, EidConverter + .getEidType( + new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder() + .setAddress( + new MacBuilder().setMac( + new MacAddress("aa:bb:cc:dd:ee:ff")) + .build()) + .build())); + + //TODO testing of other types when they are implemented + } +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizerTest.java new file mode 100755 index 000000000..6dccdfeab --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/InterfaceCustomizerTest.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +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.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.locator.set.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispAddDelLocator; +import org.openvpp.jvpp.core.dto.LispAddDelLocatorReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class InterfaceCustomizerTest { + + @Mock + private FutureJVppCore fakeJvpp; + + @Mock + private WriteContext writeContext; + + @Mock + private MappingContext mappingContext; + + @Captor + private ArgumentCaptor<LispAddDelLocator> intfCaptor; + + private NamingContext namingContext; + private InstanceIdentifier<Interface> id; + private CompletableFuture<LispAddDelLocatorReply> completeFuture; + private LispAddDelLocatorReply fakeReply; + private Interface intf; + private InterfaceCustomizer customizer; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + id = InstanceIdentifier.builder(Lisp.class) + .child(LocatorSets.class) + .child(LocatorSet.class, new LocatorSetKey("Locator")) + .child(Interface.class, new InterfaceKey("Interface")) + .build(); + + intf = new InterfaceBuilder() + .setPriority((short) 1) + .setWeight((short) 2) + .build(); + + namingContext = new NamingContext("PREFIX", "INSTANCE"); + + customizer = new InterfaceCustomizer(fakeJvpp, namingContext); + + fakeReply = new LispAddDelLocatorReply(); + + completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(writeContext.getMappingContext()).thenReturn(mappingContext); + when(mappingContext.read(Mockito.any())) + .thenReturn(Optional.of((DataObject) new MappingBuilder().setIndex(5).setName("interface").build())); + when(fakeJvpp.lispAddDelLocator(any(LispAddDelLocator.class))).thenReturn(completeFuture); + + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + new InterfaceCustomizer(mock(FutureJVppCore.class), new NamingContext("PREFIX", "INSTANCE")) + .writeCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullPriority() throws WriteFailedException { + Interface intf = mock(Interface.class); + when(intf.getWeight()).thenReturn((short) 1); + when(intf.getPriority()).thenReturn(null); + + new InterfaceCustomizer(mock(FutureJVppCore.class), new NamingContext("PREFIX", "INSTANCE")) + .writeCurrentAttributes(null, intf, null); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullWeight() throws WriteFailedException { + Interface intf = mock(Interface.class); + when(intf.getWeight()).thenReturn(null); + when(intf.getPriority()).thenReturn((short) 1); + + new InterfaceCustomizer(mock(FutureJVppCore.class), new NamingContext("PREFIX", "INSTANCE")) + .writeCurrentAttributes(null, intf, null); + } + + @Test + public void testWriteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + customizer.writeCurrentAttributes(id, intf, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelLocator(intfCaptor.capture()); + + LispAddDelLocator request = intfCaptor.getValue(); + + assertNotNull(request); + assertEquals(1, request.isAdd); + assertEquals(2, request.weight); + assertEquals(1, request.priority); + assertEquals(5, request.swIfIndex); + assertEquals("Locator", TranslateUtils.toString(request.locatorSetName)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + new InterfaceCustomizer(fakeJvpp, namingContext) + .updateCurrentAttributes(null, null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullData() throws WriteFailedException { + new InterfaceCustomizer(fakeJvpp, namingContext) + .deleteCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullPriority() throws WriteFailedException { + Interface interf = mock(Interface.class); + when(interf.getWeight()).thenReturn((short) 1); + when(interf.getPriority()).thenReturn(null); + + new InterfaceCustomizer(mock(FutureJVppCore.class), new NamingContext("PREFIX", "INSTANCE")) + .deleteCurrentAttributes(null, interf, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullWeight() throws WriteFailedException { + Interface interf = mock(Interface.class); + when(interf.getWeight()).thenReturn(null); + when(interf.getPriority()).thenReturn((short) 1); + + new InterfaceCustomizer(mock(FutureJVppCore.class), new NamingContext("PREFIX", "INSTANCE")) + .deleteCurrentAttributes(null, interf, null); + } + + @Test + public void testDeleteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + customizer.deleteCurrentAttributes(id, intf, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelLocator(intfCaptor.capture()); + + LispAddDelLocator request = intfCaptor.getValue(); + + assertNotNull(request); + assertEquals(0, request.isAdd); + assertEquals(2, request.weight); + assertEquals(1, request.priority); + assertEquals(5, request.swIfIndex); + assertEquals("Locator", TranslateUtils.toString(request.locatorSetName)); + } +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LispCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LispCustomizerTest.java new file mode 100755 index 000000000..aaa73303c --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LispCustomizerTest.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.LispBuilder; +import org.openvpp.jvpp.core.dto.LispEnableDisable; +import org.openvpp.jvpp.core.dto.LispEnableDisableReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class LispCustomizerTest { + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + new LispCustomizer(mock(FutureJVppCore.class)).writeCurrentAttributes(null, null, null); + } + + @Test + public void testWriteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + Lisp intf = new LispBuilder().setEnable(true).build(); + + ArgumentCaptor<LispEnableDisable> mappingCaptor = ArgumentCaptor.forClass(LispEnableDisable.class); + + LispEnableDisableReply fakeReply = new LispEnableDisableReply(); + + CompletableFuture<LispEnableDisableReply> completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(fakeJvpp.lispEnableDisable(any(LispEnableDisable.class))).thenReturn(completeFuture); + + new LispCustomizer(fakeJvpp).writeCurrentAttributes(null, intf, null); + + verify(fakeJvpp, times(1)).lispEnableDisable(mappingCaptor.capture()); + + LispEnableDisable request = mappingCaptor.getValue(); + + assertNotNull(request); + assertEquals(1, request.isEn); + } + + @Test(expected = NullPointerException.class) + public void testUpdateCurrentAttributesNullData() throws WriteFailedException { + new LispCustomizer(mock(FutureJVppCore.class)).updateCurrentAttributes(null, null, null, null); + } + + @Test + public void testUpdateCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + Lisp lisp = new LispBuilder().setEnable(true).build(); + + ArgumentCaptor<LispEnableDisable> lispCaptor = ArgumentCaptor.forClass(LispEnableDisable.class); + + LispEnableDisableReply fakeReply = new LispEnableDisableReply(); + + CompletableFuture<LispEnableDisableReply> completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(fakeJvpp.lispEnableDisable(any(LispEnableDisable.class))).thenReturn(completeFuture); + + new LispCustomizer(fakeJvpp).updateCurrentAttributes(null, null, lisp, null); + + verify(fakeJvpp, times(1)).lispEnableDisable(lispCaptor.capture()); + + LispEnableDisable request = lispCaptor.getValue(); + + assertNotNull(request); + assertEquals(1, request.isEn); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullData() throws WriteFailedException { + new LispCustomizer(mock(FutureJVppCore.class)).deleteCurrentAttributes(null, null, null); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + Lisp lisp = new LispBuilder().setEnable(true).build(); + + ArgumentCaptor<LispEnableDisable> lispCaptor = ArgumentCaptor.forClass(LispEnableDisable.class); + + LispEnableDisableReply fakeReply = new LispEnableDisableReply(); + + CompletableFuture<LispEnableDisableReply> completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(fakeJvpp.lispEnableDisable(any(LispEnableDisable.class))).thenReturn(completeFuture); + + new LispCustomizer(fakeJvpp).deleteCurrentAttributes(null, lisp, null); + + verify(fakeJvpp, times(1)).lispEnableDisable(lispCaptor.capture()); + + LispEnableDisable request = lispCaptor.getValue(); + + assertNotNull(request); + assertEquals(0, request.isEn); + } + +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizerTest.java new file mode 100755 index 000000000..2b28ce6b9 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocalMappingCustomizerTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +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.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.LocalMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.LocalMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.local.mappings.local.mapping.EidBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispAddDelLocalEid; +import org.openvpp.jvpp.core.dto.LispAddDelLocalEidReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class LocalMappingCustomizerTest { + + @Mock + private FutureJVppCore fakeJvpp; + + @Captor + private ArgumentCaptor<LispAddDelLocalEid> mappingCaptor; + + private MappingId mappingId; + private InstanceIdentifier<LocalMapping> id; + private LocalMapping mapping; + private LispAddDelLocalEidReply fakeReply; + private CompletableFuture<LispAddDelLocalEidReply> completeFuture; + private LocalMappingCustomizer customizer; + private EidMappingContext localMappingContext; + private WriteContext writeContext; + private MappingContext mappingCtx; + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + final Eid + eid = new EidBuilder().setAddress( + new Ipv4Builder().setIpv4( + new Ipv4Address("192.168.2.1")) + .build()) + .build(); + + + mappingId = new MappingId("REMOTE"); + final LocalMappingKey key = new LocalMappingKey(mappingId); + localMappingContext = new EidMappingContext("local"); + mappingCtx = mock(MappingContext.class); + writeContext = mock(WriteContext.class); + + mapping = new LocalMappingBuilder() + .setEid(eid) + .setLocatorSet("Locator") + .build(); + + id = InstanceIdentifier.builder(Lisp.class) + .child(EidTable.class) + .child(VniTable.class, new VniTableKey(25L)) + .child(LocalMappings.class) + .child(LocalMapping.class, new LocalMappingKey(new MappingId("local"))) + .build(); + + fakeReply = new LispAddDelLocalEidReply(); + completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + customizer = new LocalMappingCustomizer(fakeJvpp, localMappingContext); + + when(fakeJvpp.lispAddDelLocalEid(any(LispAddDelLocalEid.class))).thenReturn(completeFuture); + when(writeContext.getMappingContext()).thenReturn(mappingCtx); + when(mappingCtx.read(Mockito.any())).thenReturn(com.google.common.base.Optional + .of(new LocalMappingBuilder().setKey(key).setId(mappingId).setEid(eid).build())); + } + + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + customizer.writeCurrentAttributes(null, null, writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullEid() throws WriteFailedException { + + LocalMapping mapping = mock(LocalMapping.class); + when(mapping.getEid()).thenReturn(null); + when(mapping.getLocatorSet()).thenReturn("Locator"); + + new LocalMappingCustomizer(mock(FutureJVppCore.class), localMappingContext) + .writeCurrentAttributes(null, mapping, writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullLocator() throws WriteFailedException { + + LocalMapping mapping = mock(LocalMapping.class); + when(mapping.getEid()).thenReturn(mock(Eid.class)); + when(mapping.getLocatorSet()).thenReturn(null); + + customizer.writeCurrentAttributes(null, mapping, writeContext); + } + + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + //to simulate no mapping + when(mappingCtx.read(Mockito.any())).thenReturn(com.google.common.base.Optional.absent()); + + customizer.writeCurrentAttributes(id, mapping, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelLocalEid(mappingCaptor.capture()); + + LispAddDelLocalEid request = mappingCaptor.getValue(); + + assertNotNull(request); + assertEquals("Locator", new String(request.locatorSetName)); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.eid).getValue()); + assertEquals(0, request.eidType); + assertEquals(1, request.isAdd); + assertEquals(25, request.vni); + assertEquals("Locator", TranslateUtils.toString(request.locatorSetName)); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + new LocalMappingCustomizer(mock(FutureJVppCore.class), localMappingContext) + .updateCurrentAttributes(null, null, null, writeContext); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + customizer.deleteCurrentAttributes(id, mapping, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelLocalEid(mappingCaptor.capture()); + + LispAddDelLocalEid request = mappingCaptor.getValue(); + + assertNotNull(request); + assertEquals("Locator", new String(request.locatorSetName)); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.eid).getValue()); + assertEquals(0, request.eidType); + assertEquals(0, request.isAdd); + assertEquals(25, request.vni); + assertEquals("Locator", TranslateUtils.toString(request.locatorSetName)); + } +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizerTest.java new file mode 100755 index 000000000..e7fb88ae5 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/LocatorSetCustomizerTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableList; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.ModificationCache; +import io.fd.honeycomb.translate.v3po.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.locator.sets.grouping.locator.sets.LocatorSetBuilder; +import org.openvpp.jvpp.core.dto.LispAddDelLocatorSet; +import org.openvpp.jvpp.core.dto.LispAddDelLocatorSetReply; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetails; +import org.openvpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class LocatorSetCustomizerTest { + + private FutureJVppCore fakeJvpp; + private NamingContext locatorSetContext; + private MappingContext mappingContext; + private ModificationCache cache; + private WriteContext context; + + @Before + public void init() { + fakeJvpp = mock(FutureJVppCore.class); + locatorSetContext = new NamingContext("locator-set", "instance"); + context = mock(WriteContext.class); + mappingContext = mock(MappingContext.class); + cache = new ModificationCache(); + when(context.getMappingContext()).thenReturn(mappingContext); + when(context.getModificationCache()).thenReturn(cache); + } + + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + new LocatorSetCustomizer(fakeJvpp, locatorSetContext).writeCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesBadData() throws WriteFailedException { + new LocatorSetCustomizer(fakeJvpp, locatorSetContext) + .writeCurrentAttributes(null, mock(LocatorSet.class), null); + } + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + + LocatorSet locatorSet = new LocatorSetBuilder() + .setName("Locator") + .build(); + + ArgumentCaptor<LispAddDelLocatorSet> locatorSetCaptor = ArgumentCaptor.forClass(LispAddDelLocatorSet.class); + + LispAddDelLocatorSetReply fakeReply = new LispAddDelLocatorSetReply(); + + CompletableFuture<LispAddDelLocatorSetReply> completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(fakeJvpp.lispAddDelLocatorSet(any(LispAddDelLocatorSet.class))).thenReturn(completeFuture); + + final LispLocatorSetDetailsReplyDump reply = new LispLocatorSetDetailsReplyDump(); + LispLocatorSetDetails details = new LispLocatorSetDetails(); + details.locatorSetName = "Locator".getBytes(StandardCharsets.UTF_8); + reply.lispLocatorSetDetails = ImmutableList.of(details); + + cache.put(io.fd.honeycomb.lisp.translate.read.LocatorSetCustomizer.LOCATOR_SETS_CACHE_ID, reply); + + new LocatorSetCustomizer(fakeJvpp, locatorSetContext).writeCurrentAttributes(null, locatorSet, context); + + verify(fakeJvpp, times(1)).lispAddDelLocatorSet(locatorSetCaptor.capture()); + + LispAddDelLocatorSet request = locatorSetCaptor.getValue(); + + assertNotNull(request); + assertEquals("Locator", new String(request.locatorSetName)); + assertEquals(1, request.isAdd); + + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + new LocatorSetCustomizer(fakeJvpp, locatorSetContext).updateCurrentAttributes(null, null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullData() throws WriteFailedException { + new LocatorSetCustomizer(fakeJvpp, locatorSetContext).deleteCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesBadData() throws WriteFailedException { + new LocatorSetCustomizer(fakeJvpp, locatorSetContext) + .deleteCurrentAttributes(null, mock(LocatorSet.class), null); + } + + @Test + public void testDeleteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + + LocatorSet locatorSet = new LocatorSetBuilder() + .setName("Locator") + .build(); + + ArgumentCaptor<LispAddDelLocatorSet> locatorSetCaptor = ArgumentCaptor.forClass(LispAddDelLocatorSet.class); + + LispAddDelLocatorSetReply fakeReply = new LispAddDelLocatorSetReply(); + + CompletableFuture<LispAddDelLocatorSetReply> completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + + when(fakeJvpp.lispAddDelLocatorSet(any(LispAddDelLocatorSet.class))).thenReturn(completeFuture); + + new LocatorSetCustomizer(fakeJvpp, locatorSetContext).deleteCurrentAttributes(null, locatorSet, context); + + verify(fakeJvpp, times(1)).lispAddDelLocatorSet(locatorSetCaptor.capture()); + + LispAddDelLocatorSet request = locatorSetCaptor.getValue(); + + assertNotNull(request); + assertEquals("Locator", new String(request.locatorSetName)); + assertEquals(0, request.isAdd); + + } +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizerTest.java new file mode 100755 index 000000000..63be37a23 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/MapResolverCustomizerTest.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +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.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.map.resolvers.grouping.map.resolvers.MapResolverBuilder; +import org.openvpp.jvpp.core.dto.LispAddDelMapResolver; +import org.openvpp.jvpp.core.dto.LispAddDelMapResolverReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class MapResolverCustomizerTest { + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + new MapResolverCustomizer(mock(FutureJVppCore.class)).writeCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesBadData() throws WriteFailedException { + new MapResolverCustomizer(mock(FutureJVppCore.class)) + .writeCurrentAttributes(null, new MapResolverBuilder().build(), null); + } + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + + MapResolverCustomizer customizer = new MapResolverCustomizer(fakeJvpp); + Ipv4Address address = new Ipv4Address("192.168.2.1"); + MapResolver resolver = new MapResolverBuilder().setIpAddress(new IpAddress(address)).build(); + + ArgumentCaptor<LispAddDelMapResolver> resolverCaptor = ArgumentCaptor.forClass(LispAddDelMapResolver.class); + + LispAddDelMapResolverReply fakeReply = new LispAddDelMapResolverReply(); + + CompletableFuture<LispAddDelMapResolverReply> finalStage = new CompletableFuture<>(); + finalStage.complete(fakeReply); + + when(fakeJvpp.lispAddDelMapResolver(any(LispAddDelMapResolver.class))).thenReturn(finalStage); + + customizer.writeCurrentAttributes(null, resolver, null); + verify(fakeJvpp, times(1)).lispAddDelMapResolver(resolverCaptor.capture()); + + LispAddDelMapResolver request = resolverCaptor.getValue(); + assertEquals(1, request.isAdd); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.ipAddress).getValue()); + } + + + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + new MapResolverCustomizer(mock(FutureJVppCore.class)).updateCurrentAttributes(null, null, null, null); + } + + @Test + public void testDeleteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + + MapResolverCustomizer customizer = new MapResolverCustomizer(fakeJvpp); + Ipv4Address address = new Ipv4Address("192.168.2.1"); + MapResolver resolver = new MapResolverBuilder().setIpAddress(new IpAddress(address)).build(); + + ArgumentCaptor<LispAddDelMapResolver> resolverCaptor = ArgumentCaptor.forClass(LispAddDelMapResolver.class); + + LispAddDelMapResolverReply fakeReply = new LispAddDelMapResolverReply(); + + CompletableFuture<LispAddDelMapResolverReply> finalStage = new CompletableFuture<>(); + finalStage.complete(fakeReply); + + when(fakeJvpp.lispAddDelMapResolver(any(LispAddDelMapResolver.class))).thenReturn(finalStage); + + customizer.deleteCurrentAttributes(null, resolver, null); + verify(fakeJvpp, times(1)).lispAddDelMapResolver(resolverCaptor.capture()); + + LispAddDelMapResolver request = resolverCaptor.getValue(); + assertEquals(0, request.isAdd); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.ipAddress).getValue()); + } + +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizerTest.java new file mode 100755 index 000000000..5f1ffb888 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/PitrCfgCustomizerTest.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.pitr.cfg.grouping.PitrCfgBuilder; +import org.openvpp.jvpp.core.dto.LispPitrSetLocatorSet; +import org.openvpp.jvpp.core.dto.LispPitrSetLocatorSetReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class PitrCfgCustomizerTest { + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + new PitrCfgCustomizer(mock(FutureJVppCore.class)).writeCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesBadData() throws WriteFailedException { + new PitrCfgCustomizer(mock(FutureJVppCore.class)).writeCurrentAttributes(null, mock(PitrCfg.class), null); + } + + @Test + public void testWriteCurrentAttributes() throws InterruptedException, ExecutionException, WriteFailedException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + + PitrCfgCustomizer customizer = new PitrCfgCustomizer(fakeJvpp); + PitrCfg cfg = new PitrCfgBuilder().setLocatorSet("Locator").build(); + + ArgumentCaptor<LispPitrSetLocatorSet> cfgCaptor = ArgumentCaptor.forClass(LispPitrSetLocatorSet.class); + + LispPitrSetLocatorSetReply fakeReply = new LispPitrSetLocatorSetReply(); + + CompletableFuture<LispPitrSetLocatorSetReply> finalStage = new CompletableFuture<>(); + finalStage.complete(fakeReply); + + when(fakeJvpp.lispPitrSetLocatorSet(any(LispPitrSetLocatorSet.class))).thenReturn(finalStage); + + customizer.writeCurrentAttributes(null, cfg, null); + verify(fakeJvpp, times(1)).lispPitrSetLocatorSet(cfgCaptor.capture()); + + LispPitrSetLocatorSet request = cfgCaptor.getValue(); + assertEquals(1, request.isAdd); + assertEquals("Locator", new String(request.lsName)); + } + + @Test + public void testUpdateCurrentAttributes() throws WriteFailedException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + + PitrCfgCustomizer customizer = new PitrCfgCustomizer(fakeJvpp); + PitrCfg cfg = new PitrCfgBuilder().setLocatorSet("Locator").build(); + + ArgumentCaptor<LispPitrSetLocatorSet> cfgCaptor = ArgumentCaptor.forClass(LispPitrSetLocatorSet.class); + + LispPitrSetLocatorSetReply fakeReply = new LispPitrSetLocatorSetReply(); + + CompletableFuture<LispPitrSetLocatorSetReply> finalStage = new CompletableFuture<>(); + finalStage.complete(fakeReply); + + when(fakeJvpp.lispPitrSetLocatorSet(any(LispPitrSetLocatorSet.class))).thenReturn(finalStage); + + customizer.writeCurrentAttributes(null, cfg, null); + verify(fakeJvpp, times(1)).lispPitrSetLocatorSet(cfgCaptor.capture()); + + LispPitrSetLocatorSet request = cfgCaptor.getValue(); + assertEquals(1, request.isAdd); + assertEquals("Locator", new String(request.lsName)); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullData() throws WriteFailedException { + new PitrCfgCustomizer(mock(FutureJVppCore.class)).deleteCurrentAttributes(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesBadData() throws WriteFailedException { + new PitrCfgCustomizer(mock(FutureJVppCore.class)).deleteCurrentAttributes(null, mock(PitrCfg.class), null); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + FutureJVppCore fakeJvpp = mock(FutureJVppCore.class); + + PitrCfgCustomizer customizer = new PitrCfgCustomizer(fakeJvpp); + PitrCfg cfg = new PitrCfgBuilder().setLocatorSet("Locator").build(); + + ArgumentCaptor<LispPitrSetLocatorSet> cfgCaptor = ArgumentCaptor.forClass(LispPitrSetLocatorSet.class); + + LispPitrSetLocatorSetReply fakeReply = new LispPitrSetLocatorSetReply(); + + CompletableFuture<LispPitrSetLocatorSetReply> finalStage = new CompletableFuture<>(); + finalStage.complete(fakeReply); + + when(fakeJvpp.lispPitrSetLocatorSet(any(LispPitrSetLocatorSet.class))).thenReturn(finalStage); + + customizer.deleteCurrentAttributes(null, cfg, null); + verify(fakeJvpp, times(1)).lispPitrSetLocatorSet(cfgCaptor.capture()); + + LispPitrSetLocatorSet request = cfgCaptor.getValue(); + assertEquals(0, request.isAdd); + assertEquals("Locator", new String(request.lsName)); + } + +} diff --git a/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizerTest.java b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizerTest.java new file mode 100755 index 000000000..7797db1f7 --- /dev/null +++ b/lisp/lisp2vpp/src/test/java/io/fd/honeycomb/lisp/translate/write/RemoteMappingCustomizerTest.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2015 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.lisp.translate.write; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.lisp.context.util.EidMappingContext; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.v3po.util.TranslateUtils; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +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; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.address.Ipv4Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MapReplyAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.EidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.NegativeMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev160520.eid.table.grouping.eid.table.vni.table.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.LocatorBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.jvpp.core.dto.LispAddDelRemoteMapping; +import org.openvpp.jvpp.core.dto.LispAddDelRemoteMappingReply; +import org.openvpp.jvpp.core.future.FutureJVppCore; + + +public class RemoteMappingCustomizerTest { + + @Mock + private FutureJVppCore fakeJvpp; + + @Captor + private ArgumentCaptor<LispAddDelRemoteMapping> mappingCaptor; + + private MappingId mappingId; + private RemoteMappingCustomizer customizer; + private RemoteMapping intf; + private LispAddDelRemoteMappingReply fakeReply; + private CompletableFuture<LispAddDelRemoteMappingReply> completeFuture; + private InstanceIdentifier<RemoteMapping> id; + private EidMappingContext remoteMappingContext; + private WriteContext writeContext; + private MappingContext mapping; + + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + + final Eid eid = new EidBuilder().setAddress( + new Ipv4Builder().setIpv4( + new Ipv4Address("192.168.2.1")) + .build()) + .build(); + + mappingId = new MappingId("REMOTE"); + final RemoteMappingKey key = new RemoteMappingKey(mappingId); + remoteMappingContext = new EidMappingContext("remote"); + mapping = mock(MappingContext.class); + writeContext = mock(WriteContext.class); + + + intf = new RemoteMappingBuilder() + .setEid( + eid) + .setLocatorList(new NegativeMappingBuilder().setMapReplyAction(MapReplyAction.Drop).build()) + .build(); + + id = InstanceIdentifier.builder(Lisp.class).child(EidTable.class) + .child(VniTable.class, new VniTableKey(25L)) + .child(RemoteMappings.class) + .child(RemoteMapping.class, key).build(); + + fakeReply = new LispAddDelRemoteMappingReply(); + completeFuture = new CompletableFuture<>(); + completeFuture.complete(fakeReply); + customizer = new RemoteMappingCustomizer(fakeJvpp, remoteMappingContext); + + when(fakeJvpp.lispAddDelRemoteMapping(Mockito.any())).thenReturn(completeFuture); + when(writeContext.getMappingContext()).thenReturn(mapping); + when(mapping.read(Mockito.any())).thenReturn(com.google.common.base.Optional + .of(new RemoteMappingBuilder().setKey(key).setId(mappingId).setEid(eid).build())); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesNullData() throws WriteFailedException { + customizer.writeCurrentAttributes(null, null, writeContext); + } + + @Test(expected = NullPointerException.class) + public void testWriteCurrentAttributesBadData() throws WriteFailedException { + customizer + .writeCurrentAttributes(null, mock(RemoteMapping.class), writeContext); + } + + @Test + public void testWriteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + //to simulate no mapping + when(mapping.read(Mockito.any())).thenReturn(com.google.common.base.Optional.absent()); + + customizer.writeCurrentAttributes(id, intf, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelRemoteMapping(mappingCaptor.capture()); + + LispAddDelRemoteMapping request = mappingCaptor.getValue(); + + assertNotNull(request); + assertEquals(1, request.isAdd); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.eid).getValue()); + assertEquals(25, request.vni); + } + + @Test(expected = UnsupportedOperationException.class) + public void testUpdateCurrentAttributes() throws WriteFailedException { + customizer.updateCurrentAttributes(null, null, null, writeContext); + } + + @Test(expected = NullPointerException.class) + public void testDeleteCurrentAttributesNullData() throws WriteFailedException { + customizer.deleteCurrentAttributes(null, null, writeContext); + } + + @Test + public void testDeleteCurrentAttributes() throws WriteFailedException, InterruptedException, ExecutionException { + customizer.deleteCurrentAttributes(id, intf, writeContext); + + verify(fakeJvpp, times(1)).lispAddDelRemoteMapping(mappingCaptor.capture()); + + LispAddDelRemoteMapping request = mappingCaptor.getValue(); + + assertNotNull(request); + assertEquals(0, request.isAdd); + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(request.eid).getValue()); + assertEquals(25, request.vni); + } + +} diff --git a/lisp/pom.xml b/lisp/pom.xml index 67670397b..e55294ba2 100644..100755 --- a/lisp/pom.xml +++ b/lisp/pom.xml @@ -34,6 +34,7 @@ </prerequisites> <modules> <module>api</module> + <module>lisp2vpp</module> </modules> <!-- DO NOT install or deploy the repo root pom as it's only needed to initiate a build --> @@ -55,4 +56,4 @@ </plugin> </plugins> </build> -</project>
\ No newline at end of file +</project> @@ -35,8 +35,8 @@ <module>infra</module> <module>nsh</module> <module>vpp-common</module> - <module>v3po</module> <module>vpp-integration</module> + <module>v3po</module> <module>lisp</module> <module>samples</module> <module>tools</module> diff --git a/vpp-common/vpp-translate-utils/pom.xml b/vpp-common/vpp-translate-utils/pom.xml index 12cb770ec..15431c59d 100644 --- a/vpp-common/vpp-translate-utils/pom.xml +++ b/vpp-common/vpp-translate-utils/pom.xml @@ -74,6 +74,11 @@ <artifactId>data-api</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.9</version> + </dependency> <!-- Testing Dependencies --> <dependency> diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/TranslateUtils.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/TranslateUtils.java index 0902064eb..95b07743f 100644 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/TranslateUtils.java +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/TranslateUtils.java @@ -17,6 +17,8 @@ package io.fd.honeycomb.translate.v3po.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.base.Splitter; import com.google.common.net.InetAddresses; @@ -28,10 +30,21 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.BiConsumer; +import java.util.stream.Collectors; import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Hex; +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.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.Ipv4Prefix; +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; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.jvpp.VppBaseCallException; import org.openvpp.jvpp.dto.JVppReply; @@ -102,6 +115,236 @@ public final class TranslateUtils { } } + public static final 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())); + } + } + + /** + * Creates address array from address part of {@link Ipv4Prefix} + */ + public static 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; + } + + /** + * Converts {@link IpAddress} to array representing {@link Ipv4Address} or {@link Ipv6Address} + */ + public static 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 + public static IpAddress arrayToIpAddress(boolean isIpv6, byte[] ip) { + if (isIpv6) { + return new IpAddress(arrayToIpv6AddressNoZone(ip)); + } else { + return new IpAddress(arrayToIpv4AddressNoZone(ip)); + } + } + + /** + * Extracts {@link Ipv4Prefix} prefix + */ + public static 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 + */ + public static Ipv4Prefix arrayToIpv4Prefix(final byte[] address, byte prefixLength) { + Ipv4AddressNoZone addressPart = arrayToIpv4AddressNoZone(address); + + return new Ipv4Prefix(addressPart.getValue().concat("/").concat(String.valueOf(prefixLength))); + } + + /** + * 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 + */ + public static byte[] ipv6AddressNoZoneToArray(@Nonnull final Ipv6AddressNoZone ipv6Addr) { + byte[] retval = new byte[16]; + + //splits address and add ommited zeros for easier parsing + List<String> 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} + */ + public static 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 + */ + public static 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 + */ + public static 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 + public static 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); + } + } + + + /** + * 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 + public static 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); + } + } + + /** + * Converts byte array to address string ,not separated with ":" + */ + public static String byteArrayToMacUnseparated(byte[] address) { + checkArgument(address.length == 6, "Illegal array length"); + return Hex.encodeHexString(address); + } + + /** + * Converts byte array to address string ,separated with ":" + */ + public static String byteArrayToMacSeparated(byte[] address) { + checkArgument(address.length == 6, "Illegal array length"); + + String unseparatedAddress = Hex.encodeHexString(address); + 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 + * */ + public static 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); + } + } + + /** + * Detects whether {@code IpAddress} is ipv6 + */ + public static boolean isIpv6(IpAddress address) { + checkNotNull(address, "Address cannot be null"); + + checkState(!(address.getIpv4Address() == null && address.getIpv6Address() == null), "Invalid address"); + return address.getIpv6Address() != null; + } + + /** + * Detects whether {@code IpPrefix} is ipv6 + */ + public static boolean isIpv6(IpPrefix address) { + checkNotNull(address, "Address cannot be null"); + checkState(!(address.getIpv4Prefix() == null && address.getIpv6Prefix() == null), "Invalid address"); + return address.getIpv6Prefix() != null; + } + + /** * Transform Ipv4 address to a byte array acceptable by VPP. VPP expects incoming byte array to be in the same order * as the address. @@ -144,6 +387,31 @@ public final class TranslateUtils { } /** + * 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 + public static 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); + } + } + + /** * Return (interned) string from byte array while removing \u0000. Strings represented as fixed length byte[] from * vpp contain \u0000. */ diff --git a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/cache/EntityDumpExecutor.java b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/cache/EntityDumpExecutor.java index 8f3ae5596..5bc2a4b77 100644 --- a/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/cache/EntityDumpExecutor.java +++ b/vpp-common/vpp-translate-utils/src/main/java/io/fd/honeycomb/translate/v3po/util/cache/EntityDumpExecutor.java @@ -26,6 +26,8 @@ import javax.annotation.concurrent.ThreadSafe; @ThreadSafe public interface EntityDumpExecutor<T, U> { + static Void NO_PARAMS = null; + /** * Performs dump on {@link T} entity * diff --git a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/TranslateUtilsTest.java b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/TranslateUtilsTest.java index d9cb52f3a..a55c3053a 100644 --- a/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/TranslateUtilsTest.java +++ b/vpp-common/vpp-translate-utils/src/test/java/io/fd/honeycomb/translate/v3po/util/TranslateUtilsTest.java @@ -15,6 +15,9 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; 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; +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; import org.opendaylight.yangtools.yang.binding.DataContainer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -134,4 +137,62 @@ public class TranslateUtilsTest { TranslateUtils.byteToBoolean((byte) 123); } + @Test + public void testIpv6NoZone(){ + final Ipv6AddressNoZone ipv6Addr = new Ipv6AddressNoZone("3ffe:1900:4545:3:200:f8ff:fe21:67cf"); + byte[] bytes = TranslateUtils.ipv6AddressNoZoneToArray(ipv6Addr); + assertEquals((byte)63,bytes[0]); + + bytes = reverseBytes(bytes); + final Ipv6AddressNoZone ivp6AddressNoZone = TranslateUtils.arrayToIpv6AddressNoZone(bytes); + assertEquals(ipv6Addr,ivp6AddressNoZone); + } + + @Test + public void testByteArrayToMacUnseparated(){ + byte[] address = TranslateUtils.parseMac("aa:bb:cc:dd:ee:ff"); + + String converted = TranslateUtils.byteArrayToMacUnseparated(address); + + assertEquals("aabbccddeeff",converted); + } + + @Test + public void testByteArrayToMacSeparated(){ + byte[] address = TranslateUtils.parseMac("aa:bb:cc:dd:ee:ff"); + + String converted = TranslateUtils.byteArrayToMacSeparated(address); + + assertEquals("aa:bb:cc:dd:ee:ff",converted); + } + + @Test(expected = IllegalArgumentException.class) + public void testByteArrayToMacUnseparatedIllegal(){ + TranslateUtils.byteArrayToMacUnseparated(new byte[]{54,26,87,32,14}); + } + + @Test(expected = IllegalArgumentException.class) + public void testByteArrayToMacSeparatedIllegal() { + TranslateUtils.byteArrayToMacSeparated(new byte[]{54, 26, 87, 32, 14}); + } + + @Test + public void testIpv4AddressPrefixToArray() { + byte[] ip = TranslateUtils.ipv4AddressPrefixToArray(new Ipv4Prefix("192.168.2.1/24")); + + assertEquals("1.2.168.192", TranslateUtils.arrayToIpv4AddressNoZone(ip).getValue()); + } + + @Test + public void testIpv6AddressPrefixToArray() { + byte[] ip = TranslateUtils.ipv6AddressPrefixToArray(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48")); + + assertEquals("cf67:21fe:fff8:2:300:4545:19:fe3f", TranslateUtils.arrayToIpv6AddressNoZone(ip).getValue()); + } + + @Test + public void testExtractPrefix() { + assertEquals(24, TranslateUtils.extractPrefix(new Ipv4Prefix("192.168.2.1/24"))); + assertEquals(48, TranslateUtils.extractPrefix(new Ipv6Prefix("3ffe:1900:4545:3:200:f8ff:fe21:67cf/48"))); + } }
\ No newline at end of file diff --git a/vpp-integration/minimal-distribution/pom.xml b/vpp-integration/minimal-distribution/pom.xml index 39f1070d8..e3244c203 100644 --- a/vpp-integration/minimal-distribution/pom.xml +++ b/vpp-integration/minimal-distribution/pom.xml @@ -30,6 +30,7 @@ <properties> <main.class>io.fd.honeycomb.vpp.integration.distro.Main</main.class> <v3po.version>1.16.9-SNAPSHOT</v3po.version> + <lisp.version>1.16.9-SNAPSHOT</lisp.version> <vpp.common.min.distro.version>1.16.9-SNAPSHOT</vpp.common.min.distro.version> </properties> @@ -67,6 +68,10 @@ <artifactId>v3po2vpp</artifactId> <version>${v3po.version}</version> </dependency> - + <dependency> + <groupId>io.fd.honeycomb.lisp</groupId> + <artifactId>lisp2vpp</artifactId> + <version>${lisp.version}</version> + </dependency> </dependencies> </project> diff --git a/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java b/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java index 6485aedb1..7c1d07d80 100644 --- a/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java +++ b/vpp-integration/minimal-distribution/src/main/java/io/fd/honeycomb/vpp/integration/distro/Main.java @@ -18,6 +18,7 @@ package io.fd.honeycomb.vpp.integration.distro; import com.google.common.collect.Lists; import com.google.inject.Module; +import io.fd.honeycomb.lisp.LispModule; import io.fd.honeycomb.translate.v3po.V3poModule; import io.fd.honeycomb.vpp.distro.VppCommonModule; import java.util.List; @@ -30,6 +31,7 @@ public class Main { // All the plugins should be listed here sampleModules.add(new VppCommonModule()); sampleModules.add(new V3poModule()); + sampleModules.add(new LispModule()); io.fd.honeycomb.infra.distro.Main.init(sampleModules); } |