HC2VPP-288 - add readers for SRv6 module 30/12830/10
authorMichal Cmarada <[email protected]>
Fri, 15 Jun 2018 11:10:53 +0000 (13:10 +0200)
committerMarek Gradzki <[email protected]>
Tue, 19 Jun 2018 18:56:27 +0000 (18:56 +0000)
Changes:
- add locator context to map locator name to locator IPv6Prefix
- add readers for SRv6 module
- implements reading of local sids and their end functions.
- implements support for FIB table management (HC2VPP-345)

Change-Id: Ib04402539a0b6666c5a1d0b4e1b5b5e08ccbf67b
Signed-off-by: Michal Cmarada <[email protected]>
39 files changed:
srv6/srv6-api/src/main/yang/[email protected] [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/Srv6Configuration.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/Srv6Module.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/ReadRequest.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/Srv6ReaderFactory.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizer.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizer.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequest.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequest.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManager.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImpl.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionBindingRegistry.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBinder.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistry.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistryProvider.java [new file with mode: 0644]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionWriteBinder.java [moved from srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionBinder.java with 79% similarity]
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionWriteBindingRegistry.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionWriteBindingRegistryProvider.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/lookup/EndDT4FunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/lookup/EndDT6FunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/lookup/EndTFunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/lookup/TableLookupFunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/nofunction/EndFunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/xconnect/EndDX2FunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/xconnect/EndDX4FunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/xconnect/EndDX6FunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/xconnect/EndXFunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/xconnect/XConnectFunctionBinder.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/write/Srv6WriterFactory.java
srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/write/sid/LocatorCustomizer.java
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/Srv6ModuleTest.java
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizerTest.java [new file with mode: 0644]
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizerTest.java [new file with mode: 0644]
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequestTest.java [new file with mode: 0644]
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequestTest.java [new file with mode: 0644]
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/util/JvppRequestTest.java
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImplTest.java [new file with mode: 0644]
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionBindingRegistryTest.java
srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/write/sid/request/LocalSidRequestTest.java

new file mode 100644 (file)
index 0000000..0634be5
--- /dev/null
@@ -0,0 +1,73 @@
+module locator-context {
+    yang-version 1;
+    namespace "urn:honeycomb:params:xml:ns:yang:locator:context";
+    prefix "locator-ctx";
+
+    import ietf-inet-types {
+       prefix "inet";
+    }
+
+    import naming-context {
+       prefix "nc";
+    }
+
+    import yang-ext {
+       prefix "ext";
+    }
+
+    organization
+        "FD.io - The Fast Data Project";
+
+    contact
+        "Hc2vpp Wiki <https://wiki.fd.io/view/Hc2vpp>
+         Mailing List <[email protected]>";
+
+    description
+        "This module provides mapping between SRV6 locator identifiers
+         defined in the ietf-nat-srv6-base module
+         and identifiers used by the VPP SRV6 plugin.
+
+         The mapping is managed internally by the HC SRV6 plugin.
+         It is exposed as operational state data for debugging purposes.
+
+         Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.";
+
+    revision "2018-06-05" {
+        description "Initial revision.";
+    }
+
+    grouping srv6-locator-context-attributes {
+        container srv6-locator-mappings {
+            list srv6-locator-mapping {
+                key "name";
+
+                leaf name {
+                    type string;
+                    description "Srv6 locator name";
+                }
+
+                leaf prefix {
+                    type inet:ipv6-prefix;
+                    description "Locator represented by IPv6 address and locator length.";
+                }
+            }
+        }
+    }
+
+    augment /nc:contexts {
+        ext:augment-identifier "srv6-locator-context-augmentation";
+        uses srv6-locator-context-attributes;
+    }
+}
index 8d23b17..f11c730 100644 (file)
@@ -19,17 +19,10 @@ package io.fd.hc2vpp.srv6;
 public class Srv6Configuration {
 
     /**
-     * Used to map Srv6 Sids to locator length values
+     * Provides default locator length value for locator context. Since local SID is represented as IPv6 address, which
+     * represents LOCATOR+FUNCTION. This address with total length of 128 bits is divided into these parts by defining
+     * locator length. Because ietf-srv6-types model defines local SIds OpCode (function) as uint32, it leaves 96 bits
+     * for the locator part. This way we can use full range of the IPv6 address without loosing any bits.
      */
-    public static final String LOCATOR_CONTEXT = "locator-context";
-
-    /**
-     * Locator length context child name for locator length
-     */
-    public static final String LOCATOR_LENGTH = "locator-length";
-
-    /**
-     * Locator length context child name for locator length
-     */
-    public static final String LOCATOR_IPV6_ADDRESS = "locator-ipv6-address";
+    public static final Integer DEFAULT_LOCATOR_LENGTH = 96;
 }
index 5dd3e20..ec91b21 100644 (file)
 
 package io.fd.hc2vpp.srv6;
 
+import static io.fd.hc2vpp.srv6.Srv6Configuration.DEFAULT_LOCATOR_LENGTH;
+
 import com.google.inject.AbstractModule;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
+import io.fd.hc2vpp.srv6.read.Srv6ReaderFactory;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+import io.fd.hc2vpp.srv6.util.LocatorContextManagerImpl;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistry;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistryProvider;
 import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBindingRegistry;
 import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBindingRegistryProvider;
 import io.fd.hc2vpp.srv6.write.Srv6WriterFactory;
+import io.fd.honeycomb.translate.read.ReaderFactory;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,6 +44,11 @@ public class Srv6Module extends AbstractModule {
         LOG.info("Reading SRv6 configuration");
         requestInjection(Srv6Configuration.class);
 
+        bind(LocatorContextManager.class).toInstance(new LocatorContextManagerImpl(DEFAULT_LOCATOR_LENGTH));
+
+        bind(LocalSidFunctionReadBindingRegistry.class).toProvider(LocalSidFunctionReadBindingRegistryProvider.class)
+                .in(Singleton.class);
+
         bind(LocalSidFunctionWriteBindingRegistry.class).toProvider(LocalSidFunctionWriteBindingRegistryProvider.class)
                 .in(Singleton.class);
 
@@ -43,6 +56,10 @@ public class Srv6Module extends AbstractModule {
         final Multibinder<WriterFactory> writeBinder = Multibinder.newSetBinder(binder(), WriterFactory.class);
         writeBinder.addBinding().to(Srv6WriterFactory.class);
 
+        LOG.info("Injecting SRv6 readers");
+        final Multibinder<ReaderFactory> readerBinder = Multibinder.newSetBinder(binder(), ReaderFactory.class);
+        readerBinder.addBinding().to(Srv6ReaderFactory.class);
+
         LOG.info("SRv6 module successfully configured");
     }
 }
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/ReadRequest.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/ReadRequest.java
new file mode 100644 (file)
index 0000000..1b366fd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read;
+
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Represents common interface for read requests
+ *
+ * @param <T> type class to be read
+ * @param <K> key class of read type
+ * @param <B> builder class for read type
+ */
+public interface ReadRequest<T extends DataObject & Identifiable<K>, K extends Identifier<T>, B extends Builder<T>> {
+
+    /**
+     * Provide list of keys for specified type
+     *
+     * @param identifier identifies path to DataObject class of specified type
+     * @param ctx        read context holds modification cache and mapping context
+     * @return list of keys for specified type
+     * @throws ReadFailedException when read error occurs
+     */
+    @Nonnull
+    List<K> readAllKeys(@Nonnull final InstanceIdentifier<T> identifier, @Nonnull final ReadContext ctx) throws
+            ReadFailedException;
+
+    /**
+     * Reads one specific value
+     *
+     * @param identifier identifies path to DataObject class of specified type
+     * @param ctx        read context holds modification cache and mapping context
+     * @param builder    builder for particular type which will hold actual data
+     * @throws ReadFailedException when read error occurs
+     */
+    void readSpecific(@Nonnull final InstanceIdentifier<T> identifier, @Nonnull final ReadContext ctx,
+                      @Nonnull B builder)
+            throws ReadFailedException;
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/Srv6ReaderFactory.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/Srv6ReaderFactory.java
new file mode 100644 (file)
index 0000000..312280d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read;
+
+import com.google.inject.Inject;
+import io.fd.hc2vpp.srv6.Srv6IIds;
+import io.fd.hc2vpp.srv6.read.sid.LocatorCustomizer;
+import io.fd.hc2vpp.srv6.read.sid.SidCustomizer;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistry;
+import io.fd.honeycomb.translate.impl.read.GenericInitListReader;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.Locator1Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator.StaticBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator._static.LocalSidsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.Routing1Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.routing.Srv6Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.LocatorsBuilder;
+
+public class Srv6ReaderFactory implements ReaderFactory {
+
+    @Inject
+    private FutureJVppCore vppApi;
+
+    @Inject
+    private LocalSidFunctionReadBindingRegistry bindingRegistry;
+
+    @Inject
+    protected LocatorContextManager locatorContext;
+
+    @Override
+    public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+
+        registry.addStructuralReader(Srv6IIds.RT_RT1_AUG, Routing1Builder.class);
+        registry.addStructuralReader(Srv6IIds.RT_SRV6, Srv6Builder.class);
+        registry.addStructuralReader(Srv6IIds.RT_SRV6_LOCATORS, LocatorsBuilder.class);
+        registry.addStructuralReader(Srv6IIds.RT_SRV6_LOCS_LOC_AUG, Locator1Builder.class);
+        registry.addStructuralReader(Srv6IIds.RT_SRV6_LOCS_LOC_STATIC, StaticBuilder.class);
+        registry.addStructuralReader(Srv6IIds.RT_SRV6_LOCS_LOC_ST_LOCALSIDS, LocalSidsBuilder.class);
+
+        registry.add(new GenericInitListReader<>(Srv6IIds.RT_SRV6_LOCS_LOCATOR,
+                new LocatorCustomizer(vppApi, locatorContext)));
+        registry.add(new GenericInitListReader<>(Srv6IIds.RT_SRV6_LOCS_LOC_ST_LS_SID,
+                new SidCustomizer(vppApi, bindingRegistry, locatorContext)));
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizer.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizer.java
new file mode 100644 (file)
index 0000000..3fc3398
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.srv6.read.sid.request.LocatorReadRequest;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+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.InitializingListReaderCustomizer;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.LocatorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocatorCustomizer extends FutureJVppCustomizer
+        implements InitializingListReaderCustomizer<Locator, LocatorKey, LocatorBuilder> {
+
+    private final LocatorContextManager locatorContext;
+
+    public LocatorCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+                             @Nonnull final LocatorContextManager locatorContext) {
+        super(futureJVppCore);
+        this.locatorContext = locatorContext;
+    }
+
+    @Nonnull
+    @Override
+    public Initialized<? extends DataObject> init(@Nonnull InstanceIdentifier<Locator> instanceIdentifier,
+                                                  @Nonnull Locator locator,
+                                                  @Nonnull ReadContext readContext) {
+        return Initialized.create(instanceIdentifier, locator);
+    }
+
+    @Nonnull
+    @Override
+    public List<LocatorKey> getAllIds(@Nonnull InstanceIdentifier<Locator> instanceIdentifier,
+                                      @Nonnull ReadContext readContext) throws ReadFailedException {
+        return new LocatorReadRequest(getFutureJVpp(), locatorContext).readAllKeys(instanceIdentifier, readContext);
+    }
+
+    @Override
+    public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Locator> locators) {
+        ((LocatorsBuilder) builder).setLocator(locators);
+    }
+
+    @Nonnull
+    @Override
+    public LocatorBuilder getBuilder(@Nonnull InstanceIdentifier<Locator> instanceIdentifier) {
+        return new LocatorBuilder();
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull InstanceIdentifier<Locator> instanceIdentifier,
+                                      @Nonnull LocatorBuilder locatorBuilder,
+                                      @Nonnull ReadContext readContext) throws ReadFailedException {
+        new LocatorReadRequest(getFutureJVpp(), locatorContext)
+                .readSpecific(instanceIdentifier, readContext, locatorBuilder);
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizer.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizer.java
new file mode 100644 (file)
index 0000000..58beb9d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid;
+
+import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.srv6.read.sid.request.LocalSidReadRequest;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistry;
+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.InitializingListReaderCustomizer;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator._static.LocalSidsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidKey;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SidCustomizer extends FutureJVppCustomizer
+        implements InitializingListReaderCustomizer<Sid, SidKey, SidBuilder> {
+
+    private final LocalSidFunctionReadBindingRegistry registry;
+    private final LocatorContextManager locatorContext;
+
+    public SidCustomizer(@Nonnull final FutureJVppCore futureJVppCore, LocalSidFunctionReadBindingRegistry registry,
+                         @Nonnull final LocatorContextManager locatorContext) {
+        super(futureJVppCore);
+        this.registry = registry;
+        this.locatorContext = locatorContext;
+    }
+
+    @Nonnull
+    @Override
+    public Initialized<? extends DataObject> init(@Nonnull InstanceIdentifier<Sid> instanceIdentifier,
+                                                  @Nonnull Sid sid,
+                                                  @Nonnull ReadContext readContext) {
+        return Initialized.create(instanceIdentifier, sid);
+    }
+
+    @Nonnull
+    @Override
+    public List<SidKey> getAllIds(@Nonnull InstanceIdentifier<Sid> instanceIdentifier, @Nonnull ReadContext readContext)
+            throws ReadFailedException {
+
+        return new LocalSidReadRequest(getFutureJVpp(), locatorContext, registry)
+                .readAllKeys(instanceIdentifier, readContext);
+    }
+
+    @Override
+    public void merge(@Nonnull Builder<? extends DataObject> builder, @Nonnull List<Sid> list) {
+        ((LocalSidsBuilder) builder).setSid(list);
+    }
+
+    @Nonnull
+    @Override
+    public SidBuilder getBuilder(@Nonnull InstanceIdentifier<Sid> instanceIdentifier) {
+        return new SidBuilder();
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull InstanceIdentifier<Sid> instanceIdentifier,
+                                      @Nonnull SidBuilder sidBuilder,
+                                      @Nonnull ReadContext readContext) throws ReadFailedException {
+        LocalSidReadRequest readRequest = new LocalSidReadRequest(getFutureJVpp(), locatorContext,
+                registry);
+        readRequest.readSpecific(instanceIdentifier, readContext, sidBuilder);
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequest.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequest.java
new file mode 100644 (file)
index 0000000..e1bd8d0
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid.request;
+
+import static java.lang.Integer.parseInt;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.googlecode.ipv6.IPv6NetworkMask;
+import io.fd.hc2vpp.srv6.read.ReadRequest;
+import io.fd.hc2vpp.srv6.util.JVppRequest;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistry;
+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.util.read.cache.DumpCacheManager;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDump;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+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.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX2;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6FuncOpcodeUnreserved;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocalSidReadRequest extends JVppRequest implements ReadRequest<Sid, SidKey, SidBuilder> {
+
+    private static final Map<Integer, Class<? extends Srv6EndpointType>> VPP_END_FUNC_REGISTER;
+    private static final SrLocalsidsDump STATIC_DUMP_REQUEST = new SrLocalsidsDump();
+    private static final SrLocalsidsDetailsReplyDump STATIC_EMPTY_REPLY = new SrLocalsidsDetailsReplyDump();
+
+    static {
+        VPP_END_FUNC_REGISTER = ImmutableMap.<Integer, Class<? extends Srv6EndpointType>>builder()
+                .put(1, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.End.class)
+                .put(2, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndX.class)
+                .put(3, org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndT.class)
+                .put(5, EndDX2.class)
+                .put(6, EndDX6.class)
+                .put(7, EndDX4.class)
+                .put(8, EndDT6.class)
+                .put(9, EndDT4.class)
+                .build();
+    }
+
+    private final DumpCacheManager<SrLocalsidsDetailsReplyDump, Void> dumpManager;
+    private final LocatorContextManager locatorContext;
+    private final LocalSidFunctionReadBindingRegistry registry;
+
+    public LocalSidReadRequest(final FutureJVppCore api,
+                               final LocatorContextManager locatorContext,
+                               final LocalSidFunctionReadBindingRegistry registry) {
+        super(api);
+        this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<SrLocalsidsDetailsReplyDump, Void>()
+                .acceptOnly(SrLocalsidsDetailsReplyDump.class)
+                .withExecutor((identifier, params) -> getReplyForRead(
+                        api.srLocalsidsDump(STATIC_DUMP_REQUEST).toCompletableFuture(), identifier))
+                .build();
+        this.locatorContext = locatorContext;
+        this.registry = registry;
+    }
+
+    /**
+     * Extracts Operational code (SRv6 endpoint function) from provided SID value. SID value consists of two parts.
+     * First part is Locator defined by its IPv6 address and length (stored in mappingContext referenced
+     * by locator name). Second part is Operational code (endpoint function). Locator length(number of bits) divides SID
+     * address to bits used for locator value and bits used for endpoint function.
+     *
+     * @see <a href="https://tools.ietf.org/html/draft-filsfils-spring-srv6-network-programming-04">
+     *     SRv6 network programming (SRv6 Segment)</a>
+     * @see <a href="https://tools.ietf.org/html/draft-raza-spring-srv6-yang-01">
+     *      *     SRv6 Yang (SRv6 Types)</a>
+     *
+     * @param sid provided SRv6 SIDs IPv6 address
+     * @param mappingContext mapping context which stores mapping for locator length
+     * @param locName locator name used as a key to retrieve locator length from mapping context
+     * @return operational code (endpoint function) of SRv6 SID address
+     */
+    private Srv6FuncOpcodeUnreserved extractOpCode(Ipv6Address sid, MappingContext mappingContext,
+                                                   final String locName) {
+        int locLength = LocatorContextManager.parseLength(locatorContext.getLocator(locName, mappingContext));
+        com.googlecode.ipv6.IPv6Address ip = com.googlecode.ipv6.IPv6Address.fromString(sid.getValue());
+        IPv6NetworkMask mask = IPv6NetworkMask.fromPrefixLength(locLength);
+        com.googlecode.ipv6.IPv6Address locator = ip.maskWithNetworkMask(mask);
+
+        long function = ip.toBigInteger().subtract(locator.toBigInteger()).longValue();
+
+        return new Srv6FuncOpcodeUnreserved(function);
+    }
+
+    @Override
+    @Nonnull
+    public List<SidKey> readAllKeys(@Nonnull InstanceIdentifier<Sid> identifier, @Nonnull ReadContext ctx)
+            throws ReadFailedException {
+        final LocatorKey key = Preconditions.checkNotNull(identifier.firstKeyOf(Locator.class),
+                "Identifier does not have %s ", LocatorKey.class);
+        String locator = key.getName();
+
+        return dumpManager.getDump(identifier, ctx.getModificationCache()).or(STATIC_EMPTY_REPLY).srLocalsidsDetails
+                .stream()
+                .filter(detail -> arrayToIpv6AddressNoZone(detail.addr.addr).getValue().contains(locator))
+                .map(srLocalsidsDetails -> extractOpCode(arrayToIpv6AddressNoZone(srLocalsidsDetails.addr.addr),
+                        ctx.getMappingContext(), locator))
+                .map(SidKey::new)
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void readSpecific(@Nonnull InstanceIdentifier<Sid> identifier, @Nonnull ReadContext ctx,
+                             @Nonnull SidBuilder builder)
+            throws ReadFailedException {
+        final SidKey sidKey = Preconditions.checkNotNull(identifier.firstKeyOf(Sid.class),
+                "Identifier does not contain %s ", SidKey.class);
+        final LocatorKey locatorKey = Preconditions.checkNotNull(identifier.firstKeyOf(Locator.class),
+                "Identifier does not contain %s ", Locator.class);
+
+        // VPP stores SID address as whole without defining locator and function parts (or locator length).
+        // It is necessary to split SID address to locator and function (operational code), because that is how SID
+        // is identified in model. Currently we use locatorContext to store locator length, so it is possible to split
+        // SID address back to locator (used as LocatorKey) and function (used as SidKey) or to construct SID from
+        // from locator and function (opCode)
+        Integer locLength = LocatorContextManager
+                .parseLength(locatorContext.getLocator(locatorKey.getName(), ctx.getMappingContext()));
+        Ipv6Address locator = LocatorContextManager
+                .parseLocator(locatorContext.getLocator(locatorKey.getName(), ctx.getMappingContext()));
+
+        Ipv6Address sidAddress =
+                parseSrv6SidAddress(locator.getValue(), locLength.toString(), sidKey.getOpcode().getValue());
+
+        dumpManager.getDump(identifier, ctx.getModificationCache()).or(STATIC_EMPTY_REPLY).srLocalsidsDetails
+                .stream()
+                .filter(detail -> Arrays.equals(detail.addr.addr, ipv6AddressNoZoneToArray(sidAddress)))
+                .findFirst()
+                .ifPresent(detail -> bindLocalSid(detail, ctx, locatorKey.getName(), sidAddress, builder));
+    }
+
+    private Ipv6Address parseSrv6SidAddress(final String locatorIp, final String locatorLength, final Long opcode) {
+        com.googlecode.ipv6.IPv6Address ip =
+                com.googlecode.ipv6.IPv6Address.fromString(locatorIp);
+        IPv6NetworkMask mask = IPv6NetworkMask.fromPrefixLength(parseInt(locatorLength));
+        com.googlecode.ipv6.IPv6Address srv6Sid = ip.maskWithNetworkMask(mask);
+        return new Ipv6Address(srv6Sid.add(opcode.intValue()).toString());
+    }
+
+    private void bindLocalSid(final SrLocalsidsDetails detail, final ReadContext readContext, final String locName,
+                              final Ipv6Address sidAddress, final SidBuilder builder) {
+        Class<? extends Srv6EndpointType> behaviorType = parseEndBehaviorType(detail.behavior);
+        Srv6FuncOpcodeUnreserved opcode = extractOpCode(sidAddress, readContext.getMappingContext(), locName);
+        builder.setEndBehaviorType(behaviorType).setKey(new SidKey(opcode)).setOpcode(opcode);
+        parseEndFunction(builder, detail, readContext);
+    }
+
+    private void parseEndFunction(SidBuilder builder, SrLocalsidsDetails detail, ReadContext readContext) {
+        registry.bind(detail, readContext, builder);
+    }
+
+    private Class<? extends Srv6EndpointType> parseEndBehaviorType(short behavior) {
+        return VPP_END_FUNC_REGISTER.get((int) behavior);
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequest.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequest.java
new file mode 100644 (file)
index 0000000..ff6316b
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid.request;
+
+import static io.fd.hc2vpp.srv6.Srv6Configuration.DEFAULT_LOCATOR_LENGTH;
+
+import com.google.common.base.Preconditions;
+import com.googlecode.ipv6.IPv6NetworkMask;
+import io.fd.hc2vpp.srv6.read.ReadRequest;
+import io.fd.hc2vpp.srv6.util.JVppRequest;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
+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.util.read.cache.DumpCacheManager;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDump;
+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.hc2vpp.params.xml.ns.yang.vpp.ietf.srv6.base.rev180613.VppSrv6FibLocatorAugment;
+import org.opendaylight.yang.gen.v1.urn.hc2vpp.params.xml.ns.yang.vpp.ietf.srv6.base.rev180613.VppSrv6FibLocatorAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.hc2vpp.params.xml.ns.yang.vpp.ietf.srv6.base.rev180613.vpp.srv6.fib.FibTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.locator.PrefixBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6LocatorLen;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.VniReference;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocatorReadRequest extends JVppRequest implements ReadRequest<Locator, LocatorKey, LocatorBuilder> {
+
+    private static final SrLocalsidsDump STATIC_DUMP_REQUEST = new SrLocalsidsDump();
+    private static final SrLocalsidsDetailsReplyDump STATIC_EMPTY_REPLY = new SrLocalsidsDetailsReplyDump();
+    private final DumpCacheManager<SrLocalsidsDetailsReplyDump, Void> dumpManager;
+    private final LocatorContextManager locatorCtx;
+
+    public LocatorReadRequest(final FutureJVppCore api, LocatorContextManager locatorCtx) {
+        super(api);
+        this.dumpManager = new DumpCacheManager.DumpCacheManagerBuilder<SrLocalsidsDetailsReplyDump, Void>()
+                .acceptOnly(SrLocalsidsDetailsReplyDump.class)
+                .withExecutor((identifier, params) -> getReplyForRead(
+                        api.srLocalsidsDump(STATIC_DUMP_REQUEST).toCompletableFuture(), identifier))
+                .build();
+        this.locatorCtx = locatorCtx;
+    }
+
+    private Ipv6Address extractLocator(Ipv6Address sid, final MappingContext mappingContext, String locName) {
+        /*
+        * TODO(HC2VPP-353): VPP does not support locator length, therefore it is necessary to use default value for
+        * locator length, if there is no other way of getting the value (e.g. hc2vpp starts with configuration already
+        * present in VPP).
+        * */
+        int locLength = locName == null
+                ? DEFAULT_LOCATOR_LENGTH
+                : LocatorContextManager.parseLength(locatorCtx.getLocator(locName, mappingContext));
+        com.googlecode.ipv6.IPv6Address ip = com.googlecode.ipv6.IPv6Address.fromString(sid.getValue());
+        IPv6NetworkMask mask = IPv6NetworkMask.fromPrefixLength(locLength);
+        // strip function part if present
+        ip = ip.maskWithNetworkMask(mask);
+        return new Ipv6AddressNoZone(ip.toString());
+    }
+
+    @Override
+    @Nonnull
+    public List<LocatorKey> readAllKeys(@Nonnull final InstanceIdentifier<Locator> identifier,
+                                        @Nonnull final ReadContext ctx)
+            throws ReadFailedException {
+        return dumpManager.getDump(identifier, ctx.getModificationCache()).or(STATIC_EMPTY_REPLY).srLocalsidsDetails
+                .stream()
+                .map(srLocalsidsDetails -> extractLocator(arrayToIpv6AddressNoZone(srLocalsidsDetails.addr.addr),
+                        ctx.getMappingContext(), null).getValue())
+                .map(LocatorKey::new)
+                .distinct()
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public void readSpecific(@Nonnull final InstanceIdentifier<Locator> identifier, @Nonnull final ReadContext ctx,
+                             @Nonnull LocatorBuilder builder) throws ReadFailedException {
+        final LocatorKey key = Preconditions.checkNotNull(identifier.firstKeyOf(Locator.class),
+                "Identifier does not have %s ", LocatorKey.class);
+        String locator = key.getName();
+
+        dumpManager.getDump(identifier, ctx.getModificationCache()).or(STATIC_EMPTY_REPLY).srLocalsidsDetails
+                .stream()
+                .filter(detail -> arrayToIpv6AddressNoZone(detail.addr.addr).getValue().contains(locator))
+                .findFirst()
+                .ifPresent(srLocalsidsDetails -> bindLocalSid(srLocalsidsDetails, ctx.getMappingContext(), locator,
+                        builder));
+    }
+
+    private void bindLocalSid(final SrLocalsidsDetails detail, final MappingContext mappingContext,
+                              final String locName, LocatorBuilder builder) {
+        Ipv6Address locator = extractLocator(arrayToIpv6AddressNoZone(detail.addr.addr), mappingContext, locName);
+        int locLength = LocatorContextManager.parseLength(locatorCtx.getLocator(locName, mappingContext));
+
+        builder.setKey(new LocatorKey(locator.getValue()))
+                .setName(locator.getValue())
+                .setPrefix(
+                        new PrefixBuilder()
+                                .setAddress(locator)
+                                .setLength(new Srv6LocatorLen((short) locLength))
+                                .build())
+                .setIsDefault(false)
+                .setEnable(true)
+                .addAugmentation(VppSrv6FibLocatorAugment.class, new VppSrv6FibLocatorAugmentBuilder()
+                        .setFibTable(new FibTableBuilder()
+                                .setAddressFamily(Ipv6.class)
+                                .setTableId(new VniReference(Integer.toUnsignedLong(detail.fibTable)))
+                                .build())
+                        .build());
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManager.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManager.java
new file mode 100644 (file)
index 0000000..6241ae8
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import io.fd.honeycomb.translate.MappingContext;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+
+/**
+ * Manages metadata for SRv6 plugin
+ */
+public interface LocatorContextManager {
+    String GROUP_IP = "ip";
+    String GROUP_PREFIX = "prefix";
+    Pattern IP_PREFIX_PATTERN = Pattern.compile("(?<ip>\\S.*)/(?<prefix>\\d{1,3})");
+
+    /**
+     * Creates metadata for locator. Existing mapping is overwritten if exists.
+     *
+     * @param name       locator name
+     * @param ipv6Prefix locator with locator length in form of Ipv6Prefix
+     * @param ctx        mapping context providing context data for current transaction
+     */
+    void addLocator(@Nonnull final String name, @Nonnull Ipv6Prefix ipv6Prefix, @Nonnull final MappingContext ctx);
+
+    /**
+     * Check whether metadata for given locator is present.
+     *
+     * @param name locator name
+     * @param ctx  mapping context providing context data for current transaction
+     * @return true if present, false otherwise
+     */
+    boolean containsLocator(@Nonnull final String name, @Nonnull final MappingContext ctx);
+
+    /**
+     * Retrieves locator IPv6 prefix for given locator IPv6 address. If not present, artificial name will be generated.
+     *
+     * @param name locator name
+     * @param ctx  mapping context providing context data for current transaction
+     * @return Locator prefix matching supplied locator address
+     */
+    Ipv6Prefix getLocator(@Nonnull final String name, @Nonnull final MappingContext ctx);
+
+    /**
+     * Removes locator metadata from current context.
+     *
+     * @param name locator name
+     * @param ctx  mapping context providing context data for current transaction
+     */
+    void removeLocator(@Nonnull final String name, @Nonnull final MappingContext ctx);
+
+    static Integer parseLength(@Nonnull final Ipv6Prefix prefix) {
+        Matcher matcher = IP_PREFIX_PATTERN.matcher(prefix.getValue());
+        checkArgument(matcher.matches(), "Could`t parse Locator length: {}", prefix);
+        return Integer.parseInt(matcher.group(GROUP_PREFIX));
+    }
+
+    static Ipv6Address parseLocator(@Nonnull final Ipv6Prefix prefix) {
+        Matcher matcher = IP_PREFIX_PATTERN.matcher(prefix.getValue());
+        checkArgument(matcher.matches(), "Could`t parse Locator: {}", prefix);
+        return new Ipv6Address(matcher.group(GROUP_IP));
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImpl.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImpl.java
new file mode 100644 (file)
index 0000000..aba852d
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.translate.MappingContext;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.Srv6LocatorContextAugmentation;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.Srv6LocatorMappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.srv6.locator.mappings.Srv6LocatorMapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.srv6.locator.mappings.Srv6LocatorMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.srv6.locator.mappings.Srv6LocatorMappingKey;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Facade on top of {@link MappingContext} that manages {@link Srv6LocatorMappings}.
+ */
+@ThreadSafe
+public final class LocatorContextManagerImpl implements LocatorContextManager {
+    private static final String SLASH = "/";
+    private final InstanceIdentifier<Srv6LocatorMappings> ctxIid;
+    private final Integer defaultLocatorLength;
+
+    public LocatorContextManagerImpl(@Nonnull final Integer defaultLocatorLength) {
+        checkArgument(defaultLocatorLength > 0 && defaultLocatorLength < 128,
+                "defaultLocatorLength is out of range(1-127).");
+        this.defaultLocatorLength = checkNotNull(defaultLocatorLength, "defaultLocatorLength should not be null");
+
+        this.ctxIid = InstanceIdentifier.create(Contexts.class)
+                .augmentation(Srv6LocatorContextAugmentation.class)
+                .child(Srv6LocatorMappings.class);
+    }
+
+    @Override
+    public void addLocator(@Nonnull final String name, @Nonnull Ipv6Prefix ipv6Prefix,
+                           @Nonnull final MappingContext ctx) {
+        final KeyedInstanceIdentifier<Srv6LocatorMapping, Srv6LocatorMappingKey> mappingIid = getLocatorIid(name);
+        final Srv6LocatorMappingBuilder builder = new Srv6LocatorMappingBuilder()
+                .setKey(new Srv6LocatorMappingKey(name)).setPrefix(ipv6Prefix).setName(name);
+        ctx.put(mappingIid, builder.build());
+    }
+
+    @Override
+    public boolean containsLocator(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        final Optional<Srv6LocatorMapping> read = ctx.read(getLocatorIid(name));
+        return read.isPresent();
+    }
+
+    @Override
+    public Ipv6Prefix getLocator(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        final Optional<Srv6LocatorMapping> read = ctx.read(getLocatorIid(name));
+        if (read.isPresent()) {
+            return read.get().getPrefix();
+        }
+
+        // construct artificial mapping with default locator length
+        Ipv6Prefix ipv6Prefix = new Ipv6Prefix(getArtificialName(name));
+        addLocator(getArtificialName(name), ipv6Prefix, ctx);
+        return ipv6Prefix;
+    }
+
+    @Override
+    public void removeLocator(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        ctx.delete(getLocatorIid(name));
+    }
+
+    private KeyedInstanceIdentifier<Srv6LocatorMapping, Srv6LocatorMappingKey> getLocatorIid(
+            @Nonnull final String locator) {
+        return ctxIid.child(Srv6LocatorMapping.class, new Srv6LocatorMappingKey(locator));
+    }
+
+    private synchronized String getArtificialName(String name) {
+        return name + SLASH + defaultLocatorLength;
+    }
+
+}
index d56656f..361f042 100644 (file)
@@ -28,23 +28,40 @@ import org.slf4j.LoggerFactory;
 abstract class LocalSidFunctionBindingRegistry<T extends LocalSidFunctionRequest> {
 
     private static final Logger LOG = LoggerFactory.getLogger(LocalSidFunctionBindingRegistry.class);
-    final List<LocalSidFunctionBinder<T>> binders;
+    final List<LocalSidFunctionWriteBinder<T>> wBinders;
+    final List<LocalSidFunctionReadBinder> rBinders;
+
 
     LocalSidFunctionBindingRegistry() {
-        binders = new ArrayList<>();
+        wBinders = new ArrayList<>();
+        rBinders = new ArrayList<>();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void registerWriteFunctionType(@Nonnull final LocalSidFunctionWriteBinder binder) {
+        checkNotNull(binder, "Cannot register null binder");
+        if (!isFunctionRegistered(binder)) {
+            wBinders.add(binder);
+        } else {
+            LOG.warn("Binder for class already registered. Canceling registration for {}.", binder);
+        }
+    }
+
+    private boolean isFunctionRegistered(@Nonnull final LocalSidFunctionWriteBinder binder) {
+        return wBinders.stream().parallel().anyMatch(locBinder -> locBinder.getClass().equals(binder.getClass()));
     }
 
     @SuppressWarnings("unchecked")
-    public void registerFunctionType(@Nonnull final LocalSidFunctionBinder binder) {
+    public void registerReadFunctionType(@Nonnull final LocalSidFunctionReadBinder binder) {
         checkNotNull(binder, "Cannot register null binder");
         if (!isFunctionRegistered(binder)) {
-            binders.add(binder);
+            rBinders.add(binder);
         } else {
             LOG.warn("Binder for class already registered. Canceling registration for {}.", binder);
         }
     }
 
-    private boolean isFunctionRegistered(@Nonnull final LocalSidFunctionBinder binder) {
-        return binders.stream().parallel().anyMatch(locBinder -> locBinder.getClass().equals(binder.getClass()));
+    private boolean isFunctionRegistered(@Nonnull final LocalSidFunctionReadBinder binder) {
+        return rBinders.stream().parallel().anyMatch(locBinder -> locBinder.getClass().equals(binder.getClass()));
     }
 }
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBinder.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBinder.java
new file mode 100644 (file)
index 0000000..ab624fb
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util.function;
+
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
+
+/**
+ * Binder interface, which is used to map local sid function requests from VPP to yang model data classes of
+ * local sid functions. It uses behavior function type integer value defined by VPP API, to find
+ * suitable binder. This value is translated to {@link Srv6EndpointType} in model, which represents the same endpoint
+ * function as defined by VPP API.
+ */
+public interface LocalSidFunctionReadBinder {
+
+    /**
+     * Translate data read From VPP to data defined by model
+     *
+     * @param data local sid details read from VPP
+     * @param ctx read context that contains modification cache and mapping chache
+     * @param builder builder for setting data
+     */
+    void translateFromDump(@Nonnull final SrLocalsidsDetails data, @Nonnull final ReadContext ctx,
+                           @Nonnull final SidBuilder builder);
+
+    /**
+     * Provide behavior function type integer value.
+     *
+     * @return integer value of behaviour function type as defined in VPP api
+     */
+    int getBehaviourFunctionType();
+
+    /**
+     * Checks whether this binder is able to process provided function from VPP
+     *
+     * @param functionCode integer value of behaviour function type as defined in VPP api
+     * @return true if endpoint function binder is able to process provided functionCode, false otherwise
+     */
+    default boolean canHandle(int functionCode) {
+        return getBehaviourFunctionType() == functionCode;
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistry.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistry.java
new file mode 100644 (file)
index 0000000..66586b9
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util.function;
+
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidFunctionRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.util.RWUtils;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+
+public class LocalSidFunctionReadBindingRegistry<T extends LocalSidFunctionRequest>
+        extends LocalSidFunctionBindingRegistry<T> {
+
+    public void bind(@Nonnull final SrLocalsidsDetails details, @Nonnull final ReadContext ctx,
+                     @Nonnull final SidBuilder builder) {
+        rBinders.parallelStream()
+                .filter(localSidFunctionBinder -> localSidFunctionBinder.canHandle(details.behavior))
+                .collect(RWUtils.singleItemCollector())
+                .translateFromDump(details, ctx, builder);
+    }
+}
diff --git a/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistryProvider.java b/srv6/srv6-impl/src/main/java/io/fd/hc2vpp/srv6/util/function/LocalSidFunctionReadBindingRegistryProvider.java
new file mode 100644 (file)
index 0000000..40e3053
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util.function;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.srv6.util.function.lookup.EndDT4FunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.lookup.EndDT6FunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.lookup.EndTFunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.nofunction.EndFunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.xconnect.EndDX2FunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.xconnect.EndDX4FunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.xconnect.EndDX6FunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.xconnect.EndXFunctionBinder;
+import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import javax.inject.Named;
+
+public class LocalSidFunctionReadBindingRegistryProvider implements Provider<LocalSidFunctionReadBindingRegistry> {
+
+    @Inject
+    @Named("interface-context")
+    private NamingContext interfaceContext;
+
+    @Inject
+    private FutureJVppCore api;
+    private final LocalSidFunctionReadBindingRegistry registry = new LocalSidFunctionReadBindingRegistry();
+
+    @Override
+    public LocalSidFunctionReadBindingRegistry get() {
+        registry.registerReadFunctionType(new EndFunctionBinder(api));
+        registry.registerReadFunctionType(new EndTFunctionBinder(api));
+        registry.registerReadFunctionType(new EndDT4FunctionBinder(api));
+        registry.registerReadFunctionType(new EndDT6FunctionBinder(api));
+        registry.registerReadFunctionType(new EndXFunctionBinder(api, interfaceContext));
+        registry.registerReadFunctionType(new EndDX2FunctionBinder(api, interfaceContext));
+        registry.registerReadFunctionType(new EndDX4FunctionBinder(api, interfaceContext));
+        registry.registerReadFunctionType(new EndDX6FunctionBinder(api, interfaceContext));
+
+        return registry;
+    }
+}
@@ -24,14 +24,14 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.
 
 /**
  * Binder interface, which is used to map yang model data classes of local sid functions to local sid function requests
- * used to configure endpoint functions on VPP. It uses behavior function type integer value defined by VPP API, to find
- * suitable binder. This value is translated to {@link Srv6EndpointType} in model, which represents the same endpoint
- * function as defined by VPP API.
+ * used to configure endpoint functions on VPP. It uses {@link Srv6EndpointType} class value, to find suitable binder.
+ * This value is translated to behavior function type integer value defined by VPP API, which represents the same
+ * function as defined by the model.
  *
  * @param <T> Type which extends general interface for {@link LocalSidFunctionRequest} and represents template binder
  *            that is used to process end function data represented by provided class type.
  */
-public interface LocalSidFunctionBinder<T extends LocalSidFunctionRequest> {
+public interface LocalSidFunctionWriteBinder<T extends LocalSidFunctionRequest> {
 
     /**
      * Binds request accordingly to type of function implemented by this interface
@@ -43,20 +43,14 @@ public interface LocalSidFunctionBinder<T extends LocalSidFunctionRequest> {
 
     /**
      * Provides Endpoint function type class.
+     *
      * @return Endpoint function class
      */
     @Nonnull
     Class<? extends Srv6EndpointType> getHandledFunctionType();
 
     /**
-     * Provide behavior function type integer value.
-     *
-     * @return integer value of behaviour function type as defined in VPP api
-     */
-    int getBehaviourFunctionType();
-
-    /**
-     * Checks whether binder can handle provided data
+     * Checks whether binder can handle provided Sid data from model
      *
      * @param data sid function data to be checked
      * @return true if function binder is able to process provided data, false otherwise
index b74a766..8558fb9 100644 (file)
@@ -26,7 +26,7 @@ public class LocalSidFunctionWriteBindingRegistry<T extends LocalSidFunctionRequ
         extends LocalSidFunctionBindingRegistry<T> {
 
     public LocalSidFunctionRequest bind(final Sid localSid, @Nonnull final WriteContext ctx) {
-        return binders.parallelStream()
+        return wBinders.parallelStream()
                 .filter(toLocalSidFunctionBinder -> toLocalSidFunctionBinder.canHandle(localSid))
                 .map(binder -> binder.createWriteRequestAndBind(localSid, ctx))
                 .collect(RWUtils.singleItemCollector());
index 20189b7..ead94c9 100644 (file)
@@ -42,14 +42,14 @@ public class LocalSidFunctionWriteBindingRegistryProvider implements Provider<Lo
 
     @Override
     public LocalSidFunctionWriteBindingRegistry get() {
-        registry.registerFunctionType(new EndFunctionBinder(api));
-        registry.registerFunctionType(new EndTFunctionBinder(api));
-        registry.registerFunctionType(new EndDT4FunctionBinder(api));
-        registry.registerFunctionType(new EndDT6FunctionBinder(api));
-        registry.registerFunctionType(new EndXFunctionBinder(api, interfaceContext));
-        registry.registerFunctionType(new EndDX2FunctionBinder(api, interfaceContext));
-        registry.registerFunctionType(new EndDX4FunctionBinder(api, interfaceContext));
-        registry.registerFunctionType(new EndDX6FunctionBinder(api, interfaceContext));
+        registry.registerWriteFunctionType(new EndFunctionBinder(api));
+        registry.registerWriteFunctionType(new EndTFunctionBinder(api));
+        registry.registerWriteFunctionType(new EndDT4FunctionBinder(api));
+        registry.registerWriteFunctionType(new EndDT6FunctionBinder(api));
+        registry.registerWriteFunctionType(new EndXFunctionBinder(api, interfaceContext));
+        registry.registerWriteFunctionType(new EndDX2FunctionBinder(api, interfaceContext));
+        registry.registerWriteFunctionType(new EndDX4FunctionBinder(api, interfaceContext));
+        registry.registerWriteFunctionType(new EndDX6FunctionBinder(api, interfaceContext));
 
         return registry;
     }
index e8ea224..67b7391 100644 (file)
@@ -18,15 +18,22 @@ package io.fd.hc2vpp.srv6.util.function.lookup;
 
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.srv6.write.sid.request.TableLookupLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDt4Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT4;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.TableId;
 
 public class EndDT4FunctionBinder extends TableLookupFunctionBinder {
 
+    private static final int END_DT4_FUNCTION_VALUE = 9;
+
     public EndDT4FunctionBinder(@Nonnull final FutureJVppCore api) {
         super(api);
     }
@@ -41,9 +48,21 @@ public class EndDT4FunctionBinder extends TableLookupFunctionBinder {
         return bindData(new TableLookupLocalSidRequest(getFutureJVpp()), lookupTable, false, ctx);
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        builder.setEndDt4(new EndDt4Builder()
+                .setLookupTableIpv4(new TableId(Integer.toUnsignedLong(data.xconnectIfaceOrVrfTable))).build());
+    }
+
     @Override
     @Nonnull
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
         return EndDT4.class;
     }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_DT4_FUNCTION_VALUE;
+    }
 }
index 01e6c6b..d9782a1 100644 (file)
@@ -18,15 +18,22 @@ package io.fd.hc2vpp.srv6.util.function.lookup;
 
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.srv6.write.sid.request.TableLookupLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDt6Builder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT6;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.TableId;
 
 public class EndDT6FunctionBinder extends TableLookupFunctionBinder {
 
+    private static final int END_DT6_FUNCTION_VALUE = 8;
+
     public EndDT6FunctionBinder(@Nonnull final FutureJVppCore api) {
         super(api);
     }
@@ -41,9 +48,21 @@ public class EndDT6FunctionBinder extends TableLookupFunctionBinder {
         return bindData(new TableLookupLocalSidRequest(getFutureJVpp()), lookupTable, true, ctx);
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        builder.setEndDt6(new EndDt6Builder()
+                .setLookupTableIpv6(new TableId(Integer.toUnsignedLong(data.xconnectIfaceOrVrfTable))).build());
+    }
+
     @Override
     @Nonnull
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
         return EndDT6.class;
     }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_DT6_FUNCTION_VALUE;
+    }
 }
index 13a2d3b..cd9a37c 100644 (file)
@@ -18,14 +18,22 @@ package io.fd.hc2vpp.srv6.util.function.lookup;
 
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.srv6.write.sid.request.TableLookupLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndTBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndT;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.TableId;
 
 public class EndTFunctionBinder extends TableLookupFunctionBinder {
 
+    private static final int END_T_FUNCTION_VALUE = 3;
+
     public EndTFunctionBinder(@Nonnull FutureJVppCore api) {
         super(api);
     }
@@ -39,9 +47,22 @@ public class EndTFunctionBinder extends TableLookupFunctionBinder {
         return bindData(new TableLookupLocalSidRequest(getFutureJVpp()), lookupTable, true, ctx);
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        builder.setEndT(
+                new EndTBuilder().setLookupTableIpv6(new TableId(Integer.toUnsignedLong(data.xconnectIfaceOrVrfTable)))
+                        .build());
+    }
+
     @Override
     @Nonnull
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
-        return org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndT.class;
+        return EndT.class;
+    }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_T_FUNCTION_VALUE;
     }
 }
index 8e6ab4f..a775a78 100644 (file)
 
 package io.fd.hc2vpp.srv6.util.function.lookup;
 
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.collect.ImmutableMap;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.fib.management.FibManagementIIds;
-import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBinder;
 import io.fd.hc2vpp.srv6.write.sid.request.TableLookupLocalSidRequest;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
-import java.util.Map;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDT6;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndT;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.AddressFamilyIdentity;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.table.management.rev180521.Ipv6;
@@ -40,18 +33,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.fib.
 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 
 abstract class TableLookupFunctionBinder extends FutureJVppCustomizer
-        implements LocalSidFunctionBinder<TableLookupLocalSidRequest> {
-
-    private static final Map<Class<? extends Srv6EndpointType>, Integer> REGISTER = ImmutableMap.of(
-            EndT.class, 3,
-            EndDT6.class, 8,
-            EndDT4.class, 9
-    );
+        implements LocalSidFunctionWriteBinder<TableLookupLocalSidRequest>, LocalSidFunctionReadBinder {
 
     TableLookupFunctionBinder(@Nonnull final FutureJVppCore api) {
         super(api);
-        checkState(REGISTER.containsKey(getHandledFunctionType()),
-                "Unsupported type of Local SID function %s", getHandledFunctionType());
     }
 
     TableLookupLocalSidRequest bindData(TableLookupLocalSidRequest request, int tableIndex, final boolean isIpv6,
@@ -68,9 +53,4 @@ abstract class TableLookupFunctionBinder extends FutureJVppCustomizer
         request.setFunction(getBehaviourFunctionType());
         return request;
     }
-
-    @Override
-    public int getBehaviourFunctionType() {
-        return REGISTER.get(getHandledFunctionType());
-    }
 }
index a1952e3..4d7ad69 100644 (file)
@@ -18,16 +18,22 @@ package io.fd.hc2vpp.srv6.util.function.nofunction;
 
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
-import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBinder;
 import io.fd.hc2vpp.srv6.write.sid.request.NoProtocolLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.End;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 public class EndFunctionBinder extends FutureJVppCustomizer implements
-        LocalSidFunctionBinder<NoProtocolLocalSidRequest> {
+        LocalSidFunctionWriteBinder<NoProtocolLocalSidRequest>, LocalSidFunctionReadBinder {
 
     private static final int END_FUNCTION_VALUE = 1;
 
@@ -45,10 +51,16 @@ public class EndFunctionBinder extends FutureJVppCustomizer implements
         return request;
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        builder.setEnd(new EndBuilder().build());
+    }
+
     @Nonnull
     @Override
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
-        return org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.End.class;
+        return End.class;
     }
 
     @Override
index 63de40b..551a211 100644 (file)
@@ -19,15 +19,22 @@ package io.fd.hc2vpp.srv6.util.function.xconnect;
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDx2Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.end.dx2.PathsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX2;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 public class EndDX2FunctionBinder extends XConnectFunctionBinder {
 
+    private static final int END_DX2_FUNCTION_VALUE = 5;
+
     public EndDX2FunctionBinder(@Nonnull final FutureJVppCore api, @Nonnull final NamingContext interfaceContext) {
         super(api, interfaceContext);
     }
@@ -48,9 +55,21 @@ public class EndDX2FunctionBinder extends XConnectFunctionBinder {
         return request;
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        String interfaceName = getInterfaceName(ctx.getMappingContext(), data.xconnectIfaceOrVrfTable);
+        builder.setEndDx2(new EndDx2Builder().setPaths(new PathsBuilder().setInterface(interfaceName).build()).build());
+    }
+
     @Nonnull
     @Override
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
         return EndDX2.class;
     }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_DX2_FUNCTION_VALUE;
+    }
 }
index 51abc98..cb8dbfe 100644 (file)
@@ -19,18 +19,30 @@ package io.fd.hc2vpp.srv6.util.function.xconnect;
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
 import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v4.PathsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v4.paths.Path;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v4.paths.PathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDx4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDx4Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.PathAttrsCmn;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX4;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 public class EndDX4FunctionBinder extends XConnectFunctionBinder {
 
+    private static final int END_DX4_FUNCTION_VALUE = 7;
+
     public EndDX4FunctionBinder(@Nonnull FutureJVppCore api, @Nonnull NamingContext interfaceContext) {
         super(api, interfaceContext);
     }
@@ -52,9 +64,31 @@ public class EndDX4FunctionBinder extends XConnectFunctionBinder {
         return request;
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        Ipv4AddressNoZone ipv4AddressNoZone = arrayToIpv4AddressNoZone(data.xconnectNhAddr4);
+        String interfaceName = getInterfaceName(ctx.getMappingContext(), data.xconnectIfaceOrVrfTable);
+        EndDx4 endDx4 = new EndDx4Builder().setPaths(new PathsBuilder().setPath(Collections.singletonList(
+                // TODO(HC2VPP-335): currently vpp allows to configure only one next hop
+                // therefore setting path index, role and weight to constants
+                new PathBuilder().setNextHop(ipv4AddressNoZone)
+                        .setInterface(interfaceName)
+                        .setPathIndex(DEFAULT_PATH_INDEX)
+                        .setWeight(DEFAULT_WEIGHT)
+                        .setRole(PathAttrsCmn.Role.PRIMARY)
+                        .build())).build()).build();
+        builder.setEndDx4(endDx4);
+    }
+
     @Nonnull
     @Override
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
         return EndDX4.class;
     }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_DX4_FUNCTION_VALUE;
+    }
 }
index 71194fb..3c12180 100644 (file)
@@ -19,18 +19,30 @@ package io.fd.hc2vpp.srv6.util.function.xconnect;
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
 import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.PathsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.paths.Path;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.paths.PathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDx6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndDx6Builder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.PathAttrsCmn;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX6;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 public class EndDX6FunctionBinder extends XConnectFunctionBinder {
 
+    private static final int END_DX6_FUNCTION_VALUE = 6;
+
     public EndDX6FunctionBinder(@Nonnull FutureJVppCore api, @Nonnull NamingContext interfaceContext) {
         super(api, interfaceContext);
     }
@@ -52,9 +64,31 @@ public class EndDX6FunctionBinder extends XConnectFunctionBinder {
         return request;
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        Ipv6AddressNoZone ipv6AddressNoZone = arrayToIpv6AddressNoZone(data.xconnectNhAddr6);
+        String interfaceName = getInterfaceName(ctx.getMappingContext(), data.xconnectIfaceOrVrfTable);
+        EndDx6 endDx6 = new EndDx6Builder().setPaths(new PathsBuilder().setPath(Collections.singletonList(
+                // TODO(HC2VPP-335): currently vpp allows to configure only one next hop
+                // therefore setting path index, role and weight to constants
+                new PathBuilder().setNextHop(ipv6AddressNoZone)
+                        .setInterface(interfaceName)
+                        .setPathIndex(DEFAULT_PATH_INDEX)
+                        .setWeight(DEFAULT_WEIGHT)
+                        .setRole(PathAttrsCmn.Role.PRIMARY)
+                        .build())).build()).build();
+        builder.setEndDx6(endDx6);
+    }
+
     @Nonnull
     @Override
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
         return EndDX6.class;
     }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_DX6_FUNCTION_VALUE;
+    }
 }
index 0b3af39..e153bd5 100644 (file)
@@ -19,17 +19,29 @@ package io.fd.hc2vpp.srv6.util.function.xconnect;
 import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
+import io.fd.honeycomb.translate.read.ReadContext;
 import io.fd.honeycomb.translate.write.WriteContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
+import java.util.Collections;
 import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.PathsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.paths.Path;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.multi.paths.v6.paths.PathBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6.sid.config.EndXBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.PathAttrsCmn;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndX;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 public class EndXFunctionBinder extends XConnectFunctionBinder {
 
+    private static final int END_X_FUNCTION_VALUE = 2;
+
     public EndXFunctionBinder(@Nonnull FutureJVppCore api, @Nonnull NamingContext interfaceContext) {
         super(api, interfaceContext);
     }
@@ -53,9 +65,33 @@ public class EndXFunctionBinder extends XConnectFunctionBinder {
         return request;
     }
 
+    @Override
+    public void translateFromDump(@Nonnull SrLocalsidsDetails data, @Nonnull ReadContext ctx,
+                                  @Nonnull final SidBuilder builder) {
+        Ipv6AddressNoZone ipv6AddressNoZone = arrayToIpv6AddressNoZone(data.xconnectNhAddr6);
+        String interfaceName = getInterfaceName(ctx.getMappingContext(), data.xconnectIfaceOrVrfTable);
+        EndXBuilder endX = new EndXBuilder()
+                // TODO(HC2VPP-335): currently vpp allows to configure only one next hop
+                // therefore setting path index, role and weight to constants
+                .setPaths(new PathsBuilder().setPath(Collections.singletonList(
+                        new PathBuilder()
+                                .setNextHop(ipv6AddressNoZone)
+                                .setInterface(interfaceName)
+                                .setPathIndex(DEFAULT_PATH_INDEX)
+                                .setWeight(DEFAULT_WEIGHT)
+                                .setRole(PathAttrsCmn.Role.PRIMARY)
+                                .build())).build());
+        builder.setEndX(endX.build());
+    }
+
     @Nonnull
     @Override
     public Class<? extends Srv6EndpointType> getHandledFunctionType() {
-        return org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndX.class;
+        return EndX.class;
+    }
+
+    @Override
+    public int getBehaviourFunctionType() {
+        return END_X_FUNCTION_VALUE;
     }
 }
index 9f69c90..eef5d96 100644 (file)
 
 package io.fd.hc2vpp.srv6.util.function.xconnect;
 
-import static com.google.common.base.Preconditions.checkState;
 import static java.lang.String.format;
 
-import com.google.common.collect.ImmutableMap;
 import io.fd.hc2vpp.common.translate.util.AddressTranslator;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBinder;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBinder;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
-import java.util.Map;
 import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX2;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndDX6;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndX;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6EndpointType;
 
 abstract class XConnectFunctionBinder extends FutureJVppCustomizer
-        implements LocalSidFunctionBinder<XConnectLocalSidRequest>, AddressTranslator {
-
-    private static final Map<Class<? extends Srv6EndpointType>, Integer>
-            REGISTER = ImmutableMap.of(EndX.class, 2,
-            EndDX2.class, 5,
-            EndDX4.class, 7,
-            EndDX6.class, 6);
+        implements LocalSidFunctionWriteBinder<XConnectLocalSidRequest>, LocalSidFunctionReadBinder, AddressTranslator {
 
     private final NamingContext interfaceContext;
+    static final long DEFAULT_WEIGHT = 1L;
+    static final short DEFAULT_PATH_INDEX = 1;
 
     XConnectFunctionBinder(@Nonnull final FutureJVppCore api, @Nonnull final NamingContext interfaceContext) {
         super(api);
         this.interfaceContext = interfaceContext;
-        checkState(REGISTER.containsKey(getHandledFunctionType()), "Unsupported type of Local SID function %s",
-                getHandledFunctionType());
     }
 
-    @Override
-    public int getBehaviourFunctionType() {
-        return REGISTER.get(getHandledFunctionType());
+    String getInterfaceName(final MappingContext ctx, final int index) {
+        return interfaceContext.getName(index, ctx);
+    }
+
+    protected int getVLanIndex(final MappingContext ctx, final String name) {
+        return interfaceContext.getIndex(name, ctx, () -> new IllegalArgumentException(
+                format("VLan with name %s not found", name)));
     }
 
     int getInterfaceIndex(final MappingContext ctx, final String name) {
index 5dea50f..d9f0229 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.srv6.write;
 import com.google.common.collect.ImmutableSet;
 import com.google.inject.Inject;
 import io.fd.hc2vpp.srv6.Srv6IIds;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
 import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBindingRegistry;
 import io.fd.hc2vpp.srv6.write.encap.source.EncapsulationSourceCustomizer;
 import io.fd.hc2vpp.srv6.write.sid.LocatorCustomizer;
@@ -36,6 +37,8 @@ public class Srv6WriterFactory implements WriterFactory {
     private FutureJVppCore futureJVppCore;
     @Inject
     private LocalSidFunctionWriteBindingRegistry bindingRegistry;
+    @Inject
+    protected LocatorContextManager locatorContext;
 
     @Override
     public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
@@ -43,7 +46,7 @@ public class Srv6WriterFactory implements WriterFactory {
         registry.add(new GenericWriter<>(Srv6IIds.RT_SRV6, new Srv6Customizer()));
 
         registry.subtreeAdd(ImmutableSet.of(Srv6IIds.LOC_PREFIX, Srv6IIds.LOC_FT_AUG, Srv6IIds.LOC_FT),
-                new GenericWriter<>(Srv6IIds.RT_SRV6_LOCS_LOCATOR, new LocatorCustomizer(futureJVppCore)));
+                new GenericWriter<>(Srv6IIds.RT_SRV6_LOCS_LOCATOR, new LocatorCustomizer(futureJVppCore, locatorContext)));
 
         registry.add(new GenericWriter<>(Srv6IIds.RT_SRV6_ENCAP, new EncapsulationSourceCustomizer(futureJVppCore)));
 
index 86ab359..41e838e 100644 (file)
 
 package io.fd.hc2vpp.srv6.write.sid;
 
+import com.google.common.base.Preconditions;
 import io.fd.hc2vpp.common.translate.util.FutureJVppCustomizer;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.translate.write.WriteContext;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
 import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 public class LocatorCustomizer extends FutureJVppCustomizer implements ListWriterCustomizer<Locator, LocatorKey> {
 
-    public LocatorCustomizer(@Nonnull final FutureJVppCore futureJVppCore) {
+    private final LocatorContextManager locatorCtx;
+
+    public LocatorCustomizer(@Nonnull final FutureJVppCore futureJVppCore,
+                             @Nonnull final LocatorContextManager locatorContext) {
         super(futureJVppCore);
+        this.locatorCtx = locatorContext;
     }
 
     @Override
     public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Locator> instanceIdentifier,
                                        @Nonnull final Locator locator, @Nonnull final WriteContext writeContext) {
-        // noop
+        Preconditions.checkNotNull(locator.getPrefix(), "Prefix should not be empty in locator: {}", locator);
+        Preconditions.checkNotNull(locator.getPrefix().getLength(),
+                "Length in prefix should not be empty for locator: {}", locator);
+        Ipv6Address locAddress = Preconditions.checkNotNull(locator.getPrefix().getAddress(),
+                "Address in prefix should not be empty for locator: {}", locator);
+        Short locLength = Preconditions.checkNotNull(locator.getPrefix().getLength().getValue(),
+                "Length in prefix should not be empty for locator: {}", locator);
+
+        locatorCtx.addLocator(locAddress.getValue(), new Ipv6Prefix(locAddress.getValue() + "/" + locLength),
+                writeContext.getMappingContext());
     }
 
     @Override
     public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Locator> instanceIdentifier,
                                         @Nonnull final Locator locator, @Nonnull final WriteContext writeContext) {
-        // noop
+        Preconditions.checkNotNull(locator.getPrefix(), "Prefix should not be empty in locator: {}", locator);
+        Ipv6Address locAddress = Preconditions.checkNotNull(locator.getPrefix().getAddress(),
+                "Address in prefix should not be empty for locator: {}", locator);
+
+        locatorCtx.removeLocator(locAddress.getValue(), writeContext.getMappingContext());
     }
 }
index c465dfb..54e4cdd 100644 (file)
@@ -31,10 +31,13 @@ import com.google.inject.name.Named;
 import com.google.inject.testing.fieldbinder.Bind;
 import com.google.inject.testing.fieldbinder.BoundFieldModule;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.srv6.read.Srv6ReaderFactory;
 import io.fd.hc2vpp.srv6.write.Srv6WriterFactory;
 import io.fd.hc2vpp.vpp.classifier.context.VppClassifierContextManager;
 import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder;
 import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder;
+import io.fd.honeycomb.translate.read.ReaderFactory;
 import io.fd.honeycomb.translate.util.YangDAG;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import io.fd.vpp.jvpp.core.future.FutureJVppCore;
@@ -44,6 +47,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.RoutingBuilder;
 
 public class Srv6ModuleTest {
 
@@ -74,6 +78,9 @@ public class Srv6ModuleTest {
     @Mock
     private VppClassifierContextManager classifierContextManager;
 
+    @Inject
+    private Set<ReaderFactory> readerFactories = new HashSet<>();
+
     @Inject
     private Set<WriterFactory> writerFactories = new HashSet<>();
 
@@ -84,6 +91,19 @@ public class Srv6ModuleTest {
         Guice.createInjector(new Srv6Module(), BoundFieldModule.of(this)).injectMembers(this);
     }
 
+    @Test
+    public void testReaderFactories() {
+        assertThat(readerFactories, is(not(empty())));
+
+        // Test registration process (all dependencies present, topological order of readers does exist, etc.)
+        final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(new YangDAG());
+        readerFactories.forEach(factory -> factory.init(registryBuilder));
+        registryBuilder.addStructuralReader(Srv6IIds.RT, RoutingBuilder.class);
+        assertNotNull(registryBuilder.build());
+        assertEquals(1, readerFactories.size());
+        assertTrue(readerFactories.iterator().next() instanceof Srv6ReaderFactory);
+    }
+
     @Test
     public void testWriterFactories() {
         assertThat(writerFactories, is(not(empty())));
diff --git a/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizerTest.java b/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/LocatorCustomizerTest.java
new file mode 100644 (file)
index 0000000..3f2a74f
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidRequestTest;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.types.Srv6Sid;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.LocatorsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+
+public class LocatorCustomizerTest extends LocalSidRequestTest {
+
+    private static final Ipv6Address SID_ADR = new Ipv6Address("a::101");
+
+    @Mock
+    private ReadContext readCtx;
+
+    @Mock
+    private ModificationCache modificationCache;
+
+    private SrLocalsidsDetailsReplyDump replyDump = new SrLocalsidsDetailsReplyDump();
+
+    @Override
+    protected void init() {
+        when(readCtx.getModificationCache()).thenReturn(modificationCache);
+        when(modificationCache.get(any())).thenReturn(replyDump);
+        when(locatorContext.getLocator(eq(LOCATOR.getName()), any())).thenReturn(new Ipv6Prefix("a::/64"));
+    }
+
+    @Test
+    public void getAllIdsTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        srLocalsidsDetails.behavior = 1;
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+
+        LocatorCustomizer customizer = new LocatorCustomizer(api, locatorContext);
+        List<LocatorKey> allIds = customizer.getAllIds(SID_A_101.firstIdentifierOf(Locator.class), readCtx);
+
+        Assert.assertNotNull(allIds);
+        Assert.assertFalse(allIds.isEmpty());
+        Assert.assertTrue(allIds.contains(SID_A_101.firstKeyOf(Locator.class)));
+    }
+
+    @Test
+    public void readCurrentAttributesTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        srLocalsidsDetails.behavior = 1;
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+
+        LocatorCustomizer customizer = new LocatorCustomizer(api, locatorContext);
+        LocatorBuilder builder = new LocatorBuilder();
+        customizer.readCurrentAttributes(SID_A_101.firstIdentifierOf(Locator.class), builder, readCtx);
+        Assert.assertEquals(SID_A_101.firstKeyOf(Locator.class), builder.getKey());
+        Assert.assertNotNull(customizer.getBuilder(SID_A_101.firstIdentifierOf(Locator.class)));
+
+        LocatorsBuilder parentBuilder = new LocatorsBuilder();
+        customizer.merge(parentBuilder, Collections.singletonList(builder.build()));
+
+        Assert.assertNotNull(parentBuilder.getLocator());
+        Assert.assertFalse(parentBuilder.getLocator().isEmpty());
+        Assert.assertTrue(parentBuilder.getLocator().contains(builder.build()));
+    }
+}
diff --git a/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizerTest.java b/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/SidCustomizerTest.java
new file mode 100644 (file)
index 0000000..419c431
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidRequestTest;
+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.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.types.Srv6Sid;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator._static.LocalSidsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidKey;
+
+public class SidCustomizerTest extends LocalSidRequestTest {
+
+    private static final Ipv6Address SID_ADR = new Ipv6Address("a::101");
+
+    @Mock
+    private ReadContext readCtx;
+
+    @Mock
+    private ModificationCache modificationCache;
+
+    @Mock
+    private MappingContext mappingContext;
+
+    private SrLocalsidsDetailsReplyDump replyDump = new SrLocalsidsDetailsReplyDump();
+
+    @Override
+    protected void init() {
+        when(readCtx.getModificationCache()).thenReturn(modificationCache);
+        when(modificationCache.get(any())).thenReturn(replyDump);
+        when(readCtx.getMappingContext()).thenReturn(mappingContext);
+        when(mappingContext.read(any())).thenReturn(Optional.of(LOCATOR));
+        when(locatorContext.getLocator(eq(LOCATOR.getName()), any())).thenReturn(new Ipv6Prefix("a::/64"));
+    }
+
+    @Test
+    public void getAllIdsTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        srLocalsidsDetails.behavior = 1;
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+
+        SidCustomizer customizer = new SidCustomizer(api, READ_REGISTRY, locatorContext);
+        List<SidKey> allIds = customizer.getAllIds(SID_A_101, readCtx);
+
+        Assert.assertNotNull(allIds);
+        Assert.assertFalse(allIds.isEmpty());
+        Assert.assertTrue(allIds.contains(SID_A_101.firstKeyOf(Sid.class)));
+    }
+
+    @Test
+    public void readCurrentAttributesTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        srLocalsidsDetails.behavior = 1;
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+
+        SidCustomizer customizer = new SidCustomizer(api, READ_REGISTRY, locatorContext);
+        SidBuilder builder = new SidBuilder();
+        customizer.readCurrentAttributes(SID_A_101, builder, readCtx);
+        Assert.assertEquals(SID_A_101.firstKeyOf(Sid.class), builder.getKey());
+        Assert.assertNotNull(builder.getEnd());
+        Assert.assertNotNull(customizer.getBuilder(SID_A_101));
+
+        LocalSidsBuilder parentBuilder = new LocalSidsBuilder();
+        customizer.merge(parentBuilder, Collections.singletonList(builder.build()));
+        Assert.assertNotNull(parentBuilder.getSid());
+        Assert.assertFalse(parentBuilder.getSid().isEmpty());
+        Assert.assertTrue(parentBuilder.getSid().contains(builder.build()));
+    }
+}
diff --git a/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequestTest.java b/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocalSidReadRequestTest.java
new file mode 100644 (file)
index 0000000..21668e3
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid.request;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidRequestTest;
+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.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.types.Srv6Sid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Routing;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.Locator1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator.Static;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.routing.srv6.locators.locator._static.LocalSids;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.Sid;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6._static.rev180301.srv6._static.cfg.SidKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.Routing1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.routing.Srv6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.Locators;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndT;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.EndX;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.types.rev180301.Srv6FuncOpcodeUnreserved;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocalSidReadRequestTest extends LocalSidRequestTest {
+
+    private static final String LOCAL_0 = "local0";
+    private static final String VLAN_0 = "vlan0";
+    private static final Ipv6Address SID_ADR = new Ipv6Address("a::100");
+    private static final Ipv6Address SID_ADR_2 = new Ipv6Address("a::101");
+    private static final Ipv6AddressNoZone ADDRESS_NO_ZONE = new Ipv6AddressNoZone(SID_ADR_2);
+    private static final long OPERATION = 256L; // 100 in hex IPv6 format
+    private static final InstanceIdentifier<Sid> ID_SID =
+            InstanceIdentifier.create(Routing.class)
+                    .augmentation(Routing1.class)
+                    .child(Srv6.class)
+                    .child(Locators.class)
+                    .child(Locator.class, new LocatorKey("a::"))
+                    .augmentation(Locator1.class)
+                    .child(Static.class)
+                    .child(LocalSids.class)
+                    .child(Sid.class, new SidKey(new Srv6FuncOpcodeUnreserved(OPERATION)));
+
+    @Mock
+    private ReadContext readCtx;
+
+    @Mock
+    private CompletionStage<SrLocalsidsDetailsReplyDump> stage;
+
+    @Mock
+    private CompletableFuture<SrLocalsidsDetailsReplyDump> detailsFuture;
+
+    @Mock
+    private ModificationCache modificationCache;
+
+    @Mock
+    private MappingContext mappingContext;
+
+    private SrLocalsidsDetailsReplyDump replyDump = new SrLocalsidsDetailsReplyDump();
+
+    @Override
+    protected void init() {
+        MockitoAnnotations.initMocks(this);
+        defineMapping(mappingContext, LOCAL_0, 1, "interface-context");
+        defineMapping(mappingContext, VLAN_0, 2, "interface-context");
+        replyDump.srLocalsidsDetails = new ArrayList<>();
+        when(ctx.getMappingContext()).thenReturn(mappingContext);
+        when(readCtx.getMappingContext()).thenReturn(mappingContext);
+        when(readCtx.getModificationCache()).thenReturn(modificationCache);
+        when(modificationCache.get(any())).thenReturn(replyDump);
+        when(api.srLocalsidsDump(any())).thenReturn(stage);
+        when(stage.toCompletableFuture()).thenReturn(detailsFuture);
+        when(locatorContext.getLocator(eq(LOCATOR.getName()), any())).thenReturn(new Ipv6Prefix("a::/64"));
+
+
+        try {
+            when(detailsFuture.get()).thenReturn(replyDump);
+        } catch (InterruptedException | ExecutionException e) {
+            // noop
+        }
+    }
+
+    @Test
+    public void readAllKeysTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+
+        SrLocalsidsDetails srLocalsidsDetails2 = new SrLocalsidsDetails();
+        Srv6Sid sid2 = new Srv6Sid();
+        sid2.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR_2));
+        srLocalsidsDetails2.addr = sid2;
+
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails2);
+
+        final LocalSidReadRequest request = new LocalSidReadRequest(api, locatorContext, READ_REGISTRY);
+        request.checkValid();
+        List<SidKey> sidKeys = request.readAllKeys(ID_SID, readCtx);
+
+        Assert.assertFalse(sidKeys.isEmpty());
+        Assert.assertEquals(2, sidKeys.size());
+    }
+
+    @Test
+    public void readSpecificEndXTest() throws ReadFailedException {
+        SrLocalsidsDetails endX = new SrLocalsidsDetails();
+        endX.behavior = 2;
+        endX.endPsp = 0;
+        endX.xconnectNhAddr6 = AddressTranslator.INSTANCE.ipv6AddressNoZoneToArray(SID_ADR_2);
+        endX.xconnectIfaceOrVrfTable = 1;
+
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        endX.addr = sid;
+
+        replyDump.srLocalsidsDetails.add(endX);
+
+        final LocalSidReadRequest request = new LocalSidReadRequest(api, locatorContext, READ_REGISTRY);
+        SidBuilder sidBuilder = new SidBuilder();
+        request.readSpecific(ID_SID, readCtx, sidBuilder);
+
+        Assert.assertNotNull(sidBuilder.getEndX());
+        Assert.assertEquals(EndX.class, sidBuilder.getEndBehaviorType());
+        Assert.assertEquals(OPERATION, sidBuilder.getOpcode().getValue().longValue());
+        Assert.assertNotNull(sidBuilder.getEndX().getPaths().getPath());
+        Assert.assertFalse(sidBuilder.getEndX().getPaths().getPath().isEmpty());
+        Assert.assertEquals(LOCAL_0, sidBuilder.getEndX().getPaths().getPath().get(0).getInterface());
+        Assert.assertEquals(ADDRESS_NO_ZONE, sidBuilder.getEndX().getPaths().getPath().get(0).getNextHop());
+    }
+
+
+    @Test
+    public void readSpecificEndTTest() throws ReadFailedException {
+        SrLocalsidsDetails endT = new SrLocalsidsDetails();
+        endT.behavior = 3;
+        endT.xconnectIfaceOrVrfTable = 4;
+        endT.endPsp = 0;
+
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        endT.addr = sid;
+
+        replyDump.srLocalsidsDetails.add(endT);
+
+        final LocalSidReadRequest request = new LocalSidReadRequest(api, locatorContext, READ_REGISTRY);
+        SidBuilder sidBuilder = new SidBuilder();
+        request.readSpecific(ID_SID, readCtx, sidBuilder);
+
+        Assert.assertNotNull(sidBuilder.getEndT());
+        Assert.assertEquals(EndT.class, sidBuilder.getEndBehaviorType());
+        Assert.assertEquals(OPERATION, sidBuilder.getOpcode().getValue().longValue());
+        Assert.assertEquals(4L, sidBuilder.getEndT().getLookupTableIpv6().getValue().longValue());
+    }
+}
diff --git a/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequestTest.java b/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/read/sid/request/LocatorReadRequestTest.java
new file mode 100644 (file)
index 0000000..404aa6b
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.read.sid.request;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidRequestTest;
+import io.fd.honeycomb.translate.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetailsReplyDump;
+import io.fd.vpp.jvpp.core.types.Srv6Sid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.routing.rev180313.Routing;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.Routing1;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.routing.Srv6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.Locators;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.Locator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.srv6.base.rev180301.srv6.locators.locators.LocatorKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocatorReadRequestTest extends LocalSidRequestTest {
+
+    private static final String LOCAL_0 = "local0";
+    private static final Ipv6Address SID_ADR = new Ipv6Address("a::100");
+    private static final Ipv6Address SID_ADR_2 = new Ipv6Address("b::101");
+    private static final InstanceIdentifier<Locator> ID_LOC =
+            InstanceIdentifier.create(Routing.class)
+                    .augmentation(Routing1.class)
+                    .child(Srv6.class)
+                    .child(Locators.class)
+                    .child(Locator.class, new LocatorKey("a::"));
+
+    @Mock
+    private ReadContext readCtx;
+
+    @Mock
+    private CompletionStage<SrLocalsidsDetailsReplyDump> stage;
+
+    @Mock
+    private CompletableFuture<SrLocalsidsDetailsReplyDump> detailsFuture;
+
+    @Mock
+    private ModificationCache modificationCache;
+
+    private SrLocalsidsDetailsReplyDump replyDump = new SrLocalsidsDetailsReplyDump();
+
+    @Override
+    protected void init() {
+        MockitoAnnotations.initMocks(this);
+        defineMapping(mappingContext, LOCAL_0, 1, "interface-context");
+        replyDump.srLocalsidsDetails = new ArrayList<>();
+        when(readCtx.getModificationCache()).thenReturn(modificationCache);
+        when(modificationCache.get(any())).thenReturn(replyDump);
+        when(api.srLocalsidsDump(any())).thenReturn(stage);
+        when(stage.toCompletableFuture()).thenReturn(detailsFuture);
+        when(locatorContext.getLocator(eq(LOCATOR.getName()), any())).thenReturn(new Ipv6Prefix("a::/64"));
+
+        try {
+            when(detailsFuture.get()).thenReturn(replyDump);
+        } catch (InterruptedException | ExecutionException e) {
+            // noop
+        }
+    }
+
+    @Test
+    public void readAllKeysTest() throws ReadFailedException {
+        SrLocalsidsDetails srLocalsidsDetails = new SrLocalsidsDetails();
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        srLocalsidsDetails.addr = sid;
+
+        SrLocalsidsDetails srLocalsidsDetails2 = new SrLocalsidsDetails();
+        Srv6Sid sid2 = new Srv6Sid();
+        sid2.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR_2));
+        srLocalsidsDetails2.addr = sid2;
+
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails);
+        replyDump.srLocalsidsDetails.add(srLocalsidsDetails2);
+
+        final LocatorReadRequest request = new LocatorReadRequest(api, locatorContext);
+        request.checkValid();
+        List<LocatorKey> locatorKeys = request.readAllKeys(ID_LOC, readCtx);
+
+        Assert.assertFalse(locatorKeys.isEmpty());
+        Assert.assertEquals(2, locatorKeys.size());
+        Assert.assertTrue(locatorKeys.contains(new LocatorKey("a::")));
+        Assert.assertTrue(locatorKeys.contains(new LocatorKey("b::")));
+    }
+
+    @Test
+    public void readSpecificEndXTest() throws ReadFailedException {
+        SrLocalsidsDetails endX = new SrLocalsidsDetails();
+        endX.behavior = 2;
+        endX.endPsp = 0;
+        endX.xconnectNhAddr6 = AddressTranslator.INSTANCE.ipv6AddressNoZoneToArray(SID_ADR_2);
+        endX.xconnectIfaceOrVrfTable = 1;
+
+        Srv6Sid sid = new Srv6Sid();
+        sid.addr = AddressTranslator.INSTANCE.ipAddressToArray(new IpAddress(SID_ADR));
+        endX.addr = sid;
+
+        replyDump.srLocalsidsDetails.add(endX);
+
+        final LocatorReadRequest request = new LocatorReadRequest(api, locatorContext);
+        LocatorBuilder builder = new LocatorBuilder();
+        request.readSpecific(ID_LOC, readCtx, builder);
+
+        Assert.assertEquals(new LocatorKey("a::"), builder.getKey());
+    }
+}
index 0bc3f6b..cd33699 100644 (file)
@@ -21,6 +21,7 @@ import com.google.inject.Inject;
 import io.fd.hc2vpp.common.test.util.FutureProducer;
 import io.fd.hc2vpp.common.test.util.NamingContextHelper;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionReadBindingRegistry;
 import io.fd.hc2vpp.srv6.util.function.LocalSidFunctionWriteBindingRegistry;
 import io.fd.hc2vpp.srv6.util.function.lookup.EndDT4FunctionBinder;
 import io.fd.hc2vpp.srv6.util.function.lookup.EndDT6FunctionBinder;
@@ -43,6 +44,8 @@ import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
 
 @RunWith(HoneycombTestRunner.class)
 public abstract class JvppRequestTest implements FutureProducer, NamingContextHelper {
+    protected static final LocalSidFunctionReadBindingRegistry READ_REGISTRY =
+            new LocalSidFunctionReadBindingRegistry();
     protected static final LocalSidFunctionWriteBindingRegistry WRITE_REGISTRY =
             new LocalSidFunctionWriteBindingRegistry();
 
@@ -69,14 +72,22 @@ public abstract class JvppRequestTest implements FutureProducer, NamingContextHe
         EndDX2FunctionBinder endDX2FunctionBinder = new EndDX2FunctionBinder(api, interfaceContext);
         EndDX4FunctionBinder endDX4FunctionBinder = new EndDX4FunctionBinder(api, interfaceContext);
         EndDX6FunctionBinder endDX6FunctionBinder = new EndDX6FunctionBinder(api, interfaceContext);
-        WRITE_REGISTRY.registerFunctionType(endFunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endTFunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endDT4FunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endDT6FunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endXFunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endDX2FunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endDX4FunctionBinder);
-        WRITE_REGISTRY.registerFunctionType(endDX6FunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endFunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endTFunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endDT4FunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endDT6FunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endXFunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endDX2FunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endDX4FunctionBinder);
+        READ_REGISTRY.registerReadFunctionType(endDX6FunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endFunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endTFunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endDT4FunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endDT6FunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endXFunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endDX2FunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endDX4FunctionBinder);
+        WRITE_REGISTRY.registerWriteFunctionType(endDX6FunctionBinder);
         init();
     }
 
diff --git a/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImplTest.java b/srv6/srv6-impl/src/test/java/io/fd/hc2vpp/srv6/util/LocatorContextManagerImplTest.java
new file mode 100644 (file)
index 0000000..919e013
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2018 Bell Canada, Pantheon Technologies 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.srv6.util;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.srv6.write.sid.request.LocalSidRequestTest;
+import io.fd.honeycomb.translate.MappingContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.srv6.locator.mappings.Srv6LocatorMapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.locator.context.rev180605.srv6.locator.context.attributes.srv6.locator.mappings.Srv6LocatorMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class LocatorContextManagerImplTest extends LocalSidRequestTest {
+
+    private static final Ipv6Prefix LOCATOR_PREFIX = new Ipv6Prefix("a::/64");
+
+    @Mock
+    MappingContext mappingContext;
+
+    @Captor
+    ArgumentCaptor<Srv6LocatorMapping> locMappingCaptor;
+
+    @Captor
+    ArgumentCaptor<InstanceIdentifier<Srv6LocatorMapping>> iidCaptor;
+
+    @Before
+    public void setup() {
+        Srv6LocatorMapping locatorMapping =
+                new Srv6LocatorMappingBuilder().setName(LOCATOR.getName()).setPrefix(LOCATOR_PREFIX).build();
+        when(ctx.getMappingContext()).thenReturn(mappingContext);
+        when(mappingContext.read(any())).thenReturn(Optional.of(locatorMapping));
+    }
+
+    @Test
+    public void addLocatorTest() {
+        LocatorContextManagerImpl contextManager = new LocatorContextManagerImpl(64);
+        contextManager.addLocator(LOCATOR.getName(), LOCATOR_PREFIX, ctx.getMappingContext());
+        verify(mappingContext, times(1)).put(any(), locMappingCaptor.capture());
+        Srv6LocatorMapping mapping = locMappingCaptor.getValue();
+
+        Assert.assertEquals(mapping.getPrefix(), LOCATOR_PREFIX);
+        Assert.assertEquals(mapping.getName(), LOCATOR.getName());
+    }
+
+    @Test
+    public void containsLocatorTest() {
+        LocatorContextManagerImpl contextManager = new LocatorContextManagerImpl(64);
+        boolean containsLocator = contextManager.containsLocator(LOCATOR.getName(), ctx.getMappingContext());
+        Assert.assertTrue(containsLocator);
+    }
+
+
+    @Test
+    public void getLocatorTest() {
+        LocatorContextManagerImpl contextManager = new LocatorContextManagerImpl(64);
+        Ipv6Prefix locator = contextManager.getLocator(LOCATOR.getName(), ctx.getMappingContext());
+        Assert.assertEquals(LOCATOR_PREFIX, locator);
+    }
+
+    @Test
+    public void removeLocatorTest() {
+        MappingContext mappingContext = ctx.getMappingContext();
+        LocatorContextManagerImpl contextManager = new LocatorContextManagerImpl(64);
+        contextManager.removeLocator(LOCATOR.getName(), mappingContext);
+        verify(mappingContext, times(1)).delete(iidCaptor.capture());
+        Assert.assertEquals(LOCATOR.getName(), iidCaptor.getValue().firstKeyOf(Srv6LocatorMapping.class).getName());
+    }
+}
index 66ddf48..998916e 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.srv6.util.function;
 import static org.mockito.Mockito.when;
 
 import com.google.common.base.Optional;
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
 import io.fd.hc2vpp.fib.management.FibManagementIIds;
 import io.fd.hc2vpp.srv6.util.JvppRequestTest;
 import io.fd.hc2vpp.srv6.write.sid.request.LocalSidFunctionRequest;
@@ -26,6 +27,7 @@ import io.fd.hc2vpp.srv6.write.sid.request.NoProtocolLocalSidRequest;
 import io.fd.hc2vpp.srv6.write.sid.request.TableLookupLocalSidRequest;
 import io.fd.hc2vpp.srv6.write.sid.request.XConnectLocalSidRequest;
 import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.vpp.jvpp.core.dto.SrLocalsidsDetails;
 import java.util.Collections;
 import org.junit.Assert;
 import org.junit.Test;
@@ -113,6 +115,16 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(1, request.getFunction());
     }
 
+    @Test
+    public void testEndVpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 1;
+        details.endPsp = 0;
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEnd());
+    }
+
     @Test
     public void testEndX() {
         EndX endX = new EndXBuilder()
@@ -137,6 +149,20 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(1, xConnectRequest.getOutgoingInterfaceIndex());
     }
 
+    @Test
+    public void testEndXVpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 2;
+        details.endPsp = 0;
+        details.xconnectNhAddr6 = AddressTranslator.INSTANCE.ipv6AddressNoZoneToArray(A);
+        details.xconnectIfaceOrVrfTable = 1;
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndX());
+        Assert.assertEquals(LOCAL_0, builder.getEndX().getPaths().getPath().get(0).getInterface());
+        Assert.assertEquals(A_NO_ZONE, builder.getEndX().getPaths().getPath().get(0).getNextHop());
+    }
+
     @Test
     public void testEndDX2() {
         EndDx2 endDx2 = new EndDx2Builder().setPaths(
@@ -155,6 +181,17 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(1, xConnectRequest.getOutgoingInterfaceIndex());
     }
 
+    @Test
+    public void testEndDX2Vpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 5;
+        details.xconnectIfaceOrVrfTable = 1;
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndDx2());
+        Assert.assertEquals(LOCAL_0, builder.getEndDx2().getPaths().getInterface());
+    }
+
     @Test
     public void testEndDX6() {
         EndDx6 endDx6 = new EndDx6Builder()
@@ -177,6 +214,19 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(1, xConnectRequest.getOutgoingInterfaceIndex());
     }
 
+    @Test
+    public void testEndDX6Vpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 6;
+        details.xconnectIfaceOrVrfTable = 1;
+        details.xconnectNhAddr6 = AddressTranslator.INSTANCE.ipv6AddressNoZoneToArray(A);
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndDx6());
+        Assert.assertEquals(LOCAL_0, builder.getEndDx6().getPaths().getPath().get(0).getInterface());
+        Assert.assertEquals(A_NO_ZONE, builder.getEndDx6().getPaths().getPath().get(0).getNextHop());
+    }
+
     @Test
     public void testEndDX4() {
         EndDx4 endDx4 = new EndDx4Builder()
@@ -201,6 +251,19 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(1, xConnectRequest.getOutgoingInterfaceIndex());
     }
 
+    @Test
+    public void testEndDX4Vpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 7;
+        details.xconnectIfaceOrVrfTable = 1;
+        details.xconnectNhAddr4 = AddressTranslator.INSTANCE.ipv4AddressNoZoneToArray(A_V4);
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndDx4());
+        Assert.assertEquals(LOCAL_0, builder.getEndDx4().getPaths().getPath().get(0).getInterface());
+        Assert.assertEquals(A_V4, builder.getEndDx4().getPaths().getPath().get(0).getNextHop());
+    }
+
     @Test
     public void testEndT() {
         EndT endT = new EndTBuilder().setLookupTableIpv6(TABLE_ID_4).build();
@@ -216,6 +279,18 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(TABLE_ID_4.getValue().intValue(), tableLookupRequest.getLookupFibTable());
     }
 
+    @Test
+    public void testEndDTVpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 3;
+        details.xconnectIfaceOrVrfTable = TABLE_ID_4.getValue().intValue();
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndT());
+        Assert.assertEquals(TABLE_ID_4.getValue().intValue(),
+                builder.getEndT().getLookupTableIpv6().getValue().intValue());
+    }
+
     @Test
     public void testEndDT6() {
         EndDt6 endDt6 = new EndDt6Builder().setLookupTableIpv6(TABLE_ID_4).build();
@@ -230,6 +305,18 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         Assert.assertEquals(TABLE_ID_4.getValue().intValue(), tableLookupRequest.getLookupFibTable());
     }
 
+    @Test
+    public void testEndDT6Vpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 8;
+        details.xconnectIfaceOrVrfTable = TABLE_ID_4.getValue().intValue();
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndDt6());
+        Assert.assertEquals(TABLE_ID_4.getValue().intValue(),
+                builder.getEndDt6().getLookupTableIpv6().getValue().intValue());
+    }
+
     @Test
     public void testEndDT4() {
         EndDt4 endDt4 = new EndDt4Builder().setLookupTableIpv4(TABLE_ID_4).build();
@@ -243,4 +330,16 @@ public class LocalSidFunctionBindingRegistryTest extends JvppRequestTest {
         TableLookupLocalSidRequest tableLookupRequest = TableLookupLocalSidRequest.class.cast(request);
         Assert.assertEquals(TABLE_ID_4.getValue().intValue(), tableLookupRequest.getLookupFibTable());
     }
+
+    @Test
+    public void testEndDT4Vpp() {
+        SrLocalsidsDetails details = new SrLocalsidsDetails();
+        details.behavior = 9;
+        details.xconnectIfaceOrVrfTable = TABLE_ID_4.getValue().intValue();
+        SidBuilder builder = new SidBuilder();
+        READ_REGISTRY.bind(details, readCtx, builder);
+        Assert.assertNotNull(builder.getEndDt4());
+        Assert.assertEquals(TABLE_ID_4.getValue().intValue(),
+                builder.getEndDt4().getLookupTableIpv4().getValue().intValue());
+    }
 }
index 80cf47a..fa30c07 100644 (file)
@@ -25,6 +25,7 @@ import io.fd.hc2vpp.common.translate.util.AddressTranslator;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.srv6.Srv6IIds;
 import io.fd.hc2vpp.srv6.util.JvppRequestTest;
+import io.fd.hc2vpp.srv6.util.LocatorContextManager;
 import io.fd.vpp.jvpp.core.dto.SrLocalsidAddDel;
 import io.fd.vpp.jvpp.core.dto.SrLocalsidAddDelReply;
 import java.util.Arrays;
@@ -60,6 +61,9 @@ public abstract class LocalSidRequestTest extends JvppRequestTest {
             new PrefixBuilder().setLength(new Srv6LocatorLen((short) 64)).setAddress(new Ipv6Address("a::")).build())
             .build();
 
+    @Mock
+    protected static LocatorContextManager locatorContext;
+
     @Captor
     ArgumentCaptor<SrLocalsidAddDel> requestcaptor;