diff options
Diffstat (limited to 'lisp/lisp2vpp/src/main/java/io/fd/hc2vpp')
51 files changed, 5788 insertions, 0 deletions
diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/LispModule.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/LispModule.java new file mode 100644 index 000000000..c9acf1d77 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/LispModule.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp; + +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT_PREFIX; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.AbstractModule; +import com.google.inject.Singleton; +import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; +import io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.ContextsReaderFactoryProvider; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.factory.LispStateReaderFactory; +import io.fd.hc2vpp.lisp.translate.write.factory.LispWriterFactory; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.hc2vpp.common.translate.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("Configuring module Lisp"); + install(ConfigurationModule.create()); + 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 Adjacencies context"); + bind(AdjacenciesMappingContext.class) + .annotatedWith(Names.named(LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT)) + .toInstance(new AdjacenciesMappingContext(LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT)); + + LOG.info("Binding reader factories"); + final Multibinder<ReaderFactory> readerFactoryBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerFactoryBinder.addBinding().to(LispStateReaderFactory.class); + LOG.info("Reader factories binded"); + + LOG.info("Binding writer factories"); + final Multibinder<WriterFactory> writerFactoryBinder = Multibinder.newSetBinder(binder(), WriterFactory.class); + writerFactoryBinder.addBinding().to(LispWriterFactory.class); + LOG.info("Writer factories binded"); + + final Multibinder<ReaderFactory> readerBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class); + readerBinder.addBinding().toProvider(ContextsReaderFactoryProvider.class).in(Singleton.class); + + LOG.info("Module Lisp successfully configured"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/cfgattrs/LispConfiguration.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/cfgattrs/LispConfiguration.java new file mode 100644 index 000000000..0092bcf1c --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/cfgattrs/LispConfiguration.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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 HONEYCOMB-176 - 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"; + + /** + * Unique prefix for naming context of locator sets. + **/ + public static final String LOCATOR_SET_CONTEXT_PREFIX = "locator-set-"; + + /** + * Adjacency id to eid pair mapping + * */ + public static final String ADJACENCIES_IDENTIFICATION_CONTEXT = "adjacencies-identification-context"; +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/AdjacenciesMappingContext.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/AdjacenciesMappingContext.java new file mode 100644 index 000000000..a595928db --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/AdjacenciesMappingContext.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.context.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.util.RWUtils; +import java.util.stream.Collector; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.AdjacenciesIdentificationContexts; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.AdjacenciesIdentification; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.AdjacenciesIdentificationKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.Mappings; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.Mapping; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.MappingBuilder; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.MappingKey; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPair; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPairBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +public class AdjacenciesMappingContext { + + private static final Collector<Mapping, ?, Mapping> SINGLE_ITEM_COLLECTOR = RWUtils.singleItemCollector(); + + private final KeyedInstanceIdentifier<AdjacenciesIdentification, AdjacenciesIdentificationKey> + namingContextIid; + + /** + * Create new naming context + * + * @param instanceName name of this context instance. Will be used as list item identifier within context data tree + */ + public AdjacenciesMappingContext(@Nonnull final String instanceName) { + namingContextIid = InstanceIdentifier.create(AdjacenciesIdentificationContexts.class).child( + AdjacenciesIdentification.class, new AdjacenciesIdentificationKey(instanceName)); + } + + /** + * Retrieve name for mapping stored provided mappingContext instance. + * + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + * @return name mapped to provided index + */ + @Nonnull + public synchronized String getAdjacencyId( + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + checkState(read.isPresent(), "No adjacencies mappings stored"); + + return read.get().getMapping().stream() + .filter(mapping -> isSame(pairForCombination(localEidId, remoteEidId), mapping)) + .collect(SINGLE_ITEM_COLLECTOR).getId(); + } + + private boolean isSame(final EidIdentificatorPair currentPair, final Mapping mapping) { + // EidIdentificatorPair is container so it needs to be compared like this + final EidIdentificatorPair mappingPair = mapping.getEidIdentificatorPair(); + return currentPair.getLocalEidId().equals(mappingPair.getLocalEidId()) + && currentPair.getRemoteEidId().equals(mappingPair.getRemoteEidId()); + } + + private EidIdentificatorPair pairForCombination(final @Nonnull String localEidId, + final @Nonnull String remoteEidId) { + return new EidIdentificatorPairBuilder() + .setLocalEidId(new MappingId(localEidId)) + .setRemoteEidId(new MappingId(remoteEidId)) + .build(); + } + + /** + * Check whether mapping is present for index. + * + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + * @return true if present, false otherwise + */ + public synchronized boolean containsId( + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + return read.isPresent() && + read.get().getMapping() + .stream() + .anyMatch(mapping -> isSame(pairForCombination(localEidId, remoteEidId), mapping)); + } + + /** + * Add mapping to current context + * + * @param index index of a mapped item + * @param localEidId {@code MappingId} for local eid + * @param remoteEidId {@code MappingId} for remote eid + * @param mappingContext mapping context providing context data for current transaction + */ + public synchronized void addEidPair( + @Nonnull final String index, + @Nonnull final String localEidId, + @Nonnull final String remoteEidId, + final MappingContext mappingContext) { + + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(index); + mappingContext.put(mappingIid, new MappingBuilder().setId(index).setEidIdentificatorPair( + pairForCombination(localEidId, remoteEidId)).build()); + } + + private KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final String index) { + return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(index)); + } + + + /** + * 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 removeForIndex(@Nonnull final String 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 EidIdentificatorPair getEidPair(@Nonnull final String index, + final MappingContext mappingContext) { + final Optional<Mapping> read = mappingContext.read(getMappingIid(index)); + checkArgument(read.isPresent(), "No mapping stored for index: %s", index); + return read.get().getEidIdentificatorPair(); + } + + /** + * 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 containsEidPairForIndex(@Nonnull final String index, + @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getMappingIid(index)).isPresent(); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactory.java new file mode 100644 index 000000000..2a329cfdd --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.context.util; + +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.honeycomb.translate.util.read.BindingBrokerReader; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +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.ContextsBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * {@link ReaderFactory} initiating reader providing data from context data store for eid's. + * Making them available over RESTCONF/NETCONF. + */ +public class ContextsReaderFactory implements ReaderFactory { + + private final DataBroker contextBindingBrokerDependency; + + public ContextsReaderFactory(final DataBroker contextBindingBrokerDependency) { + this.contextBindingBrokerDependency = contextBindingBrokerDependency; + } + + @Override + public void init(final ModifiableReaderRegistryBuilder registry) { + registry.add(new BindingBrokerReader<>(InstanceIdentifier.create(Contexts.class), + contextBindingBrokerDependency, + LogicalDatastoreType.OPERATIONAL, ContextsBuilder.class)); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactoryProvider.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactoryProvider.java new file mode 100644 index 000000000..e6794ed38 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/ContextsReaderFactoryProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.context.util; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.google.inject.name.Named; +import io.fd.honeycomb.translate.read.ReaderFactory; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; + + +public class ContextsReaderFactoryProvider implements Provider<ReaderFactory> { + + @Inject + @Named("honeycomb-context") + private DataBroker contextDataBroker; + + @Override + public ReaderFactory get() { + return new ContextsReaderFactory(contextDataBroker); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/EidMappingContext.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/EidMappingContext.java new file mode 100644 index 000000000..8501a42f4 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/context/util/EidMappingContext.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.context.util; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +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.rev161214.MappingId; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class allowing {@link MappingId} to {@link Eid} mapping + */ +public class EidMappingContext implements EidTranslator { + + private static final Logger LOG = LoggerFactory.getLogger(EidMappingContext.class); + 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 remoteEid 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.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid remoteEid, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + checkState(read.isPresent(), "Mapping for eid: %s is not present. But should be", remoteEid); + + return read.get().getMapping() + .stream() + //cannot split to map + filtering,because its collecting mappings,not eid's + .filter(mapping -> compareEids(mapping.getEid(), remoteEid)) + .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.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + //don't create artificial name as naming context, to not create reference to some artificial(in vpp non-existing)eid + checkState(read.isPresent(), "Mapping for eid: %s is not present. But should be", eid); + + return read.get().getMapping().stream() + .filter(mapping -> 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.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + return read.isPresent() && + read.get().getMapping() + .stream() + .anyMatch(mapping -> compareEids(mapping.getEid(), eid)); + } + + /** + * 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.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid eid, + @Nonnull final MappingContext mappingContext) { + final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class)); + + return read.isPresent() && + read.get().getMapping() + .stream() + .anyMatch(mapping -> compareEids(mapping.getEid(), eid)); + } + + + /** + * 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.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid eid, + final MappingContext mappingContext) { + + final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(index); + 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.rev161214.dp.subtable.grouping.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.rev161214.dp.subtable.grouping.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.rev161214.dp.subtable.grouping.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 read.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/hc2vpp/lisp/translate/read/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/AdjacencyCustomizer.java new file mode 100755 index 000000000..710bb8d1c --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/AdjacencyCustomizer.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.hc2vpp.lisp.translate.read; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.MappingContext; +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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGet; +import io.fd.vpp.jvpp.core.dto.LispAdjacenciesGetReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import io.fd.vpp.jvpp.core.types.LispAdjacency; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPair; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.adjacencies.identification.context.rev160801.adjacencies.identification.context.attributes.adjacencies.identification.contexts.adjacencies.identification.mappings.mapping.EidIdentificatorPairBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.AdjacenciesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AdjacencyCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<Adjacency, AdjacencyKey, AdjacencyBuilder>, JvppReplyConsumer, EidTranslator { + + private final DumpCacheManager<LispAdjacenciesGetReply, AdjacencyDumpParams> dumpCacheManager; + private final AdjacenciesMappingContext adjacenciesMappingContext; + private final EidPairProducer eidPairProducer; + + + public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { + super(futureJvpp); + dumpCacheManager = new DumpCacheManager.DumpCacheManagerBuilder<LispAdjacenciesGetReply, AdjacencyDumpParams>() + .withExecutor(createExecutor()) + .build(); + + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); + this.eidPairProducer = new EidPairProducer(localMappingContext, remoteMappingContext); + } + + @Nonnull + @Override + public List<AdjacencyKey> getAllIds(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final ReadContext context) throws ReadFailedException { + + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + final Optional<LispAdjacenciesGetReply> optionalDump = + dumpCacheManager.getDump(id, context.getModificationCache(), new AdjacencyDumpParams(vni)); + + + if (optionalDump.isPresent()) { + return Arrays.stream(optionalDump.get().adjacencies) + .map(lispAdjacency -> eidPairProducer.createPair(lispAdjacency, vni, context.getMappingContext())) + .map(pair -> adjacenciesMappingContext + .getAdjacencyId(pair.getLocalEidId().getValue(), pair.getRemoteEidId().getValue(), + context.getMappingContext())) + .map(AdjacencyKey::new) + .collect(Collectors.toList()); + } + + //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 { + + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + final Optional<LispAdjacenciesGetReply> optionalDump = dumpCacheManager + .getDump(id, ctx.getModificationCache(), new AdjacencyDumpParams(vni)); + + if (!optionalDump.isPresent() || optionalDump.get().adjacencies.length == 0) { + return; + } + + final String currentAdjacencyId = id.firstKeyOf(Adjacency.class).getId(); + final EidIdentificatorPair currentAdjacencyIdentificationPair = + adjacenciesMappingContext.getEidPair(currentAdjacencyId, ctx.getMappingContext()); + + final LispAdjacency currentAdjacency = Arrays.stream(optionalDump.get().adjacencies) + .filter(lispAdjacency -> Objects.equals(currentAdjacencyIdentificationPair, + eidPairProducer.createPair(lispAdjacency, vni, ctx.getMappingContext()))) + .collect(RWUtils.singleItemCollector()); + + builder.setId(currentAdjacencyId) + .setKey(new AdjacencyKey(currentAdjacencyId)) + .setLocalEid(getArrayAsLocalEid( + MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.leid, vni)) + .setRemoteEid(getArrayAsRemoteEid( + MappingsDumpParams.EidType.valueOf(currentAdjacency.eidType), currentAdjacency.reid, vni)); + } + + private EntityDumpExecutor<LispAdjacenciesGetReply, AdjacencyDumpParams> createExecutor() { + return (final InstanceIdentifier<?> identifier, final AdjacencyDumpParams params) -> { + checkNotNull(params, "Dump parameters cannot be null"); + + final LispAdjacenciesGet request = new LispAdjacenciesGet(); + request.vni = params.getVni(); + + return getReplyForRead(getFutureJVpp().lispAdjacenciesGet(request).toCompletableFuture(), identifier); + }; + } + + private class EidPairProducer implements EidTranslator { + + private final EidMappingContext localMappingContext; + private final EidMappingContext remoteMappingContext; + + public EidPairProducer(final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext) { + this.localMappingContext = checkNotNull(localMappingContext, "Local mapping context cannot be null"); + this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mapping context cannot be null"); + } + + public EidIdentificatorPair createPair(final LispAdjacency data, final int vni, + final MappingContext mappingContext) { + return new EidIdentificatorPairBuilder() + .setLocalEidId(new MappingId(localMappingContext.getId(getArrayAsEidLocal( + MappingsDumpParams.EidType.valueOf(data.eidType), data.leid, vni), mappingContext))) + .setRemoteEidId(new MappingId(remoteMappingContext.getId(getArrayAsEidLocal( + MappingsDumpParams.EidType.valueOf(data.eidType), data.reid, vni), mappingContext))) + .build(); + } + } + + private static final class AdjacencyDumpParams { + + private final int vni; + + AdjacencyDumpParams(final int vni) { + this.vni = vni; + } + + public int getVni() { + return this.vni; + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/BridgeDomainSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/BridgeDomainSubtableCustomizer.java new file mode 100644 index 000000000..1e6ce3ab0 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/BridgeDomainSubtableCustomizer.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams; +import io.fd.hc2vpp.lisp.translate.read.trait.SubtableReader; +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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtableBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BridgeDomainSubtableCustomizer extends FutureJVppCustomizer implements + ReaderCustomizer<BridgeDomainSubtable, BridgeDomainSubtableBuilder>, SubtableReader { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainSubtableCustomizer.class); + + private final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> + dumpManager; + private final NamingContext bridgeDomainContext; + + public BridgeDomainSubtableCustomizer(@Nonnull final FutureJVppCore futureJvppCore, + @Nonnull final NamingContext bridgeDomainContext) { + super(futureJvppCore); + dumpManager = + new DumpCacheManagerBuilder<LispEidTableMapDetailsReplyDump, SubtableDumpParams>() + .withExecutor(createExecutor(futureJvppCore)) + .build(); + this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + } + + @Nonnull + @Override + public BridgeDomainSubtableBuilder getBuilder(@Nonnull final InstanceIdentifier<BridgeDomainSubtable> id) { + return new BridgeDomainSubtableBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomainSubtable> id, + @Nonnull final BridgeDomainSubtableBuilder builder, + @Nonnull final ReadContext ctx) throws ReadFailedException { + final int vni = checkNotNull(id.firstKeyOf(VniTable.class), "Cannot find parent VNI Table") + .getVirtualNetworkIdentifier().intValue(); + LOG.debug("Read attributes for id {}", id); + //dumps only L2(bridge domains) + final Optional<LispEidTableMapDetailsReplyDump> reply = + dumpManager.getDump(id, ctx.getModificationCache(), L2_PARAMS); + + if (!reply.isPresent() || reply.get().lispEidTableMapDetails.isEmpty()) { + return; + } + + // Single item collector cant be used in this case,because bridge-domain-subtable is container + // so read is invoked every time parent is defined + final List<LispEidTableMapDetails> + details = reply.get().lispEidTableMapDetails.stream().filter(a -> a.vni == vni) + .collect(Collectors.toList()); + if (details.size() == 1) { + final LispEidTableMapDetails detail = details.get(0); + builder.setBridgeDomainRef(bridgeDomainContext.getName(detail.dpTable, ctx.getMappingContext())); + LOG.debug("Attributes for {} successfully loaded", id); + } + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, + @Nonnull final BridgeDomainSubtable readValue) { + ((VniTableBuilder) parentBuilder).setBridgeDomainSubtable(readValue); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/InterfaceCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/InterfaceCustomizer.java new file mode 100755 index 000000000..c4bf0b865 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/InterfaceCustomizer.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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.hc2vpp.lisp.translate.read.dump.executor.params.LocatorDumpParams; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.LocatorDumpParams.LocatorDumpParamsBuilder; +import io.fd.hc2vpp.lisp.translate.read.trait.LocatorReader; +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.util.read.cache.DumpCacheManager; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.LispLocatorDetails; +import io.fd.vpp.jvpp.core.dto.LispLocatorDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.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; + + +/** + * Customizer for reading {@code Interface}<br> Currently not supported by jvpp + */ +public class InterfaceCustomizer + extends FutureJVppCustomizer + implements ListReaderCustomizer<Interface, InterfaceKey, InterfaceBuilder>, LocatorReader { + + 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(createLocatorDumpExecutor(futureJvpp)) + .build(); + } + + @Override + public InterfaceBuilder getBuilder(InstanceIdentifier<Interface> id) { + return new InterfaceBuilder(); + } + + @Override + public void readCurrentAttributes(InstanceIdentifier<Interface> id, InterfaceBuilder builder, ReadContext ctx) + throws ReadFailedException { + + final String locatorSetName = id.firstKeyOf(LocatorSet.class).getName(); + final String referencedInterfaceName = id.firstKeyOf(Interface.class).getInterfaceRef(); + + checkState(interfaceContext.containsIndex(referencedInterfaceName, ctx.getMappingContext()), + "No interface mapping for name %s", referencedInterfaceName); + checkState(locatorSetContext.containsIndex(locatorSetName, ctx.getMappingContext()), + "No locator set mapping for name %s", locatorSetName); + + final int locatorSetIndexIndex = locatorSetContext.getIndex(locatorSetName, ctx.getMappingContext()); + final int referencedInterfaceIndex = + interfaceContext.getIndex(referencedInterfaceName, ctx.getMappingContext()); + + final LocatorDumpParams params = + new LocatorDumpParamsBuilder().setLocatorSetIndex(locatorSetIndexIndex).build(); + + final Optional<LispLocatorDetailsReplyDump> reply = + dumpCacheManager.getDump(id, ctx.getModificationCache(), params); + + if (!reply.isPresent() || reply.get().lispLocatorDetails.isEmpty()) { + return; + } + + final LispLocatorDetails details = reply.get() + .lispLocatorDetails + .stream() + .filter(a -> a.swIfIndex == referencedInterfaceIndex) + .collect(RWUtils.singleItemCollector()); + + final String interfaceRef = interfaceContext.getName(details.swIfIndex, ctx.getMappingContext()); + + builder.setPriority(Byte.valueOf(details.priority).shortValue()); + builder.setWeight(Byte.valueOf(details.weight).shortValue()); + builder.setInterfaceRef(interfaceRef); + builder.setKey(new InterfaceKey(interfaceRef)); + } + + @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 LocatorDumpParamsBuilder() + .setLocatorSetIndex(locatorSetContext.getIndex(name, context.getMappingContext())).build(); + + final Optional<LispLocatorDetailsReplyDump> reply = + dumpCacheManager.getDump(id, context.getModificationCache(), params); + + if (!reply.isPresent() || reply.get().lispLocatorDetails.isEmpty()) { + return Collections.emptyList(); + } + + return reply.get() + .lispLocatorDetails + .stream() + .map(a -> new InterfaceKey(interfaceContext.getName(a.swIfIndex, context.getMappingContext()))) + .collect(Collectors.toList()); + } + + @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/hc2vpp/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/ItrRemoteLocatorSetCustomizer.java new file mode 100644 index 000000000..eb078fe68 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/ItrRemoteLocatorSetCustomizer.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.hc2vpp.lisp.translate.read; + + +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispGetMapRequestItrRlocs; +import io.fd.vpp.jvpp.core.dto.LispGetMapRequestItrRlocsReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.itr.remote.locator.sets.grouping.ItrRemoteLocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.itr.remote.locator.sets.grouping.ItrRemoteLocatorSetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureDataBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class ItrRemoteLocatorSetCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer<ItrRemoteLocatorSet, ItrRemoteLocatorSetBuilder>, ByteDataTranslator, + JvppReplyConsumer { + + private final DumpCacheManager<LispGetMapRequestItrRlocsReply, Void> dumpCacheManager; + + public ItrRemoteLocatorSetCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + dumpCacheManager = new DumpCacheManagerBuilder<LispGetMapRequestItrRlocsReply, Void>() + .withExecutor(((identifier, params) -> getReplyForRead( + futureJVppCore.lispGetMapRequestItrRlocs(new LispGetMapRequestItrRlocs()).toCompletableFuture(), + identifier))) + .build(); + } + + @Nonnull + @Override + public ItrRemoteLocatorSetBuilder getBuilder(@Nonnull final InstanceIdentifier<ItrRemoteLocatorSet> id) { + return new ItrRemoteLocatorSetBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<ItrRemoteLocatorSet> id, + @Nonnull final ItrRemoteLocatorSetBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + + final Optional<LispGetMapRequestItrRlocsReply> reply = + dumpCacheManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); + if (!reply.isPresent() || reply.get().locatorSetName == null) { + return; + } + + builder.setRemoteLocatorSetName(toString(reply.get().locatorSetName)); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, + @Nonnull final ItrRemoteLocatorSet readValue) { + ((LispFeatureDataBuilder) parentBuilder).setItrRemoteLocatorSet(readValue); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LispStateCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LispStateCustomizer.java new file mode 100755 index 000000000..7f0d4c884 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LispStateCustomizer.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + + +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ShowLispStatus; +import io.fd.vpp.jvpp.core.dto.ShowLispStatusReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispStateBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * Customizer that handles reads of {@code LispState} + */ +public class LispStateCustomizer extends FutureJVppCustomizer + implements InitializingReaderCustomizer<LispState, LispStateBuilder>, JvppReplyConsumer, ByteDataTranslator { + + 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 = getReply(getFutureJVpp().showLispStatus(new ShowLispStatus()).toCompletableFuture()); + } catch (TimeoutException | VppBaseCallException e) { + throw new ReadFailedException(id, e); + } + + builder.setEnable(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"); + } + + @Override + public Initialized<Lisp> init( + @Nonnull final InstanceIdentifier<LispState> id, @Nonnull final LispState readValue, + @Nonnull final ReadContext ctx) { + return Initialized.create(InstanceIdentifier.create(Lisp.class), + + // 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) + new LispBuilder() + .setEnable(readValue.isEnable()) + .setLispFeatureData(readValue.getLispFeatureData()) + .build()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocalMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocalMappingCustomizer.java new file mode 100755 index 000000000..06d56c185 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocalMappingCustomizer.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.valueOf; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.FilterType; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.MappingsDumpParamsBuilder; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.QuantityType; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.hc2vpp.lisp.translate.read.trait.MappingReader; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +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.util.read.cache.DumpCacheManager; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.lisp.address.Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.LocalMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +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>, EidTranslator, + MappingReader { + + private static final Logger LOG = LoggerFactory.getLogger(LocalMappingCustomizer.class); + + private final DumpCacheManager<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; + 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.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableDetailsReplyDump, MappingsDumpParams>() + .withExecutor(createMappingDumpExecutor(futureJvpp)) + .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); + final Optional<LispEidTableDetailsReplyDump> replyOptional = + dumpManager.getDump(id, ctx.getModificationCache(), dumpParams); + + if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { + return; + } + + LispEidTableDetails details = replyOptional.get().lispEidTableDetails.stream() + .filter(subtableFilterForLocalMappings(id)) + .filter(detail -> compareAddresses(eid.getAddress(), getAddressFromDumpDetail(detail))) + .collect(RWUtils.singleItemCollector()); + + //in case of local mappings,locator_set_index stands for interface index + checkState(locatorSetContext.containsName(details.locatorSetIndex, ctx.getMappingContext()), + "No Locator Set name found for index %s", details.locatorSetIndex); + 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, details.vni)); + } + + private Address getAddressFromDumpDetail(final LispEidTableDetails detail) { + return getArrayAsEidLocal(valueOf(detail.eidType), detail.eid, detail.vni).getAddress(); + } + + @Override + public List<LocalMappingKey> getAllIds(InstanceIdentifier<LocalMapping> id, ReadContext context) + throws ReadFailedException { + + checkState(id.firstKeyOf(VniTable.class) != null, "Parent VNI table not specified"); + final long vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier(); + + if (vni == 0) { + // ignoring default vni mapping + // its not relevant for us and we also don't store mapping for such eid's + // such mapping is used to create helper local mappings to process remote ones + return Collections.emptyList(); + } + + //request for all local mappings + final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder() + .setFilter(FilterType.LOCAL) + .setEidSet(QuantityType.ALL) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + final Optional<LispEidTableDetailsReplyDump> replyOptional = + dumpManager.getDump(id, context.getModificationCache(), dumpParams); + + if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { + return Collections.emptyList(); + } + + + return replyOptional.get().lispEidTableDetails.stream() + .filter(a -> a.vni == vni) + .filter(subtableFilterForLocalMappings(id)) + .map(detail -> getArrayAsEidLocal(valueOf(detail.eidType), detail.eid, detail.vni)) + .map(localEid -> localMappingContext.getId(localEid, context.getMappingContext())) + .map(MappingId::new) + .map(LocalMappingKey::new) + .collect(Collectors.toList()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<LocalMapping> readData) { + ((LocalMappingsBuilder) builder).setLocalMapping(readData); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocatorSetCustomizer.java new file mode 100755 index 000000000..9b2ec5ac6 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/LocatorSetCustomizer.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.translate.read.trait.LocatorSetReader; +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.read.cache.DumpCacheManager; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.LispLocatorSetDetails; +import io.fd.vpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.rev161214.locator.sets.grouping.LocatorSetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LocatorSetCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<LocatorSet, LocatorSetKey, LocatorSetBuilder>, ByteDataTranslator, + LocatorSetReader { + + private static final Logger LOG = LoggerFactory.getLogger(LocatorSetCustomizer.class); + + private final DumpCacheManager<LispLocatorSetDetailsReplyDump, Void> dumpManager; + private final NamingContext locatorSetContext; + + public LocatorSetCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext locatorSetContext) { + super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator Set mapping context cannot be null"); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorSetDetailsReplyDump, Void>() + .withExecutor(createExecutor(futureJvpp)) + .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); + + final Optional<LispLocatorSetDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); + + if (!dumpOptional.isPresent() || dumpOptional.get().lispLocatorSetDetails.isEmpty()) { + return; + } + + String keyName = id.firstKeyOf(LocatorSet.class).getName(); + LispLocatorSetDetailsReplyDump dump = dumpOptional.get(); + + java.util.Optional<LispLocatorSetDetails> details = dump.lispLocatorSetDetails.stream() + .filter(n -> keyName.equals(toString(n.lsName))) + .findFirst(); + + if (details.isPresent()) { + final String name = toString(details.get().lsName); + + 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); + + final Optional<LispLocatorSetDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); + + if (!dumpOptional.isPresent() || dumpOptional.get().lispLocatorSetDetails.isEmpty()) { + return Collections.emptyList(); + } + + return dumpOptional.get().lispLocatorSetDetails.stream() + .map(set -> { + + final String locatorSetName = toString(set.lsName); + //creates mapping for existing locator-set(if it is'nt already existing one) + if (!locatorSetContext.containsIndex(locatorSetName, context.getMappingContext())) { + locatorSetContext.addName(set.lsIndex, locatorSetName, context.getMappingContext()); + } + + LOG.trace("Locator Set with name: {}, VPP name: {} and index: {} found in VPP", + locatorSetContext.getName(set.lsIndex, context.getMappingContext()), + locatorSetName, + set.lsIndex); + + return set; + }) + .map(set -> new LocatorSetKey(toString(set.lsName))) + .collect(Collectors.toList()); + } + + @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/hc2vpp/lisp/translate/read/MapResolverCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/MapResolverCustomizer.java new file mode 100755 index 000000000..cc73d7751 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/MapResolverCustomizer.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +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.util.read.cache.DumpCacheManager; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispMapResolverDetails; +import io.fd.vpp.jvpp.core.dto.LispMapResolverDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispMapResolverDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.MapResolversBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.map.resolvers.MapResolverBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MapResolverCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<MapResolver, MapResolverKey, MapResolverBuilder>, AddressTranslator, + JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(MapResolverCustomizer.class); + + private final DumpCacheManager<LispMapResolverDetailsReplyDump, Void> dumpManager; + + public MapResolverCustomizer(FutureJVppCore futureJvpp) { + super(futureJvpp); + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispMapResolverDetailsReplyDump, Void>() + .withExecutor((identifier, params) -> getReplyForRead( + futureJvpp.lispMapResolverDump(new LispMapResolverDump()).toCompletableFuture(), + identifier)) + .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..."); + + final Optional<LispMapResolverDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); + + if (!dumpOptional.isPresent() || dumpOptional.get().lispMapResolverDetails.isEmpty()) { + LOG.warn("No data dumped"); + return; + } + + final MapResolverKey key = id.firstKeyOf(MapResolver.class); + final LispMapResolverDetails mapResolverDetails = + dumpOptional.get().lispMapResolverDetails.stream() + .filter(a -> addressesEqual(key.getIpAddress(), + arrayToIpAddressReversed(byteToBoolean(a.isIpv6), a.ipAddress))) + .collect(RWUtils.singleItemCollector()); + + builder.setKey(key); + builder.setIpAddress( + arrayToIpAddress(byteToBoolean(mapResolverDetails.isIpv6), mapResolverDetails.ipAddress)); + } + + // safest way to compare addresses - prevents returning false while using different types from hierarchy + // Ex. Key for MapResolver contains Ipv4Address as value but we translate addresses from binary data to Ipv4AddressNoZone + private boolean addressesEqual(final IpAddress left, final IpAddress right) { + return Arrays.equals(left.getValue(), right.getValue()); + } + + @Override + public List<MapResolverKey> getAllIds(InstanceIdentifier<MapResolver> id, ReadContext context) + throws ReadFailedException { + LOG.debug("Dumping MapResolver..."); + + final Optional<LispMapResolverDetailsReplyDump> dumpOptional = + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); + + if (!dumpOptional.isPresent() || dumpOptional.get().lispMapResolverDetails.isEmpty()) { + return Collections.emptyList(); + } + + return dumpOptional.get().lispMapResolverDetails.stream() + .map(resolver -> new MapResolverKey( + arrayToIpAddressReversed(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/hc2vpp/lisp/translate/read/PitrCfgCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/PitrCfgCustomizer.java new file mode 100755 index 000000000..8f8a1474f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/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.hc2vpp.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.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import java.util.concurrent.TimeoutException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.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 io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.ShowLispPitr; +import io.fd.vpp.jvpp.core.dto.ShowLispPitrReply; +import io.fd.vpp.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>, ByteDataTranslator, JvppReplyConsumer { + + 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(toString(reply.locatorSetName)); + LOG.debug("Reading status for Lisp Pitr node {} successfull", id); + } + + @Override + public void merge(Builder<? extends DataObject> parentBuilder, PitrCfg readValue) { + ((LispFeatureDataBuilder) 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/hc2vpp/lisp/translate/read/RemoteMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/RemoteMappingCustomizer.java new file mode 100755 index 000000000..2a36a2576 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/RemoteMappingCustomizer.java @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.valueOf; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.FilterType; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.MappingsDumpParamsBuilder; +import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MapReplyAction.NoAction; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.LocatorDumpParams; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.LocatorDumpParams.LocatorDumpParamsBuilder; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.QuantityType; +import io.fd.hc2vpp.lisp.translate.read.trait.LocatorReader; +import io.fd.hc2vpp.lisp.translate.read.trait.MappingReader; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.ModificationCache; +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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.IdentifierCacheKeyFactory; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispLocatorDetails; +import io.fd.vpp.jvpp.core.dto.LispLocatorDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MapReplyAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.RemoteMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.EidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.NegativeMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.PositiveMappingBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.negative.mapping.MapReplyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.RlocsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.LocatorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.LocatorKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Customizer for reading {@code RemoteMapping}<br> + */ +public class RemoteMappingCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<RemoteMapping, RemoteMappingKey, RemoteMappingBuilder>, + EidTranslator, AddressTranslator, ByteDataTranslator, MappingReader, LocatorReader { + + private static final Logger LOG = LoggerFactory.getLogger(RemoteMappingCustomizer.class); + + private final DumpCacheManager<LispEidTableDetailsReplyDump, MappingsDumpParams> dumpManager; + private final DumpCacheManager<LispLocatorDetailsReplyDump, LocatorDumpParams> locatorsDumpManager; + private final NamingContext locatorSetContext; + private final EidMappingContext remoteMappingContext; + + public RemoteMappingCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final EidMappingContext remoteMappingContext) { + super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator sets context not present"); + this.remoteMappingContext = checkNotNull(remoteMappingContext, "Remote mappings not present"); + // this one should have default scope == RemoteMapping + this.dumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableDetailsReplyDump, MappingsDumpParams>() + .withExecutor(createMappingDumpExecutor(futureJvpp)) + .build(); + + // cache key needs to have locator set scope to not mix with cached data + this.locatorsDumpManager = + new DumpCacheManager.DumpCacheManagerBuilder<LispLocatorDetailsReplyDump, LocatorDumpParams>() + .withExecutor(createLocatorDumpExecutor(futureJvpp)) + .withCacheKeyFactory(new IdentifierCacheKeyFactory(ImmutableSet.of(LocatorSet.class))) + .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(getEidType(eid)) + .setEid(getEidAsByteArray(eid)) + .setPrefixLength(getPrefixLength(eid)) + .setFilter(FilterType.REMOTE) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + final Optional<LispEidTableDetailsReplyDump> replyOptional = + dumpManager.getDump(id, ctx.getModificationCache(), dumpParams); + + if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { + return; + } + + LOG.debug("Valid dump loaded"); + + LispEidTableDetails details = replyOptional.get().lispEidTableDetails.stream() + .filter(subtableFilterForRemoteMappings(id)) + .filter(a -> compareAddresses(eid.getAddress(), + getArrayAsEidLocal(valueOf(a.eidType), a.eid, a.vni).getAddress())) + .collect( + RWUtils.singleItemCollector()); + + builder.setEid(getArrayAsEidRemote(valueOf(details.eidType), details.eid, details.vni)); + builder.setKey(new RemoteMappingKey(new MappingId(id.firstKeyOf(RemoteMapping.class).getId()))); + builder.setTtl(resolveTtl(details.ttl)); + builder.setAuthoritative( + new RemoteMapping.Authoritative(byteToBoolean(details.authoritative))); + resolveMappings(id, builder, details, ctx.getModificationCache(), ctx.getMappingContext()); + } + + //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"); + final int vni = id.firstKeyOf(VniTable.class).getVirtualNetworkIdentifier().intValue(); + + if (vni == 0) { + // ignoring default vni mapping + // it's not relevant for us and we also don't store mapping for such eid's + // such mapping is used to create helper local mappings to process remote ones + return Collections.emptyList(); + } + + //requesting all remote with specific vni + final MappingsDumpParams dumpParams = new MappingsDumpParamsBuilder() + .setEidSet(QuantityType.ALL) + .setFilter(FilterType.REMOTE) + .build(); + + LOG.debug("Dumping data for LocalMappings(id={})", id); + final Optional<LispEidTableDetailsReplyDump> replyOptional = + dumpManager.getDump(id, context.getModificationCache(), dumpParams); + + if (!replyOptional.isPresent() || replyOptional.get().lispEidTableDetails.isEmpty()) { + return Collections.emptyList(); + } + + return replyOptional.get() + .lispEidTableDetails + .stream() + .filter(a -> a.vni == vni) + .filter(subtableFilterForRemoteMappings(id)) + .map(detail -> getArrayAsEidRemote(valueOf(detail.eidType), detail.eid, detail.vni)) + .map(remoteEid -> remoteMappingContext.getId(remoteEid, context.getMappingContext())) + .map(MappingId::new) + .map(RemoteMappingKey::new) + .collect(Collectors.toList()); + } + + @Override + public void merge(Builder<? extends DataObject> builder, List<RemoteMapping> readData) { + ((RemoteMappingsBuilder) builder).setRemoteMapping(readData); + } + + private void resolveMappings(final InstanceIdentifier id, final RemoteMappingBuilder builder, + final LispEidTableDetails details, + final ModificationCache cache, + final MappingContext mappingContext) throws ReadFailedException { + + if (details.action != 0) { + // in this case ,negative action was defined + bindNegativeMapping(builder, MapReplyAction.forValue(details.action)); + } else { + // in this case, there is no clear determination whether negative action with NO_ACTION(value == 0) was defined, + // or if its default value and remote locators, are defined, so only chance to determine so, is to dump locators for this mapping + + // cache key needs to have locator set scope to not mix with cached data + final Optional<LispLocatorDetailsReplyDump> reply; + + // this will serve to achieve that locators have locator set scope + final InstanceIdentifier<Interface> locatorIfaceIdentifier = InstanceIdentifier.create(LocatorSets.class) + .child(LocatorSet.class, + new LocatorSetKey(locatorSetContext.getName(details.locatorSetIndex, mappingContext))) + .child(Interface.class); + try { + reply = locatorsDumpManager.getDump(locatorIfaceIdentifier, cache, + new LocatorDumpParamsBuilder().setLocatorSetIndex(details.locatorSetIndex).build()); + } catch (ReadFailedException e) { + throw new ReadFailedException(id, + new IllegalStateException("Unable to resolve Positive/Negative mapping for RemoteMapping", + e.getCause())); + } + + if (!reply.isPresent() || reply.get().lispLocatorDetails.isEmpty()) { + // no remote locators exist, therefore there was NO_ACTION defined + bindNegativeMapping(builder, NoAction); + } else { + // bind remote locators + bindPositiveMapping(builder, reply.get()); + } + } + } + + private void bindNegativeMapping(final RemoteMappingBuilder builder, + final MapReplyAction action) { + builder.setLocatorList( + new NegativeMappingBuilder().setMapReply(new MapReplyBuilder().setMapReplyAction(action).build()) + .build()); + } + + private void bindPositiveMapping(final RemoteMappingBuilder builder, final LispLocatorDetailsReplyDump reply) { + builder.setLocatorList( + new PositiveMappingBuilder() + .setRlocs( + new RlocsBuilder() + .setLocator(reply + .lispLocatorDetails + .stream() + .map(this::detailsToLocator) + .collect(Collectors.toList())) + .build() + ) + .build() + ); + } + + private Locator detailsToLocator(final LispLocatorDetails details) { + final IpAddress address = arrayToIpAddressReversed(byteToBoolean(details.isIpv6), details.ipAddress); + return new LocatorBuilder() + .setAddress(address) + .setKey(new LocatorKey(address)) + .setPriority((short) details.priority) + .setWeight((short) details.weight) + .build(); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VniTableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VniTableCustomizer.java new file mode 100755 index 000000000..c0680a7c6 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VniTableCustomizer.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkState; +import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS; + +import com.google.common.base.Optional; +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.util.read.cache.DumpCacheManager; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispEidTableVniDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableVniDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispEidTableVniDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.rev161214.eid.table.grouping.EidTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handles the reads of {@link VniTable} nodes + */ +public class VniTableCustomizer extends FutureJVppCustomizer + implements ListReaderCustomizer<VniTable, VniTableKey, VniTableBuilder>, JvppReplyConsumer { + + private static final Logger LOG = LoggerFactory.getLogger(VniTableCustomizer.class); + + private final DumpCacheManager<LispEidTableVniDetailsReplyDump, Void> dumpManager; + + public VniTableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<LispEidTableVniDetailsReplyDump, Void>() + .withExecutor(((identifier, params) -> getReplyForRead( + futureJvpp.lispEidTableVniDump(new LispEidTableVniDump()).toCompletableFuture(), identifier))) + .build(); + } + + private static VniTableKey detailsToKey(final LispEidTableVniDetails 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..."); + + final Optional<LispEidTableVniDetailsReplyDump> optionalReply = + dumpManager.getDump(id, context.getModificationCache(), NO_PARAMS); + + if (!optionalReply.isPresent() || optionalReply.get().lispEidTableVniDetails.isEmpty()) { + return Collections.emptyList(); + } + + return optionalReply.get().lispEidTableVniDetails.stream().map(VniTableCustomizer::detailsToKey) + .collect(Collectors.toList()); + } + + @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()); + + final Optional<LispEidTableVniDetailsReplyDump> optionalReply = + dumpManager.getDump(id, ctx.getModificationCache(), NO_PARAMS); + + if (!optionalReply.isPresent() || optionalReply.get().lispEidTableVniDetails.isEmpty()) { + return; + } + + //transforming right away to single detail(specific request should do the magic) + final LispEidTableVniDetails details = optionalReply.get() + .lispEidTableVniDetails + .stream() + .filter(a -> a.vni == key.getVirtualNetworkIdentifier().intValue()) + .collect(RWUtils.singleItemCollector()); + + builder.setVirtualNetworkIdentifier((long) details.vni); + builder.setKey(new VniTableKey(Long.valueOf(details.vni))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VrfSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VrfSubtableCustomizer.java new file mode 100644 index 000000000..0a73dc3f2 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/VrfSubtableCustomizer.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams; +import io.fd.hc2vpp.lisp.translate.read.trait.SubtableReader; +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.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +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.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtableBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VrfSubtableCustomizer extends FutureJVppCustomizer + implements ReaderCustomizer<VrfSubtable, VrfSubtableBuilder>, SubtableReader { + + private static final Logger LOG = LoggerFactory.getLogger(VrfSubtableCustomizer.class); + + private final DumpCacheManager<LispEidTableMapDetailsReplyDump, SubtableDumpParams> dumpManager; + + public VrfSubtableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + dumpManager = new DumpCacheManagerBuilder<LispEidTableMapDetailsReplyDump, SubtableDumpParams>() + .withExecutor(createExecutor(futureJvpp)) + .build(); + } + + @Nonnull + @Override + public VrfSubtableBuilder getBuilder(@Nonnull final InstanceIdentifier<VrfSubtable> id) { + return new VrfSubtableBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VrfSubtable> id, + @Nonnull final VrfSubtableBuilder builder, @Nonnull final ReadContext ctx) + throws ReadFailedException { + LOG.debug("Read attributes for {}", id); + final int vni = checkNotNull(id.firstKeyOf(VniTable.class), "Cannot find parent VNI Table") + .getVirtualNetworkIdentifier().intValue(); + + final Optional<LispEidTableMapDetailsReplyDump> reply = dumpManager.getDump(id, ctx.getModificationCache(), L3_PARAMS); + + if (!reply.isPresent() || reply.get().lispEidTableMapDetails.isEmpty()) { + return; + } + + // Single item collector cant be used in this case,because vrf-subtable is container + // so read is invoked every time parent is defined + final List<LispEidTableMapDetails> details = + reply.get().lispEidTableMapDetails.stream().filter(a -> a.vni == vni) + .collect(Collectors.toList()); + if (details.size() == 1) { + final LispEidTableMapDetails detail = details.get(0); + builder.setTableId(Integer.valueOf(detail.dpTable).longValue()); + + LOG.debug("Attributes for {} successfully loaded", id); + } + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder, + @Nonnull final VrfSubtable readValue) { + ((VniTableBuilder) parentBuilder).setVrfSubtable(readValue); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/LocatorDumpParams.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/LocatorDumpParams.java new file mode 100644 index 000000000..08be4f62d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/LocatorDumpParams.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.dump.executor.params; + +/** + * Params for dumping locators + */ +public final class LocatorDumpParams { + + private final int locatorSetIndex; + + private LocatorDumpParams(LocatorDumpParamsBuilder builder) { + this.locatorSetIndex = builder.locatorSetIndex; + } + + public int getLocatorSetIndex() { + return locatorSetIndex; + } + + public static final class LocatorDumpParamsBuilder { + + private int locatorSetIndex; + + public LocatorDumpParamsBuilder setLocatorSetIndex(final int locatorSetIndex) { + this.locatorSetIndex = locatorSetIndex; + return this; + } + + public LocatorDumpParams build() { + return new LocatorDumpParams(this); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/MappingsDumpParams.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/MappingsDumpParams.java new file mode 100755 index 000000000..6b422f503 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/MappingsDumpParams.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.dump.executor.params; + +import java.util.Arrays; + +/** + * Parameters for executing dump of mappings + */ +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/hc2vpp/lisp/translate/read/dump/executor/params/SubtableDumpParams.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/SubtableDumpParams.java new file mode 100644 index 000000000..1c034c14b --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/dump/executor/params/SubtableDumpParams.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.hc2vpp.lisp.translate.read.dump.executor.params; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; + +/** + * Parameters for dumping {@link VrfSubtable}/{@link BridgeDomainSubtable} + */ +public final class SubtableDumpParams { + + private final byte isL2; + + private SubtableDumpParams(SubtableDumpParamsBuilder builder) { + this.isL2 = builder.isL2; + } + + public byte isL2() { + return isL2; + } + + @Override + public String toString() { + return "SubtableDumpParams{" + + "isL2=" + isL2 + + '}'; + } + + public enum MapLevel { + L2(1), + L3(0); + + private final int value; + + private MapLevel(final int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + public static final class SubtableDumpParamsBuilder { + + private byte isL2; + + public SubtableDumpParamsBuilder setL2(@Nonnull final MapLevel mapLevel) { + isL2 = Integer.valueOf(checkNotNull(mapLevel, "Cannot set null map level").getValue()).byteValue(); + return this; + } + + public SubtableDumpParams build() { + return new SubtableDumpParams(this); + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java new file mode 100644 index 000000000..fe6616ddf --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/AbstractLispReaderFactoryBase.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.factory; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispState; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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 NamingContext bridgeDomainContext; + 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"); + } + + protected AbstractLispReaderFactoryBase(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final NamingContext bridgeDomainContext, + @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.bridgeDomainContext = checkNotNull(bridgeDomainContext, + "Bridge domain 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/hc2vpp/lisp/translate/read/factory/EidTableReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/EidTableReaderFactory.java new file mode 100755 index 000000000..195b0a010 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/EidTableReaderFactory.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.factory; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.AdjacencyCustomizer; +import io.fd.hc2vpp.lisp.translate.read.BridgeDomainSubtableCustomizer; +import io.fd.hc2vpp.lisp.translate.read.LocalMappingCustomizer; +import io.fd.hc2vpp.lisp.translate.read.RemoteMappingCustomizer; +import io.fd.hc2vpp.lisp.translate.read.VniTableCustomizer; +import io.fd.hc2vpp.lisp.translate.read.VrfSubtableCustomizer; +import io.fd.honeycomb.translate.impl.read.GenericListReader; +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.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.Adjacencies; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.AdjacenciesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.LocalMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.LocalMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.RemoteMappingsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.negative.mapping.MapReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.Rlocs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.EidTableBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +/** + * Factory that produces {@code Reader} for {@code EidTable}<br> with all its inhired child readers + */ +final class EidTableReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + private final AdjacenciesMappingContext adjacenciesMappingContext; + + private EidTableReaderFactory(final InstanceIdentifier<LispState> lispStateId, + final FutureJVppCore vppApi, + final NamingContext interfaceContext, + final NamingContext locatorSetContext, + final NamingContext bridgeDomainContext, + final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext, + final AdjacenciesMappingContext adjacenciesMappingContext) { + super(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, localMappingContext, + remoteMappingContext); + this.adjacenciesMappingContext = checkNotNull(adjacenciesMappingContext, "Adjacencies context cannot be null"); + } + + public static EidTableReaderFactory newInstance(@Nonnull final InstanceIdentifier<LispState> lispStateId, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext locatorSetContext, + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { + return new EidTableReaderFactory(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, + localMappingContext, remoteMappingContext, adjacenciesMappingContext); + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + final InstanceIdentifier<EidTable> eidTableInstanceIdentifier = + lispStateId.child(LispFeatureData.class).child(EidTable.class); + final InstanceIdentifier<VniTable> vniTableInstanceIdentifier = + eidTableInstanceIdentifier.child(VniTable.class); + final InstanceIdentifier<VrfSubtable> vrfSubtable = vniTableInstanceIdentifier.child(VrfSubtable.class); + final InstanceIdentifier<BridgeDomainSubtable> bridgeDomainSubtable = + vniTableInstanceIdentifier.child(BridgeDomainSubtable.class); + + final InstanceIdentifier<LocalMappings> vrfTableLocalMappingsInstanceIdentifier = + vrfSubtable.child(LocalMappings.class); + final InstanceIdentifier<RemoteMappings> vrfTableRemoteMappingsInstanceIdentifier = + vrfSubtable.child(RemoteMappings.class); + final InstanceIdentifier<Adjacencies> vrfTableAdjacenciesInstanceIdentifier = + vrfSubtable.child(RemoteMappings.class).child(RemoteMapping.class).child(Adjacencies.class); + + final InstanceIdentifier<LocalMappings> bridgeDomainLocalMappingsInstanceIdentifier = + bridgeDomainSubtable.child(LocalMappings.class); + final InstanceIdentifier<RemoteMappings> bridgeDomainRemoteMappingsInstanceIdentifier = + bridgeDomainSubtable.child(RemoteMappings.class); + final InstanceIdentifier<Adjacencies> bridgeDomainAdjacenciesInstanceIdentifier = + bridgeDomainSubtable.child(RemoteMappings.class).child(RemoteMapping.class).child(Adjacencies.class); + + //EidTable + registry.addStructuralReader(eidTableInstanceIdentifier, EidTableBuilder.class); + //EidTable -> VniTable + registry.add(new GenericListReader<>(vniTableInstanceIdentifier, new VniTableCustomizer(vppApi))); + + //EidTable -> VniTable -> VrfSubtable + registry.add(new GenericReader<>(vrfSubtable, new VrfSubtableCustomizer(vppApi))); + + //EidTable -> VniTable -> BridgeDomainSubtable + registry.add(new GenericReader<>(bridgeDomainSubtable, + new BridgeDomainSubtableCustomizer(vppApi, bridgeDomainContext))); + + //EidTable -> VniTable -> VrfSubtable -> LocalMappings + registry.addStructuralReader(vrfTableLocalMappingsInstanceIdentifier, LocalMappingsBuilder.class); + //EidTable -> VniTable -> BridgeDomainSubtable -> LocalMappings + registry.addStructuralReader(bridgeDomainLocalMappingsInstanceIdentifier, LocalMappingsBuilder.class); + + final InstanceIdentifier<LocalMapping> localMappingSubtreeId = InstanceIdentifier.create(LocalMapping.class); + //EidTable -> VniTable -> VrfSubtable -> LocalMappings -> LocalMapping + registry.subtreeAdd(ImmutableSet.of(localMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class)), + new GenericListReader<>(vrfTableLocalMappingsInstanceIdentifier.child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, locatorSetContext, localMappingContext))); + + //EidTable -> VniTable -> BridgeDomainSubtable -> LocalMappings -> LocalMapping + registry.subtreeAdd(ImmutableSet.of(localMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class)), + new GenericListReader<>(bridgeDomainLocalMappingsInstanceIdentifier.child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, locatorSetContext, localMappingContext))); + + //EidTable -> VniTable -> VrfSubtable -> RemoteMappings + registry.addStructuralReader(vrfTableRemoteMappingsInstanceIdentifier, RemoteMappingsBuilder.class); + registry.addStructuralReader(bridgeDomainRemoteMappingsInstanceIdentifier, 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.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), + remoteMappingSubtreeId.child(Rlocs.class), + remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), + remoteMappingSubtreeId.child(MapReply.class)), + new GenericListReader<>(vrfTableRemoteMappingsInstanceIdentifier.child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, locatorSetContext, remoteMappingContext))); + registry.subtreeAdd(ImmutableSet.of(remoteMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), + remoteMappingSubtreeId.child(Rlocs.class), + remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), + remoteMappingSubtreeId.child(MapReply.class)), + new GenericListReader<>(bridgeDomainRemoteMappingsInstanceIdentifier.child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, locatorSetContext, remoteMappingContext))); + + registry.addStructuralReader(vrfTableAdjacenciesInstanceIdentifier, AdjacenciesBuilder.class); + registry.addStructuralReader(bridgeDomainAdjacenciesInstanceIdentifier, AdjacenciesBuilder.class); + + final InstanceIdentifier<Adjacency> adjacencySubtreeId = InstanceIdentifier.create(Adjacency.class); + registry.subtreeAdd( + ImmutableSet.of(adjacencySubtreeId.child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListReader<>(vrfTableAdjacenciesInstanceIdentifier.child(Adjacency.class), + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); + registry.subtreeAdd( + ImmutableSet.of(adjacencySubtreeId.child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListReader<>(bridgeDomainAdjacenciesInstanceIdentifier.child(Adjacency.class), + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LispStateReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LispStateReaderFactory.java new file mode 100755 index 000000000..24907641f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LispStateReaderFactory.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.hc2vpp.lisp.translate.read.factory; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.LispStateCustomizer; +import io.fd.hc2vpp.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.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureDataBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +/** + * Initialize readers for {@link LispState} + */ +public class LispStateReaderFactory extends AbstractLispReaderFactoryBase implements ReaderFactory { + + private final AdjacenciesMappingContext adjacenciesIdentificationContext; + + @Inject + public LispStateReaderFactory(final FutureJVppCore vppApi, + @Named(INTERFACE_CONTEXT) final NamingContext interfaceContext, + @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, + @Named("bridge-domain-context") final NamingContext bridgeDomainContext, + @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext, + @Named(ADJACENCIES_IDENTIFICATION_CONTEXT) final + AdjacenciesMappingContext adjacenciesIdentificationContext) { + super(InstanceIdentifier.create(LispState.class), vppApi, interfaceContext, locatorSetContext, + bridgeDomainContext, localMappingContext, remoteMappingContext); + this.adjacenciesIdentificationContext = + checkNotNull(adjacenciesIdentificationContext, "Adjacencies mapping context cannot be null"); + } + + @Override + public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { + + registry.add(new GenericReader<>(lispStateId, new LispStateCustomizer(vppApi))); + registry.addStructuralReader(lispStateId.child(LispFeatureData.class), LispFeatureDataBuilder.class); + + LocatorSetsReaderFactory.newInstance(lispStateId, vppApi, interfaceContext, locatorSetContext).init(registry); + MapResolversReaderFactory.newInstance(lispStateId, vppApi).init(registry); + EidTableReaderFactory + .newInstance(lispStateId, vppApi, interfaceContext, locatorSetContext, bridgeDomainContext, + localMappingContext, remoteMappingContext, adjacenciesIdentificationContext) + .init(registry); + + registry.add(new GenericReader<>(lispStateId.child(LispFeatureData.class).child(PitrCfg.class), + new PitrCfgCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LocatorSetsReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LocatorSetsReaderFactory.java new file mode 100755 index 000000000..f31c30a8f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/LocatorSetsReaderFactory.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.hc2vpp.lisp.translate.read.factory; + + +import io.fd.hc2vpp.lisp.translate.read.InterfaceCustomizer; +import io.fd.hc2vpp.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.hc2vpp.common.translate.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.LocatorSetsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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(LispFeatureData.class).child(LocatorSets.class); + InstanceIdentifier<LocatorSet> locatorSetInstanceIdentifier = + locatorSetsInstanceIdentifier.child(LocatorSet.class); + + registry.addStructuralReader(locatorSetsInstanceIdentifier, LocatorSetsBuilder.class); + registry.add(new GenericListReader<>(locatorSetInstanceIdentifier, + new LocatorSetCustomizer(vppApi, locatorSetContext))); + registry.add(new GenericListReader<>(locatorSetInstanceIdentifier.child(Interface.class), + new InterfaceCustomizer(vppApi, interfaceContext, locatorSetContext))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/MapResolversReaderFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/MapResolversReaderFactory.java new file mode 100755 index 000000000..421b71640 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/factory/MapResolversReaderFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.factory; + + +import io.fd.hc2vpp.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.rev161214.LispState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.MapResolvers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.MapResolversBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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(LispFeatureData.class).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/hc2vpp/lisp/translate/read/trait/LocatorReader.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/LocatorReader.java new file mode 100644 index 000000000..f342d48be --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/LocatorReader.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.trait; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.LocatorDumpParams; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispLocatorDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispLocatorDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; + +/** + * Provides common logic for reading of locators + */ +public interface LocatorReader extends JvppReplyConsumer { + + default EntityDumpExecutor<LispLocatorDetailsReplyDump, LocatorDumpParams> createLocatorDumpExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + checkNotNull(params, "Params for dump request not present"); + final LispLocatorDump request = new LispLocatorDump(); + request.lsIndex = params.getLocatorSetIndex(); + //flag that lsIndex is set + request.isIndexSet = (byte) 1; + + return getReplyForRead(vppApi.lispLocatorDump(request).toCompletableFuture(), identifier); + }; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/LocatorSetReader.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/LocatorSetReader.java new file mode 100644 index 000000000..df4e2ea33 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/LocatorSetReader.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.trait; + +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispLocatorSetDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispLocatorSetDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; + +/** + * Provides common logic for reading {@link LocatorSet} + */ +public interface LocatorSetReader extends JvppReplyConsumer { + + default EntityDumpExecutor<LispLocatorSetDetailsReplyDump, Void> createExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + final LispLocatorSetDump request = new LispLocatorSetDump(); + //only local + request.filter = 1; + return getReplyForRead(vppApi.lispLocatorSetDump(request).toCompletableFuture(), identifier); + }; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingProducer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingProducer.java new file mode 100644 index 000000000..98f8f410c --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingProducer.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.trait; + +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv6Afi; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddressFamily; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.MacAfi; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Trait that verifies data for mappings + */ +public interface MappingProducer { + + /** + * Checks whether provided {@link LocalMapping} can be written under subtree idenfied by {@link InstanceIdentifier} + */ + default void checkAllowedCombination(@Nonnull final InstanceIdentifier<LocalMapping> identifier, + @Nonnull final LocalMapping data) throws WriteFailedException { + final Class<? extends LispAddressFamily> eidAddressType = data.getEid().getAddressType(); + + if (identifier.firstIdentifierOf(VrfSubtable.class) != null) { + if (Ipv4Afi.class != eidAddressType && Ipv6Afi.class != eidAddressType) { + throw new WriteFailedException.CreateFailedException(identifier, data, + new IllegalArgumentException("Only Ipv4/Ipv6 eid's are allowed for Vrf Subtable")); + } + } else if (identifier.firstIdentifierOf(BridgeDomainSubtable.class) != null) { + if (MacAfi.class != eidAddressType) { + throw new WriteFailedException.CreateFailedException(identifier, data, + new IllegalArgumentException("Only Mac eid's are allowed for Bridge Domain Subtable")); + } + } + } + + default void checkAllowedCombination(@Nonnull final InstanceIdentifier<RemoteMapping> identifier, + @Nonnull final RemoteMapping data) throws WriteFailedException { + final Class<? extends LispAddressFamily> eidAddressType = data.getEid().getAddressType(); + + if (identifier.firstIdentifierOf(VrfSubtable.class) != null) { + if (Ipv4Afi.class != eidAddressType && Ipv6Afi.class != eidAddressType) { + throw new WriteFailedException.CreateFailedException(identifier, data, + new IllegalArgumentException("Only Ipv4/Ipv6 eid's are allowed for Vrf Subtable")); + } + } else if (identifier.firstIdentifierOf(BridgeDomainSubtable.class) != null) { + if (MacAfi.class != eidAddressType) { + throw new WriteFailedException.CreateFailedException(identifier, data, + new IllegalArgumentException("Only Mac eid's are allowed for Bridge Domain Subtable")); + } + } + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingReader.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingReader.java new file mode 100644 index 000000000..f76293e3a --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/MappingReader.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.read.trait; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.MAC; + +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetails; +import io.fd.vpp.jvpp.core.dto.LispEidTableDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispEidTableDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.function.Predicate; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +/** + * Trait providing predicates to filter mappings to respective subtables + */ +public interface MappingReader extends JvppReplyConsumer { + + Predicate<LispEidTableDetails> BRIDGE_DOMAIN_MAPPINGS_ONLY = + (LispEidTableDetails detail) -> detail.eidType == MAC.getValue(); + + Predicate<LispEidTableDetails> VRF_MAPPINGS_ONLY = + (LispEidTableDetails detail) -> detail.eidType == IPV4.getValue() || detail.eidType == IPV6.getValue(); + + default Predicate<LispEidTableDetails> subtableFilterForLocalMappings( + @Nonnull final InstanceIdentifier<LocalMapping> identifier) { + + if (identifier.firstIdentifierOf(VrfSubtable.class) != null) { + return VRF_MAPPINGS_ONLY; + } else if (identifier.firstIdentifierOf(BridgeDomainSubtable.class) != null) { + return BRIDGE_DOMAIN_MAPPINGS_ONLY; + } else { + throw new IllegalArgumentException("Cannot determine mappings predicate for " + identifier); + } + } + + default Predicate<LispEidTableDetails> subtableFilterForRemoteMappings( + @Nonnull final InstanceIdentifier<RemoteMapping> identifier) { + + if (identifier.firstIdentifierOf(VrfSubtable.class) != null) { + return VRF_MAPPINGS_ONLY; + } else if (identifier.firstIdentifierOf(BridgeDomainSubtable.class) != null) { + return BRIDGE_DOMAIN_MAPPINGS_ONLY; + } else { + throw new IllegalArgumentException("Cannot determine mappings predicate for " + identifier); + } + } + + default EntityDumpExecutor<LispEidTableDetailsReplyDump, MappingsDumpParams> createMappingDumpExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + 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(); + + return getReplyForRead(vppApi.lispEidTableDump(request).toCompletableFuture(), identifier); + }; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/SubtableReader.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/SubtableReader.java new file mode 100644 index 000000000..f768f4f4d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/read/trait/SubtableReader.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.hc2vpp.lisp.translate.read.trait; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams.MapLevel.L2; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams.MapLevel.L3; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams.SubtableDumpParamsBuilder; + +import io.fd.hc2vpp.lisp.translate.read.dump.executor.params.SubtableDumpParams; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDetailsReplyDump; +import io.fd.vpp.jvpp.core.dto.LispEidTableMapDump; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; + +/** + * Provides common logic for reading Eid subtables + */ +public interface SubtableReader extends JvppReplyConsumer { + + SubtableDumpParams L2_PARAMS = new SubtableDumpParamsBuilder().setL2(L2).build(); + SubtableDumpParams L3_PARAMS = new SubtableDumpParamsBuilder().setL2(L3).build(); + + default EntityDumpExecutor<LispEidTableMapDetailsReplyDump, SubtableDumpParams> createExecutor( + @Nonnull final FutureJVppCore vppApi) { + return (identifier, params) -> { + final LispEidTableMapDump request = new LispEidTableMapDump(); + request.isL2 = checkNotNull(params, "Cannot bind null params").isL2(); + return getReplyForRead(vppApi.lispEidTableMapDump(request).toCompletableFuture(), identifier); + }; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidMetadataProvider.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidMetadataProvider.java new file mode 100644 index 000000000..3d9feca37 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidMetadataProvider.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.hc2vpp.lisp.translate.util; + +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.InstanceIdType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.LispAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEidBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEidBuilder; + +/** + * Trait providing metadata for eid's + */ +public interface EidMetadataProvider { + + /** + * Returns new {@link org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.EidBuilder} + * binded with metadata + */ + default org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.EidBuilder newRemoteEidBuilder( + @Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.EidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + + /** + * Returns new {@link org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.EidBuilder} + * binded with metadata + */ + default org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.EidBuilder newLocalEidBuilder( + @Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.EidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + + default LocalEidBuilder newEidBuilderLocal(@Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new LocalEidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + + default RemoteEidBuilder newEidBuilderRemote(@Nonnull final Class<? extends LispAddressFamily> eidAddressType, + final int vni) { + return new RemoteEidBuilder() + .setAddressType(eidAddressType) + .setVirtualNetworkId(new InstanceIdType(Long.valueOf(vni))); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidTranslator.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidTranslator.java new file mode 100755 index 000000000..347720958 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/util/EidTranslator.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.util; + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.MAC; + +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import java.util.Arrays; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv4Afi; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.lisp.address.types.rev151105.Ipv6Afi; +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.MacAfi; +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.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid; + + +/** + * Trait providing converting logic for eid's + */ +public interface EidTranslator extends AddressTranslator, EidMetadataProvider { + + + default byte getPrefixLength(LocalEid address) { + return resolverPrefixLength(address.getAddress()); + } + + default byte getPrefixLength(RemoteEid address) { + return resolverPrefixLength(address.getAddress()); + } + + default 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()); + } + + default byte getPrefixLength( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid address) { + return resolverPrefixLength(address.getAddress()); + } + + default byte getPrefixLength( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid address) { + return resolverPrefixLength(address.getAddress()); + } + + 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"); + } + } + + default Eid getArrayAsEidLocal(@Nonnull final EidType type, final byte[] address, final int vni) { + + switch (type) { + case IPV4: { + return newLocalEidBuilder(Ipv4Afi.class, vni).setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)).build()) + .build(); + } + case IPV6: { + return newLocalEidBuilder(Ipv6Afi.class, vni).setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)).build()) + .build(); + } + case MAC: { + return newLocalEidBuilder(MacAfi.class, vni).setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + default org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid getArrayAsEidRemote( + @Nonnull final EidType type, final byte[] address, final int vni) { + + switch (type) { + case IPV4: { + return newRemoteEidBuilder(Ipv4Afi.class, vni) + .setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return newRemoteEidBuilder(Ipv6Afi.class, vni) + .setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return newRemoteEidBuilder(MacAfi.class, vni) + .setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + default LocalEid getArrayAsLocalEid(@Nonnull final EidType type, final byte[] address, final int vni) { + switch (type) { + case IPV4: { + return newEidBuilderLocal(Ipv4Afi.class, vni) + .setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return newEidBuilderLocal(Ipv6Afi.class, vni) + .setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return newEidBuilderLocal(MacAfi.class, vni) + .setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + default RemoteEid getArrayAsRemoteEid(@Nonnull final EidType type, final byte[] address, final int vni) { + switch (type) { + case IPV4: { + return newEidBuilderRemote(Ipv4Afi.class, vni) + .setAddress( + new Ipv4Builder().setIpv4(arrayToIpv4AddressNoZoneReversed(address)) + .build()) + .build(); + } + case IPV6: { + return newEidBuilderRemote(Ipv6Afi.class, vni) + .setAddress( + new Ipv6Builder().setIpv6(arrayToIpv6AddressNoZoneReversed(address)) + .build()) + .build(); + } + case MAC: { + return newEidBuilderRemote(MacAfi.class, vni) + .setAddress( + new MacBuilder().setMac(new MacAddress(byteArrayToMacSeparated(address))) + .build()).build(); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + default String getArrayAsEidString( + EidType type, byte[] address) { + switch (type) { + case IPV4: { + return arrayToIpv4AddressNoZoneReversed(address).getValue(); + } + case IPV6: { + return arrayToIpv6AddressNoZoneReversed(address).getValue(); + } + case MAC: { + //as wrong as it looks ,its right(second param is not end index,but count) + return byteArrayToMacSeparated(Arrays.copyOfRange(address, 0, 6)); + } + default: { + throw new IllegalStateException("Unknown type detected"); + } + } + } + + + default 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()); + } + + default EidType getEidType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid address) { + checkNotNull(address, "SimpleAddress cannot be null"); + + return resolveType(address.getAddress()); + } + + + default EidType getEidType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + + default EidType getEidType(final LocalEid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + default EidType getEidType(final RemoteEid address) { + checkNotNull(address, "Address cannot be null"); + + return resolveType(address.getAddress()); + } + + 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 { + throw new IllegalStateException("Unknown type detected"); + } + } + + default 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()); + } + + default byte[] getEidAsByteArray( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + default byte[] getEidAsByteArray( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + default byte[] getEidAsByteArray(final LocalEid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + + default byte[] getEidAsByteArray(final RemoteEid address) { + checkNotNull(address, "Eid cannot be null"); + + return resolveByteArray(getEidType(address), address.getAddress()); + } + + default byte[] resolveByteArray(EidType type, Address address) { + switch (type) { + case IPV4: + return ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(((Ipv4) address).getIpv4())); + case IPV6: + return ipv6AddressNoZoneToArray(new Ipv6AddressNoZone(((Ipv6) address).getIpv6())); + case MAC: + return parseMac(((Mac) address).getMac().getValue()); + default: + throw new IllegalArgumentException("Unsupported type"); + } + } + + default boolean compareEids( + LispAddress first, + LispAddress second) { + + return compareAddresses(checkNotNull(first, "First eid is null").getAddress(), + checkNotNull(second, "Second eid is null").getAddress()); + } + + default 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()); + } + + return false; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/AdjacencyCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/AdjacencyCustomizer.java new file mode 100755 index 000000000..4df60b5de --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/AdjacencyCustomizer.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write; + + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType; + +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelAdjacency; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.AdjacencyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class AdjacencyCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Adjacency, AdjacencyKey>, ByteDataTranslator, EidTranslator, + JvppReplyConsumer { + + private final EidMappingContext localEidsMappingContext; + private final EidMappingContext remoteEidsMappingContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; + + public AdjacencyCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final EidMappingContext localEidsMappingContext, + @Nonnull final EidMappingContext remoteEidsMappingContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { + super(futureJvpp); + this.localEidsMappingContext = + checkNotNull(localEidsMappingContext, "Eid context for local eid's cannot be null"); + this.remoteEidsMappingContext = + checkNotNull(remoteEidsMappingContext, "Eid context for remote eid's cannot be null"); + this.adjacenciesMappingContext = checkNotNull(adjacenciesMappingContext, "Adjacencies context cannot be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Adjacency> id, + @Nonnull final Adjacency dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + try { + addDelAdjacency(true, id, dataAfter, writeContext); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + //after successful creation, create mapping + adjacenciesMappingContext.addEidPair(adjacencyId(id), + localEidId(dataAfter, writeContext), + remoteEidId(dataAfter, writeContext), + writeContext.getMappingContext()); + } + + private String remoteEidId(final @Nonnull Adjacency dataAfter, final @Nonnull WriteContext writeContext) { + return remoteEidsMappingContext.getId(toRemoteEid(dataAfter.getRemoteEid()), writeContext.getMappingContext()) + .getValue(); + } + + private String localEidId(final @Nonnull Adjacency dataAfter, final @Nonnull WriteContext writeContext) { + return localEidsMappingContext.getId(toLocalEid(dataAfter.getLocalEid()), writeContext.getMappingContext()) + .getValue(); + } + + private String adjacencyId(final @Nonnull InstanceIdentifier<Adjacency> id) { + return id.firstKeyOf(Adjacency.class).getId(); + } + + @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, writeContext); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + + //after successful creation, create mapping + adjacenciesMappingContext.removeForIndex(adjacencyId(id), + writeContext.getMappingContext()); + } + + private void addDelAdjacency(boolean add, final InstanceIdentifier<Adjacency> id, final Adjacency data, + final WriteContext writeContext) + throws TimeoutException, VppBaseCallException { + + final int vni = checkNotNull(id.firstKeyOf(VniTable.class), "Unable to find parent VNI for {}", id) + .getVirtualNetworkIdentifier().intValue(); + + // both local and remote eids must be referenced to have respective mapping, + // if there is an attempt to add adjacency. + // In our case its enough to check if local/remote mapping exist for respective eid, + // because such mappings are created while creating mappings + final LocalEid localEid = add + ? verifiedLocalEid(data.getLocalEid(), writeContext) + : data.getLocalEid(); + final RemoteEid remoteEid = add + ? verifiedRemoteEid(data.getRemoteEid(), writeContext) + : data.getRemoteEid(); + final EidType localEidType = getEidType(localEid); + final EidType remoteEidType = 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 = booleanToByte(add); + request.leid = getEidAsByteArray(localEid); + request.leidLen = getPrefixLength(localEid); + request.reid = getEidAsByteArray(remoteEid); + request.reidLen = getPrefixLength(remoteEid); + request.eidType = (byte) localEidType.getValue(); + request.vni = vni; + + getReply(getFutureJVpp().lispAddDelAdjacency(request).toCompletableFuture()); + } + + private LocalEid verifiedLocalEid(final LocalEid localEid, final WriteContext writeContext) { + if (localEidsMappingContext.containsId(toLocalEid(localEid), writeContext.getMappingContext())) { + return localEid; + } + throw new IllegalStateException( + "Referenced Local Eid[" + localEid + + "] doesn't have local mapping defined, therefore it can't be used in adjacency"); + } + + private RemoteEid verifiedRemoteEid(final RemoteEid remoteEid, final WriteContext writeContext) { + if (remoteEidsMappingContext.containsId(toRemoteEid(remoteEid), writeContext.getMappingContext())) { + return remoteEid; + } + throw new IllegalStateException( + "Referenced Remote Eid[" + remoteEid + + "] doesn't have remote mapping defined, therefore it can't be used in adjacency"); + } + + private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid toRemoteEid( + final RemoteEid remoteEid) { + return newRemoteEidBuilder(remoteEid.getAddressType(), remoteEid.getVirtualNetworkId().getValue().intValue()) + .setAddress(remoteEid.getAddress()).build(); + } + + private org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid toLocalEid( + LocalEid localEid) { + return newLocalEidBuilder(localEid.getAddressType(), localEid.getVirtualNetworkId().getValue().intValue()) + .setAddress(localEid.getAddress()).build(); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/BridgeDomainSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/BridgeDomainSubtableCustomizer.java new file mode 100644 index 000000000..b17656773 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/BridgeDomainSubtableCustomizer.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import io.fd.hc2vpp.lisp.translate.write.trait.SubtableWriter; +import io.fd.honeycomb.translate.MappingContext; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BridgeDomainSubtableCustomizer extends FutureJVppCustomizer + implements WriterCustomizer<BridgeDomainSubtable>, SubtableWriter { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainSubtableCustomizer.class); + + private final NamingContext bridgeDomainContext; + + public BridgeDomainSubtableCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext bridgeDomainContext) { + super(futureJvpp); + this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomainSubtable> id, + @Nonnull final BridgeDomainSubtable dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Writing Id {} ", id); + + try { + addDelSubtableMapping(getFutureJVpp(), true, extractVni(id), + extractBridgeDomainId(dataAfter.getBridgeDomainRef(), writeContext.getMappingContext()), true, LOG); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + LOG.debug("{} successfully written", id); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomainSubtable> id, + @Nonnull final BridgeDomainSubtable dataBefore, + @Nonnull final BridgeDomainSubtable dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomainSubtable> id, + @Nonnull final BridgeDomainSubtable dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + LOG.debug("Removing Id {}", id); + + try { + addDelSubtableMapping(getFutureJVpp(), false, extractVni(id), + extractBridgeDomainId(dataBefore.getBridgeDomainRef(), writeContext.getMappingContext()), true, + LOG); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + + LOG.debug("{} successfully removed", id); + } + + private int extractBridgeDomainId(final String bridgeDomainName, final MappingContext mappingContext) { + checkState(bridgeDomainContext.containsIndex(bridgeDomainName, mappingContext), + "No mapping for bridge domain name %s", bridgeDomainName); + return bridgeDomainContext.getIndex(bridgeDomainName, mappingContext); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/InterfaceCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/InterfaceCustomizer.java new file mode 100755 index 000000000..ccce2baec --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/InterfaceCustomizer.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +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.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelLocator; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for updating {@link Interface} + * + * @see Interface + */ +public class InterfaceCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<Interface, InterfaceKey>, ByteDataTranslator, JvppReplyConsumer { + + 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 = booleanToByte(add); + request.priority = data.getPriority().byteValue(); + request.weight = data.getWeight().byteValue(); + request.swIfIndex = interfaceIndex; + request.locatorSetName = locatorSetName.getBytes(UTF_8); + + getReply(getFutureJVpp().lispAddDelLocator(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/ItrRemoteLocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/ItrRemoteLocatorSetCustomizer.java new file mode 100644 index 000000000..fd34ec6c6 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/ItrRemoteLocatorSetCustomizer.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.hc2vpp.lisp.translate.write; + + +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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 javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.itr.remote.locator.sets.grouping.ItrRemoteLocatorSet; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelMapRequestItrRlocs; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + +public class ItrRemoteLocatorSetCustomizer extends FutureJVppCustomizer implements + WriterCustomizer<ItrRemoteLocatorSet>, ByteDataTranslator, JvppReplyConsumer { + + public ItrRemoteLocatorSetCustomizer(@Nonnull final FutureJVppCore futureJVppCore) { + super(futureJVppCore); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ItrRemoteLocatorSet> id, + @Nonnull final ItrRemoteLocatorSet dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + try { + addDelItrRemoteLocatorSet(true, dataAfter); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<ItrRemoteLocatorSet> id, + @Nonnull final ItrRemoteLocatorSet dataBefore, + @Nonnull final ItrRemoteLocatorSet dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<ItrRemoteLocatorSet> id, + @Nonnull final ItrRemoteLocatorSet dataBefore, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + try { + addDelItrRemoteLocatorSet(false, dataBefore); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.DeleteFailedException(id, e); + } + } + + private void addDelItrRemoteLocatorSet(final boolean add, @Nonnull final ItrRemoteLocatorSet data) + throws TimeoutException, VppBaseCallException { + + LispAddDelMapRequestItrRlocs request = new LispAddDelMapRequestItrRlocs(); + request.isAdd = booleanToByte(add); + request.locatorSetName = data.getRemoteLocatorSetName().getBytes(StandardCharsets.UTF_8); + + getReply(getFutureJVpp().lispAddDelMapRequestItrRlocs(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LispCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LispCustomizer.java new file mode 100755 index 000000000..1ec4c7191 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LispCustomizer.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write; + +import com.google.common.base.Preconditions; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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.rev161214.Lisp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispEnableDisable; +import io.fd.vpp.jvpp.core.dto.LispEnableDisableReply; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Handles updates of {@link Lisp} node. Takes care of LISP enable/disable + */ +public class LispCustomizer extends FutureJVppCustomizer + implements WriterCustomizer<Lisp>, ByteDataTranslator, JvppReplyConsumer { + + 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)); + getReply(lispEnableDisableReplyCompletionStage.toCompletableFuture()); + } + + private LispEnableDisable getRequest(final boolean enable) { + final LispEnableDisable lispEnableDisable = new LispEnableDisable(); + lispEnableDisable.isEn = booleanToByte(enable); + return lispEnableDisable; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocalMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocalMappingCustomizer.java new file mode 100755 index 000000000..fc9b2a662 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocalMappingCustomizer.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV4; +import static io.fd.hc2vpp.lisp.translate.read.dump.executor.params.MappingsDumpParams.EidType.IPV6; +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.trait.MappingProducer; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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.rev161214.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelLocalEid; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer that writes changes for {@link LocalMapping} + */ +public class LocalMappingCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<LocalMapping, LocalMappingKey>, ByteDataTranslator, EidTranslator, + JvppReplyConsumer, MappingProducer { + + 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"); + checkAllowedCombination(id, dataAfter); + + //checks whether value with specified mapping-id does not exist in mapping allready + final 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 = booleanToByte(add); + request.eid = getEidAsByteArray(data.getEid()); + request.eidType = (byte) 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; + } + + getReply(getFutureJVpp().lispAddDelLocalEid(request).toCompletableFuture()); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocatorSetCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocatorSetCustomizer.java new file mode 100755 index 000000000..f929193a8 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/LocatorSetCustomizer.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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.hc2vpp.lisp.translate.read.trait.LocatorSetReader; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import io.fd.vpp.jvpp.core.dto.LispAddDelLocatorSet; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSetKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +/** + * Customizer for {@link LocatorSet} entity. + * + * @see LocatorSet + */ +public class LocatorSetCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<LocatorSet, LocatorSetKey>, ByteDataTranslator, + LocatorSetReader { + + private final NamingContext locatorSetContext; + + public LocatorSetCustomizer(@Nonnull final FutureJVppCore futureJvpp, + @Nonnull final NamingContext locatorSetContext) { + super(futureJvpp); + this.locatorSetContext = checkNotNull(locatorSetContext, "Locator set context cannot be null"); + } + + @Override + public void writeCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + checkState(isNonEmptyLocatorSet(writeContext.readAfter(id).get()), + "Creating empty locator-sets is not allowed"); + final String locatorSetName = dataAfter.getName(); + checkState(!locatorSetContext.containsIndex(locatorSetName, writeContext.getMappingContext()), + "Locator set with name %s already defined", locatorSetName); + + final int locatorSetIndex = addDelLocatorSetAndReply(true, dataAfter.getName(), id); + locatorSetContext.addName(locatorSetIndex, locatorSetName, writeContext.getMappingContext()); + } + + private boolean isNonEmptyLocatorSet(final LocatorSet locatorSet) { + final List<Interface> locators = locatorSet.getInterface(); + return locators != null && !locators.isEmpty(); + } + + @Override + public void updateCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataBefore, + @Nonnull LocatorSet dataAfter, + @Nonnull WriteContext writeContext) throws WriteFailedException { + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, + new UnsupportedOperationException("Operation not supported")); + } + + @Override + public void deleteCurrentAttributes(@Nonnull InstanceIdentifier<LocatorSet> id, + @Nonnull LocatorSet dataBefore, + @Nonnull WriteContext writeContext) throws WriteFailedException { + final String locatorSetName = dataBefore.getName(); + addDelLocatorSetAndReply(false, dataBefore.getName(), id); + //removes mapping after successful delete + locatorSetContext.removeName(locatorSetName, writeContext.getMappingContext()); + } + + private int addDelLocatorSetAndReply(final boolean add, final String name, final InstanceIdentifier<LocatorSet> id) + throws WriteFailedException { + + LispAddDelLocatorSet addDelSet = new LispAddDelLocatorSet(); + + addDelSet.isAdd = booleanToByte(add); + addDelSet.locatorSetName = name.getBytes(UTF_8); + + return getReplyForWrite(getFutureJVpp().lispAddDelLocatorSet(addDelSet).toCompletableFuture(), id).lsIndex; + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/MapResolverCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/MapResolverCustomizer.java new file mode 100755 index 000000000..0c8a9ec74 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/MapResolverCustomizer.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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.rev161214.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.map.resolvers.MapResolverKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelMapResolver; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Handles updates of {@link MapResolver} list + */ +public class MapResolverCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<MapResolver, MapResolverKey>, AddressTranslator, + JvppReplyConsumer { + + 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 = booleanToByte(add); + + + boolean ipv6 = isIpv6(data.getIpAddress()); + + request.isIpv6 = booleanToByte(ipv6); + request.ipAddress = ipAddressToArray(ipv6, data.getIpAddress()); + + getReply(getFutureJVpp().lispAddDelMapResolver(request).toCompletableFuture()); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/PitrCfgCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/PitrCfgCustomizer.java new file mode 100755 index 000000000..a405b96f7 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/PitrCfgCustomizer.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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.rev161214.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispPitrSetLocatorSet; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for {@code PitrCfg} + */ +public class PitrCfgCustomizer extends FutureJVppCustomizer + implements WriterCustomizer<PitrCfg>, JvppReplyConsumer, ByteDataTranslator { + + private static final String DEFAULT_LOCATOR_SET_NAME = "N/A"; + + 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 { + + if (DEFAULT_LOCATOR_SET_NAME.equals(data.getLocatorSet())) { + // ignores attempts to write default locator set + // therefore even while its loaded to config data of honeycomb while starting + // you can still enable/disable Lisp without having to define N/A as default pitr-set + return; + } + + LispPitrSetLocatorSet request = new LispPitrSetLocatorSet(); + request.isAdd = booleanToByte(add); + request.lsName = data.getLocatorSet().getBytes(UTF_8); + + getReply(getFutureJVpp().lispPitrSetLocatorSet(request).toCompletableFuture()); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/RemoteMappingCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/RemoteMappingCustomizer.java new file mode 100755 index 000000000..2078f57d4 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/RemoteMappingCustomizer.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.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.hc2vpp.lisp.translate.write.RemoteMappingCustomizer.LocatorListType.NEGATIVE; +import static io.fd.hc2vpp.lisp.translate.write.RemoteMappingCustomizer.LocatorListType.POSITIVE; + +import com.google.common.base.Preconditions; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.read.trait.MappingProducer; +import io.fd.hc2vpp.lisp.translate.util.EidTranslator; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.hc2vpp.common.translate.util.AddressTranslator; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +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.rev161214.MapReplyAction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.MappingId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMappingKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.LocatorList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.NegativeMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.PositiveMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.Rlocs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispAddDelRemoteMapping; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; + + +/** + * Customizer for {@link RemoteMapping} + */ +public class RemoteMappingCustomizer extends FutureJVppCustomizer + implements ListWriterCustomizer<RemoteMapping, RemoteMappingKey>, EidTranslator, + AddressTranslator, JvppReplyConsumer, MappingProducer { + + 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"); + checkAllowedCombination(id, dataAfter); + + //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 = booleanToByte(add); + request.vni = vni; + request.eidType = (byte) getEidType(data.getEid()).getValue(); + request.eid = getEidAsByteArray(data.getEid()); + + //this is not length of eid array,but prefix length(bad naming by vpp) + request.eidLen = 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(); + } + + 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).getMapReply().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(); + } + + //cant be static because of use of default methods from traits + private 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 = !isIpv6(locator.getAddress()); + out.writeByte(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( + + ipv4AddressNoZoneToArray(new Ipv4AddressNoZone(locator.getAddress().getIpv4Address())), + 16); + + out.write(address); + } else { + out.write( + 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/hc2vpp/lisp/translate/write/VniTableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/VniTableCustomizer.java new file mode 100755 index 000000000..607c4b7d8 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/VniTableCustomizer.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.hc2vpp.lisp.translate.write; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.util.RWUtils; + +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTableKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * This customizer serves only as a check if user is not trying to define VniTable <br> + * without mapping to vrf/bd + */ +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 { + checkAtLeastOnChildExists(id, writeContext, false); + } + + @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 { + checkAtLeastOnChildExists(id, writeContext, true); + } + + private void checkAtLeastOnChildExists(final InstanceIdentifier<VniTable> id, final WriteContext writeContext, + final boolean before) { + + Optional<VniTable> optData; + final InstanceIdentifier<VniTable> trimmedId = RWUtils.cutId(id, InstanceIdentifier.create(VniTable.class)); + if (before) { + optData = writeContext.readBefore(trimmedId); + } else { + optData = writeContext.readAfter(trimmedId); + } + + checkState(optData.isPresent(), "Illegal after-write state"); + + final VniTable dataAfter = optData.get(); + checkState(dataAfter.getVrfSubtable() != null || dataAfter.getBridgeDomainSubtable() != null, + "At least one of VrfSubtable/BridgeDomainSubtable must be defined"); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/VrfSubtableCustomizer.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/VrfSubtableCustomizer.java new file mode 100644 index 000000000..e02987916 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/VrfSubtableCustomizer.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.hc2vpp.lisp.translate.write; + +import io.fd.hc2vpp.lisp.translate.write.trait.SubtableWriter; +import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer; +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.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VrfSubtableCustomizer extends FutureJVppCustomizer + implements WriterCustomizer<VrfSubtable>, SubtableWriter { + + private static final Logger LOG = LoggerFactory.getLogger(VrfSubtableCustomizer.class); + + public VrfSubtableCustomizer(@Nonnull final FutureJVppCore futureJvpp) { + super(futureJvpp); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<VrfSubtable> id, + @Nonnull final VrfSubtable dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Writing Id[{}]/Data[{}]", id, dataAfter); + + try { + addDelSubtableMapping(getFutureJVpp(), true, extractVni(id), dataAfter.getTableId().intValue(), false, LOG); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + + LOG.debug("{} successfully written", id); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<VrfSubtable> id, + @Nonnull final VrfSubtable dataBefore, @Nonnull final VrfSubtable dataAfter, + @Nonnull final WriteContext writeContext) throws WriteFailedException { + throw new UnsupportedOperationException("Operation not supported"); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VrfSubtable> id, + @Nonnull final VrfSubtable dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + + LOG.debug("Removing Id[{}]/Data[{}]", id, dataBefore); + + try { + addDelSubtableMapping(getFutureJVpp(), false, extractVni(id), dataBefore.getTableId().intValue(), false, + LOG); + } catch (TimeoutException | VppBaseCallException e) { + throw new WriteFailedException.CreateFailedException(id, dataBefore, e); + } + + LOG.debug("{} successfully removed", id); + } + +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java new file mode 100644 index 000000000..cf6df820d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/AbstractLispWriterFactoryBase.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write.factory; + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.Lisp; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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/hc2vpp/lisp/translate/write/factory/LispWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/LispWriterFactory.java new file mode 100755 index 000000000..5bd02a2f9 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/LispWriterFactory.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.hc2vpp.lisp.translate.write.factory; + + +import static com.google.common.base.Preconditions.checkNotNull; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.ADJACENCIES_IDENTIFICATION_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.INTERFACE_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCAL_MAPPING_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.LOCATOR_SET_CONTEXT; +import static io.fd.hc2vpp.lisp.cfgattrs.LispConfiguration.REMOTE_MAPPING_CONTEXT; + +import com.google.inject.Inject; +import com.google.inject.name.Named; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.write.LispCustomizer; +import io.fd.hc2vpp.lisp.translate.write.PitrCfgCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.pitr.cfg.grouping.PitrCfg; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +/** + * Initialize writers for {@link Lisp} + */ +public final class LispWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + private final NamingContext bridgeDomainContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; + + @Inject + public LispWriterFactory(final FutureJVppCore vppApi, + @Named(INTERFACE_CONTEXT) final NamingContext interfaceContext, + @Named(LOCATOR_SET_CONTEXT) final NamingContext locatorSetContext, + @Named("bridge-domain-context") final NamingContext bridgeDomainContext, + @Named(LOCAL_MAPPING_CONTEXT) final EidMappingContext localMappingContext, + @Named(REMOTE_MAPPING_CONTEXT) final EidMappingContext remoteMappingContext, + @Named(ADJACENCIES_IDENTIFICATION_CONTEXT) final AdjacenciesMappingContext adjacenciesMappingContext) { + super(InstanceIdentifier.create(Lisp.class), vppApi, interfaceContext, locatorSetContext, localMappingContext, + remoteMappingContext); + this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); + } + + @Override + public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { + registry.add(new GenericWriter<>(lispInstanceIdentifier, new LispCustomizer(vppApi))); + + VniTableWriterFactory.newInstance(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext, + bridgeDomainContext, adjacenciesMappingContext) + .init(registry); + LocatorSetsWriterFactory.newInstance(lispInstanceIdentifier, vppApi, interfaceContext, locatorSetContext) + .init(registry); + MapResolversWriterFactory.newInstance(lispInstanceIdentifier, vppApi).init(registry); + + registry.add(new GenericWriter<>(lispInstanceIdentifier.child(LispFeatureData.class).child(PitrCfg.class), + new PitrCfgCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/LocatorSetsWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/LocatorSetsWriterFactory.java new file mode 100755 index 000000000..c4227637f --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/LocatorSetsWriterFactory.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.hc2vpp.lisp.translate.write.factory; + +import io.fd.hc2vpp.lisp.translate.write.InterfaceCustomizer; +import io.fd.hc2vpp.lisp.translate.write.LocatorSetCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.hc2vpp.common.translate.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.rev161214.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.LocatorSets; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.LocatorSet; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.locator.sets.grouping.locator.sets.locator.set.Interface; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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(LispFeatureData.class).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/hc2vpp/lisp/translate/write/factory/MapResolversWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/MapResolversWriterFactory.java new file mode 100755 index 000000000..8b0d7d52d --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/MapResolversWriterFactory.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.hc2vpp.lisp.translate.write.factory; + + +import io.fd.hc2vpp.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.rev161214.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.MapResolvers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.map.resolvers.grouping.map.resolvers.MapResolver; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.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(LispFeatureData.class).child(MapResolvers.class).child(MapResolver.class), + new MapResolverCustomizer(vppApi))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/VniTableWriterFactory.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/VniTableWriterFactory.java new file mode 100755 index 000000000..64dd7d587 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/factory/VniTableWriterFactory.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.lisp.translate.write.factory; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.lisp.context.util.AdjacenciesMappingContext; +import io.fd.hc2vpp.lisp.context.util.EidMappingContext; +import io.fd.hc2vpp.lisp.translate.write.AdjacencyCustomizer; +import io.fd.hc2vpp.lisp.translate.write.BridgeDomainSubtableCustomizer; +import io.fd.hc2vpp.lisp.translate.write.LocalMappingCustomizer; +import io.fd.hc2vpp.lisp.translate.write.RemoteMappingCustomizer; +import io.fd.hc2vpp.lisp.translate.write.VniTableCustomizer; +import io.fd.hc2vpp.lisp.translate.write.VrfSubtableCustomizer; +import io.fd.honeycomb.translate.impl.write.GenericListWriter; +import io.fd.honeycomb.translate.impl.write.GenericWriter; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.Lisp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.Adjacencies; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.Adjacency; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.LocalEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.adjacencies.grouping.adjacencies.adjacency.RemoteEid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.LocalMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.RemoteMappings; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.LocalMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.RemoteMapping; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.negative.mapping.MapReply; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.Rlocs; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.locator.list.positive.mapping.rlocs.Locator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.EidTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.lisp.feature.data.grouping.LispFeatureData; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + + +//TODO - HONEYCOMB-282 - refactor this and other factories for better readability + +/** + * Factory for producing writers for {@code EidTable} + */ +final class VniTableWriterFactory extends AbstractLispWriterFactoryBase implements WriterFactory { + + private final NamingContext bridgeDomainContext; + private final AdjacenciesMappingContext adjacenciesMappingContext; + + private VniTableWriterFactory(final InstanceIdentifier<Lisp> lispInstanceIdentifier, + final FutureJVppCore vppApi, + final EidMappingContext localMappingContext, + final EidMappingContext remoteMappingContext, + final NamingContext bridgeDomainContext, + final AdjacenciesMappingContext adjacenciesMappingContext) { + super(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext); + this.bridgeDomainContext = checkNotNull(bridgeDomainContext, "Bridge domain context cannot be null"); + this.adjacenciesMappingContext = + checkNotNull(adjacenciesMappingContext, "Adjacencies mapping context cannot be null"); + } + + public static VniTableWriterFactory newInstance( + @Nonnull final InstanceIdentifier<Lisp> lispInstanceIdentifier, + @Nonnull final FutureJVppCore vppApi, + @Nonnull final EidMappingContext localMappingContext, + @Nonnull final EidMappingContext remoteMappingContext, + @Nonnull final NamingContext bridgeDomainContext, + @Nonnull final AdjacenciesMappingContext adjacenciesMappingContext) { + return new VniTableWriterFactory(lispInstanceIdentifier, vppApi, localMappingContext, remoteMappingContext, + bridgeDomainContext, adjacenciesMappingContext); + } + + @Override + public void init(final ModifiableWriterRegistryBuilder registry) { + final InstanceIdentifier<VniTable> vniTableId = + lispInstanceIdentifier.child(LispFeatureData.class).child(EidTable.class).child(VniTable.class); + + final InstanceIdentifier<VrfSubtable> vrfSubtableId = vniTableId.child(VrfSubtable.class); + final InstanceIdentifier<BridgeDomainSubtable> bridgeDomainSubtableId = + vniTableId.child(BridgeDomainSubtable.class); + + registry.add(new GenericListWriter<>(vniTableId, new VniTableCustomizer(vppApi))); + + registry.add(new GenericWriter<>(vrfSubtableId, new VrfSubtableCustomizer(vppApi))); + registry.add(new GenericWriter<>(bridgeDomainSubtableId, + new BridgeDomainSubtableCustomizer(vppApi, bridgeDomainContext))); + + //VniTable - > VrfSubtable -> LocalMappings - > LocalMapping + 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.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class)), + new GenericListWriter<>( + vrfSubtableId.child(LocalMappings.class).child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, localMappingContext))); + //VniTable - > BridgeDomainSubtable -> LocalMappings - > LocalMapping + registry.subtreeAdd(ImmutableSet.of(localMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.local.mappings.local.mapping.Eid.class)), + new GenericListWriter<>(bridgeDomainSubtableId.child(LocalMappings.class) + .child(LocalMapping.class), + new LocalMappingCustomizer(vppApi, localMappingContext))); + + //VniTable - > VrfSubtable -> RemoteMappings - > RemoteMapping + 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.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), + remoteMappingSubtreeId.child(Rlocs.class), + remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), + remoteMappingSubtreeId.child(MapReply.class)), + new GenericListWriter<>( + vrfSubtableId.child(RemoteMappings.class).child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + //VniTable - > BridgeDomainSubtable -> RemoteMappings - > RemoteMapping + registry.subtreeAdd(ImmutableSet.of(remoteMappingSubtreeId + .child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.dp.subtable.grouping.remote.mappings.remote.mapping.Eid.class), + remoteMappingSubtreeId.child(Rlocs.class), + remoteMappingSubtreeId.child(Rlocs.class).child(Locator.class), + remoteMappingSubtreeId.child(MapReply.class)), + new GenericListWriter<>(bridgeDomainSubtableId.child(RemoteMappings.class) + .child(RemoteMapping.class), + new RemoteMappingCustomizer(vppApi, remoteMappingContext))); + + //VniTable - > VrfSubtable -> RemoteMappings - > RemoteMapping - > Adjacencies - > Adjacency + final InstanceIdentifier<Adjacency> adjacencySubtreeId = InstanceIdentifier.create(Adjacency.class); + registry.subtreeAdd(ImmutableSet.of(adjacencySubtreeId + .child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListWriter<>( + vrfSubtableId.child(RemoteMappings.class).child(RemoteMapping.class) + .child(Adjacencies.class).child(Adjacency.class), + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); + //VniTable - > BridgeDomainSubtable -> RemoteMappings - > RemoteMapping - > Adjacencies - > Adjacency + registry.subtreeAdd(ImmutableSet.of(adjacencySubtreeId + .child(LocalEid.class), adjacencySubtreeId.child(RemoteEid.class)), + new GenericListWriter<>( + bridgeDomainSubtableId.child(RemoteMappings.class) + .child(RemoteMapping.class) + .child(Adjacencies.class).child(Adjacency.class), + new AdjacencyCustomizer(vppApi, localMappingContext, remoteMappingContext, + adjacenciesMappingContext))); + } +} diff --git a/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/trait/SubtableWriter.java b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/trait/SubtableWriter.java new file mode 100644 index 000000000..637258311 --- /dev/null +++ b/lisp/lisp2vpp/src/main/java/io/fd/hc2vpp/lisp/translate/write/trait/SubtableWriter.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.hc2vpp.lisp.translate.write.trait; + + +import static com.google.common.base.Preconditions.checkNotNull; + +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import java.util.concurrent.TimeoutException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.VniTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.BridgeDomainSubtable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.lisp.rev161214.eid.table.grouping.eid.table.vni.table.VrfSubtable; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import io.fd.vpp.jvpp.VppBaseCallException; +import io.fd.vpp.jvpp.core.dto.LispEidTableAddDelMap; +import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.slf4j.Logger; + +/** + * Trait providing logic for writing subtables + */ +public interface SubtableWriter extends ByteDataTranslator, JvppReplyConsumer { + int DEFAULT_VNI = 0; + + /** + * Writes mapping from {@link VniTable} + * to {@link VrfSubtable} or + * {@link BridgeDomainSubtable} + * + * @param addDel true if add,delete otherwise + * @param vni {@link VniTable} ID + * @param tableId if <b>isL2</b> is true, than bridge domain subtable id,else vrf subtable id + * @param isL2 indicates whether (false) writing to L3 vrfSubtrable of (true) L2 bridgeDomainSubtrable + */ + default void addDelSubtableMapping(@Nonnull final FutureJVppCore vppApi, final boolean addDel, final int vni, + final int tableId, + final boolean isL2, + final Logger logger) throws TimeoutException, VppBaseCallException { + + if (vni == DEFAULT_VNI) { + // attempt to write subtable with default vni mapping(it does'nt make sense and it should'nt be possible) + // also allows to enable lisp without defining default mapping in request + logger.info("An attempt to write subtable[id = {}] with default vni {} was detected, ignoring write", + tableId, DEFAULT_VNI); + return; + } + + checkNotNull(vppApi, "VPP Api refference cannot be null"); + + LispEidTableAddDelMap request = new LispEidTableAddDelMap(); + + request.isAdd = booleanToByte(addDel); + request.vni = vni; + request.dpTable = tableId; + request.isL2 = booleanToByte(isL2); + + getReply(vppApi.lispEidTableAddDelMap(request).toCompletableFuture()); + } + + default int extractVni(@Nonnull final InstanceIdentifier<? extends ChildOf<VniTable>> id) { + return checkNotNull( + checkNotNull(id, "Identifier cannot be null").firstKeyOf(VniTable.class), + "Parent VNI id not defined").getVirtualNetworkIdentifier().intValue(); + } +} |