HONEYCOMB-310: readers&initializers for vpp and macip acls 42/4542/2
authorMarek Gradzki <[email protected]>
Tue, 3 Jan 2017 17:12:41 +0000 (18:12 +0100)
committerMarek Gradzki <[email protected]>
Wed, 4 Jan 2017 11:44:41 +0000 (12:44 +0100)
Change-Id: I8892479123091e43bf191c544b6628d6254be564
Signed-off-by: Marek Gradzki <[email protected]>
31 files changed:
acl/acl-api/src/main/yang/vpp-acl-context.yang [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/AclModule.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AclCustomizer.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/AclReaderFactory.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java [new file with mode: 0644]
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java
acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizerTest.java
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AclCustomizerTest.java [new file with mode: 0644]
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizerTest.java
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequestTest.java
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequestTest.java
acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/write/VppAclCustomizerTest.java
vpp-common/vpp-translate-utils/src/main/java/io/fd/hc2vpp/common/translate/util/Ipv6Translator.java

diff --git a/acl/acl-api/src/main/yang/vpp-acl-context.yang b/acl/acl-api/src/main/yang/vpp-acl-context.yang
new file mode 100644 (file)
index 0000000..fde7f63
--- /dev/null
@@ -0,0 +1,66 @@
+module vpp-acl-context {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:vpp:acl:context";
+    prefix "nc";
+
+    description "Context for vpp-acl assignment mapping";
+
+    revision "2017-01-04" {
+        description "Initial revision.";
+    }
+
+    import naming-context {
+        prefix "nc";
+    }
+
+    import yang-ext {
+        prefix "ext";
+    }
+
+    grouping vpp-acl-context-attributes {
+        container vpp-acl-mappings {
+            list vpp-acl-context {
+
+                key "name";
+
+                leaf name {
+                    type string;
+                    description "vpp-acl context name";
+                }
+
+                list acl-mapping {
+                    key "name";
+
+                    leaf name {
+                        type string;
+                        description "ACL name";
+                    }
+
+                    leaf index {
+                        type int32;
+                        description "ACL index";
+                    }
+
+                    list ace-mapping {
+                        key "name";
+
+                        leaf name {
+                            type string;
+                            description "ACEs name";
+                        }
+
+                        leaf index {
+                            type int32;
+                            description "ACE index";
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    augment /nc:contexts {
+        ext:augment-identifier "vpp-acl-context-augmentation";
+        uses vpp-acl-context-attributes;
+    }
+}
\ No newline at end of file
index f15119b..a97f57e 100644 (file)
@@ -22,10 +22,12 @@ import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.google.inject.multibindings.Multibinder;
 import com.google.inject.name.Names;
+import io.fd.hc2vpp.acl.read.factory.AclReaderFactory;
 import io.fd.hc2vpp.acl.read.factory.InterfaceAclReaderFactory;
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.acl.util.AclContextManagerImpl;
 import io.fd.hc2vpp.acl.write.factory.InterfaceAclWriterFactory;
 import io.fd.hc2vpp.acl.write.factory.VppAclWriterFactory;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.read.ReaderFactory;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
@@ -39,7 +41,7 @@ public class AclModule extends AbstractModule {
     public static final String STANDARD_ACL_CONTEXT_NAME = "standard-acl-context";
     public static final String STANDARD_LEARNED_ACL_NAME_PREFIX = "standard-learned-acl-";
     public static final String MAC_IP_ACL_CONTEXT_NAME = "mac-ip-acl-context";
-    public static final String MAC_IP_LEARNED_ACL_NAME_PREFIX = "mac-ip-acl-context";
+    public static final String MAC_IP_LEARNED_ACL_NAME_PREFIX = "mac-ip-learned-acl-";
 
     private static final Logger LOG = LoggerFactory.getLogger(AclModule.class);
 
@@ -62,11 +64,11 @@ public class AclModule extends AbstractModule {
         // binds JVpp Acl future facade
         bind(FutureJVppAclFacade.class).toProvider(jvppAclProviderClass).in(Singleton.class);
 
-        bind(NamingContext.class).annotatedWith(Names.named(STANDARD_ACL_CONTEXT_NAME))
-                .toInstance(new NamingContext(STANDARD_LEARNED_ACL_NAME_PREFIX, STANDARD_ACL_CONTEXT_NAME));
+        bind(AclContextManager.class).annotatedWith(Names.named(STANDARD_ACL_CONTEXT_NAME))
+                .toInstance(new AclContextManagerImpl(STANDARD_LEARNED_ACL_NAME_PREFIX, STANDARD_ACL_CONTEXT_NAME));
 
-        bind(NamingContext.class).annotatedWith(Names.named(MAC_IP_ACL_CONTEXT_NAME))
-                .toInstance(new NamingContext(MAC_IP_LEARNED_ACL_NAME_PREFIX, MAC_IP_ACL_CONTEXT_NAME));
+        bind(AclContextManager.class).annotatedWith(Names.named(MAC_IP_ACL_CONTEXT_NAME))
+                .toInstance(new AclContextManagerImpl(MAC_IP_LEARNED_ACL_NAME_PREFIX, MAC_IP_ACL_CONTEXT_NAME));
 
         final Multibinder<WriterFactory> writerFactoryMultibinder =
                 Multibinder.newSetBinder(binder(), WriterFactory.class);
@@ -76,6 +78,7 @@ public class AclModule extends AbstractModule {
         final Multibinder<ReaderFactory> readerFactoryMultibinder =
                 Multibinder.newSetBinder(binder(), ReaderFactory.class);
         readerFactoryMultibinder.addBinding().to(InterfaceAclReaderFactory.class);
+        readerFactoryMultibinder.addBinding().to(AclReaderFactory.class);
 
         LOG.info("Module Acl successfully configured");
     }
index 782c1c0..e222c21 100644 (file)
@@ -18,6 +18,7 @@ package io.fd.hc2vpp.acl.read;
 
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
@@ -58,14 +59,14 @@ abstract class AbstractVppAclCustomizer extends FutureJVppAclCustomizer
     ByteDataTranslator {
 
     private final NamingContext interfaceContext;
-    private final NamingContext standardAclContext;
+    private final AclContextManager standardAclContext;
 
     private final DumpCacheManager<AclInterfaceListDetailsReplyDump, Integer> aclReferenceDumpManager;
     private final DumpCacheManager<AclDetailsReplyDump, Integer> aclDumpManager;
 
     protected AbstractVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
                                        @Nonnull final NamingContext interfaceContext,
-                                       @Nonnull final NamingContext standardAclContext) {
+                                       @Nonnull final AclContextManager standardAclContext) {
         super(jVppAclFacade);
         this.interfaceContext = interfaceContext;
         this.standardAclContext = standardAclContext;
@@ -127,7 +128,7 @@ abstract class AbstractVppAclCustomizer extends FutureJVppAclCustomizer
             // dump message in vpp)
             final AclInterfaceListDetails aclDetails = dumpReply.get().aclInterfaceListDetails.get(0);
             return filterAcls(aclDetails)
-                .mapToObj(aclIndex -> standardAclContext.getName(aclIndex, context.getMappingContext()))
+                .mapToObj(aclIndex -> standardAclContext.getAclName(aclIndex, context.getMappingContext()))
                 .map(aclName -> new VppAclsKey(aclName, VppAcl.class))
                 .collect(Collectors.toList());
         } else {
@@ -155,13 +156,13 @@ abstract class AbstractVppAclCustomizer extends FutureJVppAclCustomizer
                                             @Nonnull final ReadContext ctx) throws ReadFailedException {
         final VppAclsKey vppAclsKey = id.firstKeyOf(VppAcls.class);
         final String aclName = vppAclsKey.getName();
-        final int aclIndex = standardAclContext.getIndex(aclName, ctx.getMappingContext());
+        final int aclIndex = standardAclContext.getAclIndex(aclName, ctx.getMappingContext());
 
         final Optional<AclDetailsReplyDump> dumpReply =
             aclDumpManager.getDump(id, ctx.getModificationCache(), aclIndex);
 
         if (dumpReply.isPresent() && !dumpReply.get().aclDetails.isEmpty()) {
-            // FIXME (model expects hex string, but tag is written and read as ascii string)
+            // TODO(HONEYCOMB-330): (model expects hex string, but tag is written and read as ascii string)
             // decide how tag should be handled (model change might be needed).
             builder.setName(aclName);
             builder.setType(vppAclsKey.getType());
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AclCustomizer.java
new file mode 100644 (file)
index 0000000..83fc318
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.read;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
+import io.fd.hc2vpp.acl.util.ace.AceConverter;
+import io.fd.hc2vpp.acl.util.protocol.IpProtocolReader;
+import io.fd.hc2vpp.common.translate.util.Ipv4Translator;
+import io.fd.hc2vpp.common.translate.util.Ipv6Translator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+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.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.vpp.jvpp.acl.dto.AclDetails;
+import io.fd.vpp.jvpp.acl.dto.AclDetailsReplyDump;
+import io.fd.vpp.jvpp.acl.dto.AclDump;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDetails;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDetailsReplyDump;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDump;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessListsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntriesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAcl;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class AclCustomizer extends FutureJVppAclCustomizer
+    implements InitializingListReaderCustomizer<Acl, AclKey, AclBuilder>, JvppReplyConsumer, Ipv6Translator,
+    Ipv4Translator, IpProtocolReader, AceConverter {
+
+    private static final Integer READ_ALL = -1;
+    private final AclContextManager standardAclContext;
+    private final AclContextManager macipAclContext;
+
+    private final DumpCacheManager<AclDetailsReplyDump, Integer> vppAclDumpManager;
+    private final DumpCacheManager<MacipAclDetailsReplyDump, Integer> macipAclDumpManager;
+
+    public AclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+                            @Nonnull final AclContextManager standardAclContext,
+                            @Nonnull final AclContextManager macipAclContext) {
+        super(jVppAclFacade);
+        this.standardAclContext = standardAclContext;
+        this.macipAclContext = macipAclContext;
+
+        vppAclDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<AclDetailsReplyDump, Integer>()
+            .withExecutor(createVppAclExecutor())
+            .acceptOnly(AclDetailsReplyDump.class)
+            .build();
+
+        macipAclDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<MacipAclDetailsReplyDump, Integer>()
+            .withExecutor(createMacipAclExecutor())
+            .acceptOnly(MacipAclDetailsReplyDump.class)
+            .build();
+    }
+
+    private EntityDumpExecutor<AclDetailsReplyDump, Integer> createVppAclExecutor() {
+        return (identifier, params) -> {
+            AclDump request = new AclDump();
+            request.aclIndex = params;
+            return getReplyForRead(getjVppAclFacade().aclDump(request).toCompletableFuture(), identifier);
+        };
+    }
+
+    private EntityDumpExecutor<MacipAclDetailsReplyDump, Integer> createMacipAclExecutor() {
+        return (identifier, params) -> {
+            MacipAclDump request = new MacipAclDump();
+            request.aclIndex = params;
+            return getReplyForRead(getjVppAclFacade().macipAclDump(request).toCompletableFuture(), identifier);
+        };
+    }
+
+    @Nonnull
+    @Override
+    public Initialized<? extends DataObject> init(@Nonnull final InstanceIdentifier<Acl> id,
+                                                  @Nonnull final Acl readValue,
+                                                  @Nonnull final ReadContext ctx) {
+        return Initialized.create(id, readValue);
+    }
+
+    @Nonnull
+    @Override
+    public List<AclKey> getAllIds(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final ReadContext context)
+        throws ReadFailedException {
+        final List<AclKey> keys = new ArrayList<>();
+
+        final Optional<AclDetailsReplyDump> vppAclDump =
+            vppAclDumpManager.getDump(id, context.getModificationCache(), READ_ALL);
+        if (vppAclDump.isPresent()) {
+            vppAclDump.get().aclDetails.stream()
+                .map(details -> standardAclContext.getAclName(details.aclIndex, context.getMappingContext()))
+                .forEach(name -> keys.add(new AclKey(name, VppAcl.class)));
+        }
+
+        final Optional<MacipAclDetailsReplyDump> macipAclDump =
+            macipAclDumpManager.getDump(id, context.getModificationCache(), READ_ALL);
+        if (macipAclDump.isPresent()) {
+            macipAclDump.get().macipAclDetails.stream()
+                .map(details -> macipAclContext.getAclName(details.aclIndex, context.getMappingContext()))
+                .forEach(name -> keys.add(new AclKey(name, VppMacipAcl.class)));
+        }
+
+        return keys;
+    }
+
+    @Override
+    public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Acl> readData) {
+        ((AccessListsBuilder)builder).setAcl(readData);
+    }
+
+    @Nonnull
+    @Override
+    public AclBuilder getBuilder(@Nonnull final InstanceIdentifier<Acl> id) {
+        return new AclBuilder();
+    }
+
+    @Override
+    public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final AclBuilder builder,
+                                      @Nonnull final ReadContext ctx) throws ReadFailedException {
+        final AclKey key = id.firstKeyOf(Acl.class);
+        builder.setKey(key);
+        final Class<? extends AclBase> aclType = key.getAclType();
+        final String name = key.getAclName();
+
+        if (aclType.equals(VppAcl.class)) {
+            final int index = standardAclContext.getAclIndex(name, ctx.getMappingContext());
+            final Optional<AclDetailsReplyDump> dump = vppAclDumpManager.getDump(id, ctx.getModificationCache(), index);
+
+            if (dump.isPresent() && !dump.get().aclDetails.isEmpty()) {
+                final java.util.Optional<AclDetails> detail = dump.get().aclDetails.stream()
+                    .filter(acl -> acl.aclIndex == index).findFirst();
+                if (detail.isPresent()) {
+                    builder.setAccessListEntries(new AccessListEntriesBuilder()
+                        .setAce(toStandardAces(name, detail.get().r, standardAclContext, ctx.getMappingContext()))
+                        .build());
+                }
+            }
+        } else if (aclType.equals(VppMacipAcl.class)) {
+            final int index = macipAclContext.getAclIndex(name, ctx.getMappingContext());
+            final Optional<MacipAclDetailsReplyDump> dump =
+                macipAclDumpManager.getDump(id, ctx.getModificationCache(), index);
+
+            if (dump.isPresent() && !dump.get().macipAclDetails.isEmpty()) {
+                final java.util.Optional<MacipAclDetails> detail =
+                    dump.get().macipAclDetails.stream().filter(acl -> acl.aclIndex == index).findFirst();
+                if (detail.isPresent()) {
+                    builder.setAccessListEntries(new AccessListEntriesBuilder()
+                        .setAce(toMacIpAces(name, detail.get().r, macipAclContext, ctx.getMappingContext()))
+                        .build());
+                }
+            }
+        } else {
+            throw new IllegalArgumentException("Unsupported acl type: " + aclType);
+        }
+    }
+}
index eaabb0b..8e5d0df 100644 (file)
@@ -16,6 +16,7 @@
 
 package io.fd.hc2vpp.acl.read;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.util.RWUtils;
 import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails;
@@ -36,7 +37,7 @@ public final class EgressVppAclCustomizer extends AbstractVppAclCustomizer {
 
     public EgressVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
                                   @Nonnull final NamingContext interfaceContext,
-                                  @Nonnull final NamingContext standardAclContext) {
+                                  @Nonnull final AclContextManager standardAclContext) {
         super(jVppAclFacade, interfaceContext, standardAclContext);
     }
 
index e8c79c9..5980662 100644 (file)
@@ -16,6 +16,7 @@
 
 package io.fd.hc2vpp.acl.read;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.util.RWUtils;
 import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails;
@@ -36,7 +37,7 @@ public final class IngressVppAclCustomizer extends AbstractVppAclCustomizer {
 
     public IngressVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
                                    @Nonnull final NamingContext interfaceContext,
-                                   @Nonnull final NamingContext standardAclContext) {
+                                   @Nonnull final AclContextManager standardAclContext) {
         super(jVppAclFacade, interfaceContext, standardAclContext);
     }
 
index 81799e1..23776fe 100644 (file)
@@ -20,6 +20,7 @@ import static io.fd.hc2vpp.acl.read.AbstractVppAclCustomizer.getAclCfgId;
 import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS;
 
 import com.google.common.base.Optional;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
@@ -61,11 +62,11 @@ public class VppMacIpAclCustomizer extends FutureJVppAclCustomizer
     private final DumpCacheManager<MacipAclDetailsReplyDump, Integer> macIpAclDumpManager;
     private final DumpCacheManager<MacipAclInterfaceGetReply, Void> interfaceMacIpAclDumpManager;
     private final NamingContext interfaceContext;
-    private final NamingContext macIpAclContext;
+    private final AclContextManager macIpAclContext;
 
     public VppMacIpAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
                                  @Nonnull final NamingContext interfaceContext,
-                                 @Nonnull final NamingContext macIpAclContext) {
+                                 @Nonnull final AclContextManager macIpAclContext) {
         super(jVppAclFacade);
 
         // for dumping of Mac-ip details
@@ -129,7 +130,7 @@ public class VppMacIpAclCustomizer extends FutureJVppAclCustomizer
             if (macIpDumpReply.isPresent() && !macIpDumpReply.get().macipAclDetails.isEmpty()) {
                 final MacipAclDetails details = macIpDumpReply.get().macipAclDetails.get(0);
 
-                builder.setName(macIpAclContext.getName(aclIndex, mappingContext));
+                builder.setName(macIpAclContext.getAclName(aclIndex, mappingContext));
                 builder.setType(
                     org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAcl.class);
                 if (details.tag != null && details.tag.length > 0) {
@@ -143,7 +144,7 @@ public class VppMacIpAclCustomizer extends FutureJVppAclCustomizer
             }
         } else {
             // this is valid state, so just logging
-            LOG.info("No Mac-ip ACL specified for Interface name={},index={}", interfaceName, interfaceIndex);
+            LOG.debug("No Mac-ip ACL specified for Interface name={},index={}", interfaceName, interfaceIndex);
         }
     }
 
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/AclReaderFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/AclReaderFactory.java
new file mode 100644 (file)
index 0000000..90c4afe
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.read.factory;
+
+import static io.fd.hc2vpp.acl.read.factory.InterfaceAclReaderFactory.ACL_EGRESS_IID;
+import static io.fd.hc2vpp.acl.read.factory.InterfaceAclReaderFactory.ACL_INGRESS_IID;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.hc2vpp.acl.AclModule;
+import io.fd.hc2vpp.acl.read.AclCustomizer;
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.acl.util.factory.AclFactory;
+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.acl.future.FutureJVppAclFacade;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessListsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class AclReaderFactory implements ReaderFactory, AclFactory {
+
+    @Inject
+    private FutureJVppAclFacade futureAclFacade;
+
+    @Inject
+    @Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
+    private AclContextManager standardAclContext;
+
+    @Inject
+    @Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
+    private AclContextManager macIpAClContext;
+
+    private static final InstanceIdentifier<AccessLists> ACLS_ID = InstanceIdentifier.create(AccessLists.class);
+    private static final InstanceIdentifier<Acl> ACL_ID = ACLS_ID.child(Acl.class);
+
+    @Override
+    public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+        registry.addStructuralReader(ACLS_ID, AccessListsBuilder.class);
+
+        // TODO(HONEYCOMB-331): initializer is not registered correctly when subtreeAddBefore is used,
+        // enable after fixing infra issue:
+
+//        registry.subtreeAddBefore(vppAclChildren(InstanceIdentifier.create(Acl.class)),
+//            new GenericInitListReader<>(ACL_ID,
+//                new AclCustomizer(futureAclFacade, standardAclContext, macIpAClContext)),
+//            ImmutableSet.of(ACL_INGRESS_IID, ACL_EGRESS_IID));
+
+        registry.addBefore(new GenericInitListReader<>(ACL_ID,
+                new AclCustomizer(futureAclFacade, standardAclContext, macIpAClContext)),
+            ImmutableSet.of(ACL_INGRESS_IID, ACL_EGRESS_IID));
+    }
+}
index 5b627fb..5b2c450 100644 (file)
@@ -22,6 +22,7 @@ import io.fd.hc2vpp.acl.AclModule;
 import io.fd.hc2vpp.acl.read.EgressVppAclCustomizer;
 import io.fd.hc2vpp.acl.read.IngressVppAclCustomizer;
 import io.fd.hc2vpp.acl.read.VppMacIpAclCustomizer;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.impl.read.GenericInitListReader;
 import io.fd.honeycomb.translate.impl.read.GenericInitReader;
@@ -50,11 +51,11 @@ public class InterfaceAclReaderFactory implements ReaderFactory {
 
     @Inject
     @Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
-    private NamingContext standardAclContext;
+    private AclContextManager standardAclContext;
 
     @Inject
     @Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
-    private NamingContext macIpAClContext;
+    private AclContextManager macIpAClContext;
 
     @Inject
     @Named("interface-context")
@@ -65,22 +66,22 @@ public class InterfaceAclReaderFactory implements ReaderFactory {
     private static final InstanceIdentifier<VppAclInterfaceStateAugmentation> VPP_ACL_AUG_IID =
         IFC_ID.augmentation(VppAclInterfaceStateAugmentation.class);
     private static final InstanceIdentifier<Acl> ACL_IID = VPP_ACL_AUG_IID.child(Acl.class);
+    static final InstanceIdentifier<Ingress> ACL_INGRESS_IID = ACL_IID.child(Ingress.class);
+    static final InstanceIdentifier<Egress> ACL_EGRESS_IID = ACL_IID.child(Egress.class);
 
     @Override
     public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
         registry.addStructuralReader(VPP_ACL_AUG_IID, VppAclInterfaceStateAugmentationBuilder.class);
         registry.addStructuralReader(ACL_IID, AclBuilder.class);
 
-        final InstanceIdentifier<Ingress> ingressInstanceIdentifier = ACL_IID.child(Ingress.class);
-        registry.addStructuralReader(ingressInstanceIdentifier, IngressBuilder.class);
-        registry.addAfter(new GenericInitListReader<>(ingressInstanceIdentifier.child(VppAcls.class),
+        registry.addStructuralReader(ACL_INGRESS_IID, IngressBuilder.class);
+        registry.addAfter(new GenericInitListReader<>(ACL_INGRESS_IID.child(VppAcls.class),
             new IngressVppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)), IFC_ID);
-        registry.addAfter(new GenericInitReader<>(ingressInstanceIdentifier.child(VppMacipAcl.class),
+        registry.addAfter(new GenericInitReader<>(ACL_INGRESS_IID.child(VppMacipAcl.class),
             new VppMacIpAclCustomizer(futureAclFacade, interfaceContext, macIpAClContext)), IFC_ID);
 
-        final InstanceIdentifier<Egress> egressInstanceIdentifier = ACL_IID.child(Egress.class);
-        registry.addStructuralReader(egressInstanceIdentifier, EgressBuilder.class);
-        registry.addAfter(new GenericInitListReader<>(egressInstanceIdentifier.child(VppAcls.class),
+        registry.addStructuralReader(ACL_EGRESS_IID, EgressBuilder.class);
+        registry.addAfter(new GenericInitListReader<>(ACL_EGRESS_IID.child(VppAcls.class),
             new EgressVppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)), IFC_ID);
     }
 }
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManager.java
new file mode 100644 (file)
index 0000000..377d4e1
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.util;
+
+import io.fd.honeycomb.translate.MappingContext;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
+
+/**
+ * Manages metadata for acl plugin
+ */
+public interface AclContextManager {
+
+    /**
+     * Creates metadata for ACL. Existing mapping is overwritten if exists.
+     * @param id   ACL index
+     * @param name ACL name
+     * @param aces list of aces used to create rule-name to index mapping
+     * @param ctx  mapping context providing context data for current transaction
+     */
+    void addAcl(final int id, @Nonnull final String name, @Nonnull final List<Ace> aces, @Nonnull final MappingContext ctx);
+
+    /**
+     * Check whether metadata for given ACL is present.
+     *
+     * @param name classify table name
+     * @param ctx  mapping context providing context data for current transaction
+     * @return true if present, false otherwise
+     */
+    boolean containsAcl(@Nonnull String name, @Nonnull final MappingContext ctx);
+
+    /**
+     * Returns ACL index associated with the given name.
+     *
+     * @param name ACL name
+     * @param ctx  mapping context providing context data for current transaction
+     * @return integer index value matching supplied ACL name
+     * @throws IllegalArgumentException if ACL was not found
+     */
+    int getAclIndex(@Nonnull final String name, @Nonnull final MappingContext ctx);
+
+    /**
+     * Retrieves ACL name for given id. If not present, artificial name will be generated.
+     *
+     * @param id  ACL index
+     * @param ctx mapping context providing context data for current transaction
+     * @return ACL name matching supplied index
+     */
+    String getAclName(final int id, @Nonnull final MappingContext ctx);
+
+    /**
+     * Removes ACL metadata from current context.
+     *
+     * @param name ACL name
+     * @param ctx  mapping context providing context data for current transaction
+     */
+    void removeAcl(@Nonnull final String name, @Nonnull final MappingContext ctx);
+
+    /**
+     * Retrieves ACE name associated with the given ACL and ACE index. If not present, artificial name will be
+     * generated.
+     *
+     * @param aclName ACL name
+     * @param aceIndex ACE index
+     * @param ctx      mapping context providing context data for current transaction
+     * @return name of vpp node
+     */
+    String getAceName(final String aclName, final int aceIndex, @Nonnull final MappingContext ctx);
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/AclContextManagerImpl.java
new file mode 100644 (file)
index 0000000..aa25c3e
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.util;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.Optional;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.util.RWUtils;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collector;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+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.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.VppAclContextAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.VppAclMappings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.VppAclContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.VppAclContextKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.AclMappingKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMapping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev170104.vpp.acl.context.attributes.vpp.acl.mappings.vpp.acl.context.acl.mapping.AceMappingKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Facade on top of {@link MappingContext} that manages {@link VppAclContext}.
+ */
+@ThreadSafe
+public final class AclContextManagerImpl implements AclContextManager {
+
+    private static final Collector<AclMapping, ?, AclMapping> SINGLE_ITEM_ACL_COLLECTOR =
+        RWUtils.singleItemCollector();
+
+    private static final Collector<AceMapping, ?, AceMapping> SINGLE_ITEM_ACE_COLLECTOR =
+        RWUtils.singleItemCollector();
+
+    private final InstanceIdentifier<VppAclContext> ctxIid;
+
+    private final String artificialNamePrefix;
+
+    public AclContextManagerImpl(@Nonnull final String artificialNamePrefix, @Nonnull final String aclContextName) {
+        this.artificialNamePrefix = requireNonNull(artificialNamePrefix, "artificialNamePrefix should not be null");
+        requireNonNull(aclContextName, "aclContextName should not be null");
+        this.ctxIid = InstanceIdentifier.create(Contexts.class)
+            .augmentation(VppAclContextAugmentation.class).child(VppAclMappings.class)
+            .child(VppAclContext.class, new VppAclContextKey(aclContextName));
+    }
+
+    @Override
+    public synchronized void addAcl(final int id, @Nonnull final String name, @Nonnull final List<Ace> aces,
+                                    @Nonnull final MappingContext ctx) {
+        final KeyedInstanceIdentifier<AclMapping, AclMappingKey> mappingIid = getAclIid(name);
+        final AclMappingBuilder aclMapping = new AclMappingBuilder().setIndex(id).setName(name);
+
+        final List<AceMapping> mappings = new ArrayList<>(aces.size());
+        int aceIndex = 0;
+        for (final Ace ace : aces) {
+            mappings.add(new AceMappingBuilder().setName(ace.getRuleName()).setIndex(aceIndex++).build());
+        }
+        aclMapping.setAceMapping(mappings);
+        ctx.put(mappingIid, aclMapping.build());
+    }
+
+    @Override
+    public synchronized boolean containsAcl(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        final Optional<AclMapping> read = ctx.read(getAclIid(name));
+        return read.isPresent();
+    }
+
+    @Override
+    public synchronized int getAclIndex(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        final Optional<AclMapping> read = ctx.read(getAclIid(name));
+        checkArgument(read.isPresent(), "No mapping stored for name: %s", name);
+        return read.get().getIndex();
+    }
+
+    @Override
+    public synchronized String getAclName(final int id, @Nonnull final MappingContext ctx) {
+        if (!containsAclName(id, ctx)) {
+            final String artificialName = getArtificialAclName(id);
+            addAcl(id, artificialName, Collections.emptyList(), ctx);
+        }
+
+        final Optional<VppAclContext> read = ctx.read(ctxIid);
+        checkState(read.isPresent(), "VppAclContext for index: %s is not present. But should be", id);
+
+        return read.get().getAclMapping().stream()
+            .filter(t -> t.getIndex().equals(id))
+            .collect(SINGLE_ITEM_ACL_COLLECTOR).getName();
+    }
+
+    private boolean containsAclName(final int id, @Nonnull final MappingContext mappingContext) {
+        final Optional<VppAclContext> read = mappingContext.read(ctxIid);
+        return read.isPresent() && read.get().getAclMapping().stream().anyMatch(t -> t.getIndex().equals(id));
+    }
+
+    private String getArtificialAclName(final int index) {
+        return artificialNamePrefix + index;
+    }
+
+    @Override
+    public synchronized void removeAcl(@Nonnull final String name, @Nonnull final MappingContext ctx) {
+        ctx.delete(getAclIid(name));
+    }
+
+    @Override
+    public synchronized String getAceName(@Nonnull final String aclName, final int aceIndex,
+                                          @Nonnull final MappingContext ctx) {
+        if (!containsAceName(aclName, aceIndex, ctx)) {
+            final String artificialName = getArtificialAceName(aceIndex);
+            addAce(aclName, aceIndex, artificialName, ctx);
+        }
+
+        final Optional<AclMapping> read = ctx.read(getAclIid(aclName));
+        checkState(read.isPresent(), "AclMapping for name: %s is not present. But should be", aclName);
+
+        return read.get().getAceMapping().stream()
+            .filter(t -> t.getIndex().equals(aceIndex))
+            .collect(SINGLE_ITEM_ACE_COLLECTOR).getName();
+    }
+
+    private boolean containsAceName(@Nonnull final String aclName, final int id, @Nonnull final MappingContext ctx) {
+        final Optional<AclMapping> read = ctx.read(getAclIid(aclName));
+        return read.isPresent() && read.get().getAceMapping().stream().anyMatch(t -> t.getIndex().equals(id));
+    }
+
+    private String getArtificialAceName(final int index) {
+        return artificialNamePrefix + "rule" + index;
+    }
+
+    private KeyedInstanceIdentifier<AclMapping, AclMappingKey> getAclIid(@Nonnull final String name) {
+        return ctxIid.child(AclMapping.class, new AclMappingKey(name));
+    }
+
+    private void addAce(@Nonnull final String aclName, final int aceIndex, @Nonnull final String aceName,
+                        @Nonnull final MappingContext ctx) {
+        final AceMappingBuilder aceMapping = new AceMappingBuilder();
+        aceMapping.setIndex(aceIndex);
+        aceMapping.setName(aceName);
+        final KeyedInstanceIdentifier<AceMapping, AceMappingKey> iid =
+            getAclIid(aclName).child(AceMapping.class, new AceMappingKey(aceName));
+        ctx.put(iid, aceMapping.build());
+    }
+}
index 3257878..3053fe9 100644 (file)
 
 package io.fd.hc2vpp.acl.util.ace;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.ace.extractor.MacIpAceDataExtractor;
 import io.fd.hc2vpp.acl.util.ace.extractor.StandardAceDataExtractor;
 import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer;
+import io.fd.honeycomb.translate.MappingContext;
 import io.fd.vpp.jvpp.acl.types.AclRule;
 import io.fd.vpp.jvpp.acl.types.MacipAclRule;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.AceKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.MatchesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodesBuilder;
 
 /**
- * Convert Ace's to vpp rules
+ * Convert between Ace's and vpp rules.
  */
 public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtractor, ProtoPreBindRuleProducer {
 
-
-    default MacipAclRule[] convertToMacIpAclRules(@Nonnull final List<Ace> aces) {
+    default MacipAclRule[] toMacIpAclRules(@Nonnull final List<Ace> aces) {
         return aces.stream()
                 .map(ace -> {
                     final VppMacipAce macIpAce = fromMacIpAce(ace);
@@ -61,7 +70,7 @@ public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtr
                 .toArray(new MacipAclRule[aces.size()]);
     }
 
-    default AclRule[] convertToStandardAclRules(@Nonnull final List<Ace> aces) {
+    default AclRule[] toStandardAclRules(@Nonnull final List<Ace> aces) {
         return aces.stream()
                 .map(ace -> {
                     final VppAce standardAce = fromStandardAce(ace);
@@ -85,10 +94,59 @@ public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtr
                         rule.dstIpPrefixLen = ipv4DestinationAddressPrefix(standardAce);
                     }
 
-
                     return rule;
                 })
                 .collect(Collectors.toList())
                 .toArray(new AclRule[aces.size()]);
     }
+
+    default List<Ace> toMacIpAces(final String aclName, @Nonnull MacipAclRule[] rules,
+                                  @Nonnull final AclContextManager macipAclContext,
+                                  @Nonnull final MappingContext mappingContext) {
+        final List<Ace> aces = new ArrayList<>(rules.length);
+        int i = 0;
+        for (final MacipAclRule rule : rules) {
+            final AceBuilder ace = new AceBuilder();
+            final VppMacipAceBuilder aceType = new VppMacipAceBuilder();
+            final VppMacipAceNodesBuilder nodes = new VppMacipAceNodesBuilder();
+            nodes.setAceIpVersion(ipVersion(rule));
+            nodes.setSourceMacAddress(sourceMac(rule));
+            nodes.setSourceMacAddressMask(sourceMacMask(rule));
+            aceType.setVppMacipAceNodes(nodes.build());
+
+            ace.setMatches(new MatchesBuilder().setAceType(aceType.build()).build());
+            ace.setActions(actions(rule.isPermit));
+
+            final String aceName = macipAclContext.getAceName(aclName, i++, mappingContext);
+            ace.setRuleName(aceName);
+            ace.setKey(new AceKey(aceName));
+
+            aces.add(ace.build());
+        }
+        return aces;
+    }
+
+    default List<Ace> toStandardAces(final String aclName, @Nonnull AclRule[] rules,
+                                     @Nonnull final AclContextManager standardAclContext,
+                                     @Nonnull final MappingContext mappingContext) {
+        final List<Ace> aces = new ArrayList<>(rules.length);
+        int i = 0;
+        for (final AclRule rule : rules) {
+            final AceBuilder ace = new AceBuilder();
+            final VppAceBuilder aceType = new VppAceBuilder();
+            final VppAceNodesBuilder nodes = new VppAceNodesBuilder();
+            nodes.setAceIpVersion(ipVersion(rule));
+            nodes.setIpProtocol(parseProtocol(rule));
+            aceType.setVppAceNodes(nodes.build());
+
+            ace.setMatches(new MatchesBuilder().setAceType(aceType.build()).build());
+            ace.setActions(actions(rule.isPermit));
+
+            final String aceName = standardAclContext.getAceName(aclName, i++, mappingContext);
+            ace.setRuleName(aceName);
+            ace.setKey(new AceKey(aceName));
+            aces.add(ace.build());
+        }
+        return aces;
+    }
 }
index a0d1990..4a29949 100644 (file)
 package io.fd.hc2vpp.acl.util.ace.extractor;
 
 import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.hc2vpp.common.translate.util.MacTranslator;
+import io.fd.vpp.jvpp.acl.types.MacipAclRule;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv4HeaderFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv6HeaderFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.AceIpVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.ace.ip.version.AceIpv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.vpp.macip.ace.nodes.ace.ip.version.AceIpv6Builder;
 
-public interface MacIpAceDataExtractor extends AddressTranslator {
+public interface MacIpAceDataExtractor extends AddressTranslator, MacTranslator {
 
     default VppMacipAce fromMacIpAce(@Nonnull final Ace ace) {
         return VppMacipAce.class.cast(ace.getMatches().getAceType());
@@ -80,4 +86,37 @@ public interface MacIpAceDataExtractor extends AddressTranslator {
         }
     }
 
+    default AceIpVersion ipVersion(final MacipAclRule rule) {
+        if (rule.isIpv6 == 0) {
+            return ip4Ace(rule);
+        } else {
+            return ip6Ace(rule);
+        }
+    }
+
+    default AceIpVersion ip4Ace(MacipAclRule rule) {
+        final AceIpv4Builder ipVersion = new AceIpv4Builder();
+        if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) {
+            ipVersion.setSourceIpv4Network(toIpv4Prefix(truncateIp4Array(rule.srcIpAddr), rule.srcIpPrefixLen));
+        }
+        return ipVersion.build();
+    }
+
+    default AceIpVersion ip6Ace(MacipAclRule rule) {
+        final AceIpv6Builder ipVersion = new AceIpv6Builder();
+        if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) {
+            ipVersion.setSourceIpv6Network(toIpv6Prefix(rule.srcIpAddr, rule.srcIpPrefixLen));
+        }
+        return ipVersion.build();
+    }
+
+    default MacAddress sourceMac(final MacipAclRule rule) {
+        return new MacAddress(byteArrayToMacSeparated(rule.srcMac));
+    }
+
+    default MacAddress sourceMacMask(final MacipAclRule rule) {
+        return new MacAddress(byteArrayToMacSeparated(rule.srcMacMask));
+    }
+
+
 }
index 2e7ccbd..6d395fb 100644 (file)
 
 package io.fd.hc2vpp.acl.util.ace.extractor;
 
-
 import com.google.common.collect.ImmutableMap;
+import io.fd.hc2vpp.acl.util.protocol.IpProtocolReader;
 import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer;
 import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import io.fd.vpp.jvpp.acl.types.AclRule;
 import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.ActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.PacketHandling;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.DenyBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.PermitBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv6HeaderFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.actions.packet.handling.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.actions.packet.handling.StatefulBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.AceIpVersion;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv4Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6Builder;
 
-
-public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBindRuleProducer {
+public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBindRuleProducer, IpProtocolReader {
 
     /**
      * Allowed packet-processing actions for Acl's
@@ -95,4 +103,52 @@ public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBin
                         String.format("Unsupported packet-handling action %s for ACE %s", action,
                                 ace.getRuleName())))).byteValue();
     }
+
+    default AceIpVersion ipVersion(final AclRule rule) {
+        if (rule.isIpv6 == 0) {
+            return ip4Ace(rule);
+        } else {
+            return ip6Ace(rule);
+        }
+    }
+
+    default AceIpVersion ip4Ace(final AclRule rule) {
+        final AceIpv4Builder ipVersion = new AceIpv4Builder();
+        if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) {
+            ipVersion.setSourceIpv4Network(toIpv4Prefix(truncateIp4Array(rule.srcIpAddr), rule.srcIpPrefixLen));
+        }
+        if (rule.dstIpAddr != null && rule.dstIpAddr.length != 0) {
+            ipVersion.setDestinationIpv4Network(toIpv4Prefix(truncateIp4Array(rule.dstIpAddr), rule.dstIpPrefixLen));
+        }
+        return ipVersion.build();
+    }
+
+    default AceIpVersion ip6Ace(final AclRule rule) {
+        final AceIpv6Builder ipVersion = new AceIpv6Builder();
+        if (rule.srcIpAddr != null && rule.srcIpAddr.length != 0) {
+            ipVersion.setSourceIpv6Network(toIpv6Prefix(rule.srcIpAddr, rule.srcIpPrefixLen));
+        }
+        if (rule.dstIpAddr != null && rule.dstIpAddr.length != 0) {
+            ipVersion.setDestinationIpv6Network(toIpv6Prefix(rule.dstIpAddr, rule.dstIpPrefixLen));
+        }
+        return ipVersion.build();
+    }
+
+    default Actions actions(final byte isPermit) {
+        final ActionsBuilder actions = new ActionsBuilder();
+        switch (isPermit) {
+            case 0:
+                actions.setPacketHandling(new DenyBuilder().setDeny(true).build());
+                break;
+            case 1:
+                actions.setPacketHandling(new PermitBuilder().setPermit(true).build());
+                break;
+            case 2:
+                actions.setPacketHandling(new StatefulBuilder().setPermit(true).build());
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported action: " + isPermit);
+        }
+        return actions.build();
+    }
 }
index 1fecc6c..eae4bab 100644 (file)
@@ -16,9 +16,9 @@
 
 package io.fd.hc2vpp.acl.util.acl;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.ace.AceConverter;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.honeycomb.translate.write.WriteFailedException;
 import io.fd.vpp.jvpp.acl.dto.AclAddReplace;
@@ -28,8 +28,10 @@ import io.fd.vpp.jvpp.acl.dto.MacipAclAdd;
 import io.fd.vpp.jvpp.acl.dto.MacipAclAddReply;
 import io.fd.vpp.jvpp.acl.dto.MacipAclDel;
 import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.List;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 /**
@@ -41,84 +43,91 @@ public interface AclWriter extends AclDataExtractor, AceConverter, JvppReplyCons
 
     default void addStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
                                 @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
-                                @Nonnull final NamingContext standardAclContext,
+                                @Nonnull final AclContextManager standardAclContext,
                                 @Nonnull final MappingContext mappingContext) throws WriteFailedException {
 
         final AclAddReplace request = new AclAddReplace();
 
         request.tag = getAclNameAsBytes(acl);
         request.aclIndex = ACL_INDEX_CREATE_NEW;
-        request.r = convertToStandardAclRules(getAces(acl));
+
+        final List<Ace> aces = getAces(acl);
+        request.r = toStandardAclRules(aces);
         request.count = request.r.length;
 
         final AclAddReplaceReply reply =
                 getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
 
         // maps new acl to returned index
-        standardAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext);
+        standardAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext);
     }
 
     // according to vpp team, this was tested extensively, and should work
     default void updateStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
                                    @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
-                                   @Nonnull final NamingContext standardAclContext,
+                                   @Nonnull final AclContextManager standardAclContext,
                                    @Nonnull final MappingContext mappingContext) throws WriteFailedException {
 
         final AclAddReplace request = new AclAddReplace();
 
         request.tag = getAclNameAsBytes(acl);
         // by setting existing index, request is resolved as update
-        request.aclIndex = standardAclContext.getIndex(acl.getAclName(), mappingContext);
-        request.r = convertToStandardAclRules(getAces(acl));
+        request.aclIndex = standardAclContext.getAclIndex(acl.getAclName(), mappingContext);
+
+        final List<Ace> aces = getAces(acl);
+        request.r = toStandardAclRules(aces);
         request.count = request.r.length;
 
-        getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
+        final AclAddReplaceReply reply = getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
 
+        // overwrites existing acl metadata (aces might have been changed):
+        standardAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext);
     }
 
-
     default void deleteStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
                                    @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
-                                   @Nonnull final NamingContext standardAclContext,
+                                   @Nonnull final AclContextManager standardAclContext,
                                    @Nonnull final MappingContext mappingContext) throws WriteFailedException {
 
         final AclDel request = new AclDel();
         final String aclName = acl.getAclName();
-        request.aclIndex = standardAclContext.getIndex(aclName, mappingContext);
+        request.aclIndex = standardAclContext.getAclIndex(aclName, mappingContext);
 
         getReplyForDelete(futureFacade.aclDel(request).toCompletableFuture(), id);
 
         // removes mapping after successful delete
-        standardAclContext.removeName(aclName, mappingContext);
+        standardAclContext.removeAcl(aclName, mappingContext);
     }
 
     default void addMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade,
                              @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
-                             @Nonnull final NamingContext macIpAclContext,
+                             @Nonnull final AclContextManager macIpAclContext,
                              @Nonnull final MappingContext mappingContext) throws WriteFailedException {
         final MacipAclAdd request = new MacipAclAdd();
 
         request.tag = getAclNameAsBytes(acl);
-        request.r = convertToMacIpAclRules(getAces(acl));
+
+        final List<Ace> aces = getAces(acl);
+        request.r = toMacIpAclRules(aces);
         request.count = request.r.length;
 
         final MacipAclAddReply reply = getReplyForWrite(futureFacade.macipAclAdd(request).toCompletableFuture(), id);
 
         // map mac-ip acl to returned index
-        macIpAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext);
+        macIpAclContext.addAcl(reply.aclIndex, acl.getAclName(), aces, mappingContext);
     }
 
     default void deleteMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade,
                                 @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
-                                @Nonnull final NamingContext macIpAclContext,
+                                @Nonnull final AclContextManager macIpAclContext,
                                 @Nonnull final MappingContext mappingContext) throws WriteFailedException {
         final MacipAclDel request = new MacipAclDel();
         final String aclName = acl.getAclName();
-        request.aclIndex = macIpAclContext.getIndex(aclName, mappingContext);
+        request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext);
 
         getReplyForDelete(futureFacade.macipAclDel(request).toCompletableFuture(), id);
 
-        macIpAclContext.removeName(aclName, mappingContext);
+        macIpAclContext.removeAcl(aclName, mappingContext);
     }
 
 
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/factory/AclFactory.java
new file mode 100644 (file)
index 0000000..4057d22
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.util.factory;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodes;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface AclFactory {
+
+    default Set<InstanceIdentifier<?>> vppAclChildren(final InstanceIdentifier<Acl> parentId) {
+        final InstanceIdentifier<Matches> matchesIid =
+            parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class);
+        return ImmutableSet.of(parentId.child(AccessListEntries.class),
+            parentId.child(AccessListEntries.class).child(Ace.class),
+            parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class),
+            parentId.child(AccessListEntries.class).child(Ace.class).child(Actions.class),
+            matchesIid,
+            matchesIid.child(VppMacipAceNodes.class),
+            matchesIid.child(VppAceNodes.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpCodeRange.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpTypeRange.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpCodeRange.class),
+            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpTypeRange.class),
+            matchesIid.child(VppAceNodes.class).child(UdpNodes.class),
+            matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(SourcePortRange.class),
+            matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(DestinationPortRange.class),
+            matchesIid.child(VppAceNodes.class).child(TcpNodes.class),
+            matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(SourcePortRange.class),
+            matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(DestinationPortRange.class),
+            matchesIid.child(VppAceNodes.class).child(OtherNodes.class)
+
+        );
+    }
+
+}
index e3c5b72..4447b75 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.util.iface.acl;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
@@ -46,7 +47,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat
     private InstanceIdentifier<Acl> identifier;
     private List<String> inputAclNames;
     private List<String> outputAclNames;
-    private NamingContext standardAclContext;
+    private AclContextManager standardAclContext;
     private NamingContext interfaceContext;
 
 
@@ -74,7 +75,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat
         return this;
     }
 
-    public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final NamingContext standardAclContext) {
+    public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final AclContextManager standardAclContext) {
         this.standardAclContext = standardAclContext;
         return this;
     }
@@ -155,7 +156,7 @@ public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDat
         request.nInput = (byte) inputAclNames.size();
         request.count = (byte) (inputAclNames.size() + outputAclNames.size());
         request.acls = Stream.concat(inputAclNames.stream(), outputAclNames.stream())
-                .mapToInt(aclName -> standardAclContext.getIndex(aclName, mappingContext))
+                .mapToInt(aclName -> standardAclContext.getAclIndex(aclName, mappingContext))
                 .toArray();
         return request;
     }
index f8d7263..882cfd6 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.util.iface.macip;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
 import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
@@ -41,7 +42,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp
     private final MappingContext mappingContext;
     private InstanceIdentifier<VppMacipAcl> identifier;
     private String aclName;
-    private NamingContext macIpAclContext;
+    private AclContextManager macIpAclContext;
     private NamingContext interfaceContext;
 
 
@@ -68,7 +69,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp
         return this;
     }
 
-    public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final NamingContext macIpAclContext) {
+    public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final AclContextManager macIpAclContext) {
         this.macIpAclContext = macIpAclContext;
         return this;
     }
@@ -96,7 +97,7 @@ public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, Jvpp
 
             MacipAclInterfaceAddDel request = new MacipAclInterfaceAddDel();
             request.isAdd = booleanToByte(isNew);
-            request.aclIndex = macIpAclContext.getIndex(aclName, mappingContext);
+            request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext);
             request.swIfIndex =
                     interfaceContext.getIndex(interfaceName, mappingContext);
 
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/IpProtocolReader.java
new file mode 100644 (file)
index 0000000..767baef
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.util.protocol;
+
+import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.ICMPV6_INDEX;
+import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.ICMP_INDEX;
+import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.TCP_INDEX;
+import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.UDP_INDEX;
+
+import io.fd.vpp.jvpp.acl.types.AclRule;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.IpProtocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Icmp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpV6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpV6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.OtherBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Tcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.TcpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Udp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.UdpBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6NodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodesBuilder;
+
+/**
+ * Utility for parsing IpProtocol DO based on data returned by vpp as {@link AclRule}.
+ */
+public interface IpProtocolReader {
+
+    default IpProtocol parseProtocol(final AclRule rule) {
+        switch (rule.proto) {
+            case ICMP_INDEX: {
+                return Impl.parseIcmp(rule);
+            }
+
+            case TCP_INDEX: {
+                return Impl.parseTcp(rule);
+            }
+
+            case UDP_INDEX: {
+                return Impl.parseUdp(rule);
+            }
+
+            case ICMPV6_INDEX: {
+                return Impl.parseIcmp6(rule);
+            }
+            default: {
+                return Impl.parse(rule);
+            }
+        }
+    }
+
+    class Impl {
+
+        private static IcmpCodeRange parseIcmpCodeRange(final AclRule rule) {
+            return new IcmpCodeRangeBuilder()
+                .setFirst(rule.dstportOrIcmpcodeFirst)
+                .setLast(rule.dstportOrIcmpcodeLast).build();
+        }
+
+        private static IcmpTypeRange parseIcmpTypeRange(final AclRule rule) {
+            return new IcmpTypeRangeBuilder()
+                .setFirst(rule.srcportOrIcmptypeFirst)
+                .setLast(rule.srcportOrIcmptypeLast).build();
+        }
+
+        private static Icmp parseIcmp(final AclRule rule) {
+            final IcmpNodesBuilder nodes = new IcmpNodesBuilder();
+            nodes.setIcmpCodeRange(parseIcmpCodeRange(rule));
+            nodes.setIcmpTypeRange(parseIcmpTypeRange(rule));
+            return new IcmpBuilder().setIcmpNodes(nodes.build()).build();
+        }
+
+        private static DestinationPortRange parseDstPortRange(final AclRule rule) {
+            return new DestinationPortRangeBuilder()
+                .setLowerPort(new PortNumber(Short.toUnsignedInt(rule.dstportOrIcmpcodeFirst)))
+                .setUpperPort(new PortNumber(Short.toUnsignedInt(rule.dstportOrIcmpcodeLast))).build();
+        }
+
+        private static SourcePortRange parseSrcPortRange(final AclRule rule) {
+            return new SourcePortRangeBuilder()
+                .setLowerPort(new PortNumber(Short.toUnsignedInt(rule.srcportOrIcmptypeFirst)))
+                .setUpperPort(new PortNumber(Short.toUnsignedInt(rule.srcportOrIcmptypeLast))).build();
+        }
+
+        private static Tcp parseTcp(final AclRule rule) {
+            final TcpNodesBuilder nodes = new TcpNodesBuilder();
+            nodes.setDestinationPortRange(parseDstPortRange(rule));
+            nodes.setSourcePortRange(parseSrcPortRange(rule));
+            nodes.setTcpFlagsMask((short) Byte.toUnsignedInt(rule.tcpFlagsMask));
+            nodes.setTcpFlagsValue((short) Byte.toUnsignedInt(rule.tcpFlagsValue));
+            return new TcpBuilder().setTcpNodes(nodes.build()).build();
+        }
+
+        private static Udp parseUdp(final AclRule rule) {
+            final UdpNodesBuilder nodes = new UdpNodesBuilder();
+            nodes.setDestinationPortRange(parseDstPortRange(rule));
+            nodes.setSourcePortRange(parseSrcPortRange(rule));
+            return new UdpBuilder().setUdpNodes(nodes.build()).build();
+        }
+
+        private static IcmpV6 parseIcmp6(final AclRule rule) {
+            final IcmpV6NodesBuilder nodes = new IcmpV6NodesBuilder();
+            nodes.setIcmpCodeRange(parseIcmpCodeRange(rule));
+            nodes.setIcmpTypeRange(parseIcmpTypeRange(rule));
+            return new IcmpV6Builder().setIcmpV6Nodes(nodes.build()).build();
+        }
+
+        private static IpProtocol parse(final AclRule rule) {
+            final OtherNodesBuilder nodes = new OtherNodesBuilder();
+            nodes.setProtocol((short) Short.toUnsignedInt(rule.proto));
+            return new OtherBuilder().setOtherNodes(nodes.build()).build();
+        }
+    }
+}
index 3a4fb0c..f838082 100644 (file)
@@ -18,6 +18,7 @@ package io.fd.hc2vpp.acl.write;
 
 import static java.util.stream.Collectors.toList;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
 import io.fd.hc2vpp.acl.util.iface.acl.AclInterfaceAssignmentRequest;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
@@ -39,11 +40,11 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public class InterfaceAclCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<Acl> {
 
     private final NamingContext interfaceContext;
-    private final NamingContext standardAclContext;
+    private final AclContextManager standardAclContext;
 
     public InterfaceAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
                                   @Nonnull final NamingContext interfaceContext,
-                                  @Nonnull final NamingContext standardAclContext) {
+                                  @Nonnull final AclContextManager standardAclContext) {
         super(jVppAclFacade);
         this.interfaceContext = interfaceContext;
         this.standardAclContext = standardAclContext;
index 4b59c83..9f9ac52 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.write;
 import static io.fd.hc2vpp.acl.util.iface.macip.MacIpInterfaceAssignmentRequest.addNew;
 import static io.fd.hc2vpp.acl.util.iface.macip.MacIpInterfaceAssignmentRequest.deleteExisting;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
@@ -29,14 +30,13 @@ import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAcl;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-
 public class InterfaceAclMacIpCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<VppMacipAcl> {
 
-    private final NamingContext macIpAclContext;
+    private final AclContextManager macIpAclContext;
     private final NamingContext interfaceContext;
 
     public InterfaceAclMacIpCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
-                                       @Nonnull final NamingContext macIpAclContext,
+                                       @Nonnull final AclContextManager macIpAclContext,
                                        @Nonnull final NamingContext interfaceContext) {
         super(jVppAclFacade);
         this.macIpAclContext = macIpAclContext;
index a295678..ee6a9ae 100644 (file)
 
 package io.fd.hc2vpp.acl.write;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
 import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
 import io.fd.hc2vpp.acl.util.acl.AclValidator;
 import io.fd.hc2vpp.acl.util.acl.AclWriter;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.MappingContext;
 import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
 import io.fd.honeycomb.translate.write.WriteContext;
@@ -34,12 +34,12 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 public class VppAclCustomizer extends FutureJVppAclCustomizer
         implements ListWriterCustomizer<Acl, AclKey>, AclValidator, AclDataExtractor, AclWriter {
 
-    private final NamingContext standardAclContext;
-    private final NamingContext macIpAclContext;
+    private final AclContextManager standardAclContext;
+    private final AclContextManager macIpAclContext;
 
     public VppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
-                            @Nonnull final NamingContext standardAclContext,
-                            @Nonnull final NamingContext macIpAclContext) {
+                            @Nonnull final AclContextManager standardAclContext,
+                            @Nonnull final AclContextManager macIpAclContext) {
         super(jVppAclFacade);
         this.standardAclContext = standardAclContext;
         this.macIpAclContext = macIpAclContext;
index fe22f2f..37a8de2 100644 (file)
@@ -19,6 +19,7 @@ package io.fd.hc2vpp.acl.write.factory;
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 import io.fd.hc2vpp.acl.AclModule;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
 
@@ -32,11 +33,11 @@ class AbstractAclWriterFactory {
 
     @Inject
     @Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
-    protected NamingContext standardAclContext;
+    protected AclContextManager standardAclContext;
 
     @Inject
     @Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
-    protected NamingContext macIpAClContext;
+    protected AclContextManager macIpAClContext;
 
     @Inject
     @Named("interface-context")
index 546924e..bf855ef 100644 (file)
 
 package io.fd.hc2vpp.acl.write.factory;
 
-import com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.acl.util.factory.AclFactory;
 import io.fd.hc2vpp.acl.write.VppAclCustomizer;
 import io.fd.honeycomb.translate.impl.write.GenericListWriter;
 import io.fd.honeycomb.translate.write.WriterFactory;
 import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
-import java.util.Set;
 import javax.annotation.Nonnull;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.AccessListEntries;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Actions;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6Nodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodes;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-public class VppAclWriterFactory extends AbstractAclWriterFactory implements WriterFactory {
-
-    private static Set<InstanceIdentifier<?>> vppAclCustomizerHandledChildren(final InstanceIdentifier<Acl> parentId) {
-        final InstanceIdentifier<Matches> matchesIid =
-            parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class);
-        return ImmutableSet.of(parentId.child(AccessListEntries.class),
-            parentId.child(AccessListEntries.class).child(Ace.class),
-            parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class),
-            parentId.child(AccessListEntries.class).child(Ace.class).child(Actions.class),
-            matchesIid,
-            matchesIid.child(VppMacipAceNodes.class),
-            matchesIid.child(VppAceNodes.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpCodeRange.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpTypeRange.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpCodeRange.class),
-            matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpTypeRange.class),
-            matchesIid.child(VppAceNodes.class).child(UdpNodes.class),
-            matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(SourcePortRange.class),
-            matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(DestinationPortRange.class),
-            matchesIid.child(VppAceNodes.class).child(TcpNodes.class),
-            matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(SourcePortRange.class),
-            matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(DestinationPortRange.class),
-            matchesIid.child(VppAceNodes.class).child(OtherNodes.class)
-
-        );
-    }
+public class VppAclWriterFactory extends AbstractAclWriterFactory implements WriterFactory, AclFactory {
 
     @Override
     public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
         final InstanceIdentifier<AccessLists> rootNode = InstanceIdentifier.create(AccessLists.class);
 
-        registry.subtreeAdd(vppAclCustomizerHandledChildren(InstanceIdentifier.create(Acl.class)),
+        registry.subtreeAdd(vppAclChildren(InstanceIdentifier.create(Acl.class)),
             new GenericListWriter<>(rootNode.child(Acl.class),
                 new VppAclCustomizer(futureAclFacade, standardAclContext, macIpAClContext)));
     }
index e885ef0..d01da0f 100644 (file)
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.test.read.InitializingListReaderCustomizerTest;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.read.ReadFailedException;
@@ -68,7 +69,9 @@ public abstract class AbstractVppAclCustomizerTest
     protected FutureJVppAclFacade aclApi;
 
     protected NamingContext interfaceContext = new NamingContext("iface", IFC_CTX_NAME);
-    protected NamingContext standardAclContext = new NamingContext("standardAcl", ACL_CTX_NAME);
+
+    @Mock
+    protected AclContextManager standardAclContext;
 
     protected AbstractVppAclCustomizerTest(final Class<? extends Builder<? extends DataObject>> parentBuilderClass) {
         super(VppAcls.class, parentBuilderClass);
diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AclCustomizerTest.java
new file mode 100644 (file)
index 0000000..7c86025
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.read;
+
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.common.test.read.InitializingListReaderCustomizerTest;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessListsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey;
+
+public class AclCustomizerTest extends InitializingListReaderCustomizerTest<Acl, AclKey, AclBuilder> {
+
+    @Mock
+    private FutureJVppAclFacade aclApi;
+    @Mock
+    private AclContextManager standardAclContext;
+    @Mock
+    private AclContextManager macipAclContext;
+
+    public AclCustomizerTest() {
+        super(Acl.class, AccessListsBuilder.class);
+    }
+
+    @Override
+    protected AclCustomizer initCustomizer() {
+        return new AclCustomizer(aclApi, standardAclContext, macipAclContext);
+    }
+}
\ No newline at end of file
index 29df6ac..e298800 100644 (file)
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.test.read.InitializingReaderCustomizerTest;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.translate.read.ReadFailedException;
@@ -51,7 +52,6 @@ public class VppMacIpAclCustomizerTest extends InitializingReaderCustomizerTest<
     protected static final String IF_NAME_NO_ACL = "eth2";
     protected static final int IF_ID_NO_ACL = 2;
     protected static final String IFC_CTX_NAME = "interface-context";
-    protected static final String ACL_CTX_NAME = "standard-acl-context";
     private static final String IF_NAME = "eth1";
     private static final int IF_ID = 1;
     private static final String ACL_NAME = "acl-name";
@@ -61,7 +61,8 @@ public class VppMacIpAclCustomizerTest extends InitializingReaderCustomizerTest<
     @Mock
     protected FutureJVppAclFacade aclApi;
     protected NamingContext interfaceContext = new NamingContext("iface", IFC_CTX_NAME);
-    protected NamingContext macIpAclContext = new NamingContext("macIpAcl", ACL_CTX_NAME);
+    @Mock
+    protected AclContextManager macIpAclContext;
 
     public VppMacIpAclCustomizerTest() {
         super(VppMacipAcl.class, IngressBuilder.class);
@@ -76,7 +77,7 @@ public class VppMacIpAclCustomizerTest extends InitializingReaderCustomizerTest<
     protected void setUp() {
         defineMapping(mappingContext, IF_NAME, IF_ID, IFC_CTX_NAME);
         defineMapping(mappingContext, IF_NAME_NO_ACL, IF_ID_NO_ACL, IFC_CTX_NAME);
-        defineMapping(mappingContext, ACL_NAME, ACL_ID, ACL_CTX_NAME);
+        when(macIpAclContext.getAclName(ACL_ID, mappingContext)).thenReturn(ACL_NAME);
     }
 
     @Test
index 2224d11..3eb1a62 100644 (file)
@@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import com.google.common.collect.ImmutableList;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.test.util.FutureProducer;
 import io.fd.hc2vpp.common.test.util.NamingContextHelper;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
@@ -79,7 +80,9 @@ public class AclInterfaceAssignmentRequestTest implements NamingContextHelper, F
 
     private InstanceIdentifier<Acl> validIdentifier;
     private NamingContext interfaceContext;
-    private NamingContext aclContext;
+
+    @Mock
+    private AclContextManager aclContext;
 
     @Before
     public void setUp() {
@@ -91,15 +94,14 @@ public class AclInterfaceAssignmentRequestTest implements NamingContextHelper, F
                 .child(Acl.class);
 
         interfaceContext = new NamingContext("iface", "interface-context");
-        aclContext = new NamingContext("acl", "acl-context");
 
         defineMapping(mappingContext, INTERFACE_NAME, INTERFACE_INDEX, "interface-context");
 
-        defineMapping(mappingContext, ACL_NAME_1, ACL_INDEX_1, "acl-context");
-        defineMapping(mappingContext, ACL_NAME_2, ACL_INDEX_2, "acl-context");
-        defineMapping(mappingContext, ACL_NAME_3, ACL_INDEX_3, "acl-context");
-        defineMapping(mappingContext, ACL_NAME_4, ACL_INDEX_4, "acl-context");
-        defineMapping(mappingContext, ACL_NAME_5, ACL_INDEX_5, "acl-context");
+        when(aclContext.getAclIndex(ACL_NAME_1, mappingContext)).thenReturn(ACL_INDEX_1);
+        when(aclContext.getAclIndex(ACL_NAME_2, mappingContext)).thenReturn(ACL_INDEX_2);
+        when(aclContext.getAclIndex(ACL_NAME_3, mappingContext)).thenReturn(ACL_INDEX_3);
+        when(aclContext.getAclIndex(ACL_NAME_4, mappingContext)).thenReturn(ACL_INDEX_4);
+        when(aclContext.getAclIndex(ACL_NAME_5, mappingContext)).thenReturn(ACL_INDEX_5);
 
         when(api.aclInterfaceSetAclList(any())).thenReturn(future(new AclInterfaceSetAclListReply()));
     }
index e815503..a7049b7 100644 (file)
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.test.util.FutureProducer;
 import io.fd.hc2vpp.common.test.util.NamingContextHelper;
 import io.fd.hc2vpp.common.translate.util.NamingContext;
@@ -49,9 +50,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interfa
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAcl;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
-/**
- * Created by jsrnicek on 13.12.2016.
- */
 public class MacIpInterfaceAssignmentRequestTest implements NamingContextHelper,FutureProducer {
 
     private static final String INTERFACE_NAME = "iface";
@@ -70,7 +68,8 @@ public class MacIpInterfaceAssignmentRequestTest implements NamingContextHelper,
 
     private InstanceIdentifier<VppMacipAcl> validIdentifier;
     private NamingContext interfaceContext;
-    private NamingContext macIpAclContext;
+    @Mock
+    private AclContextManager macIpAclContext;
 
     @Before
     public void setUp() throws Exception {
@@ -84,10 +83,9 @@ public class MacIpInterfaceAssignmentRequestTest implements NamingContextHelper,
                 .child(VppMacipAcl.class);
 
         interfaceContext = new NamingContext("iface", "interface-context");
-        macIpAclContext = new NamingContext("mac-ip-acl", "mac-ip-acl-context");
 
         defineMapping(mappingContext, INTERFACE_NAME, INTERFACE_INDEX, "interface-context");
-        defineMapping(mappingContext, ACL_NAME, ACL_INDEX, "mac-ip-acl-context");
+        when(macIpAclContext.getAclIndex(ACL_NAME, mappingContext)).thenReturn(ACL_INDEX);
         when(api.macipAclInterfaceAddDel(any())).thenReturn(future(new MacipAclInterfaceAddDelReply()));
     }
 
index d076311..bfdd176 100644 (file)
@@ -24,8 +24,8 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import io.fd.hc2vpp.acl.AclTestSchemaContext;
+import io.fd.hc2vpp.acl.util.AclContextManager;
 import io.fd.hc2vpp.common.test.write.WriterCustomizerTest;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
 import io.fd.honeycomb.test.tools.HoneycombTestRunner;
 import io.fd.honeycomb.test.tools.annotations.InjectTestData;
 import io.fd.honeycomb.translate.write.WriteFailedException;
@@ -68,8 +68,11 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
     private InstanceIdentifier<Acl> validId;
     private InstanceIdentifier<Acl> validMacipId;
     private VppAclCustomizer aclCustomizer;
-    private NamingContext standardAclContext;
-    private NamingContext macIpAclContext;
+
+    @Mock
+    private AclContextManager standardAclContext;
+    @Mock
+    private AclContextManager macIpAclContext;
 
 
     @Override
@@ -78,8 +81,6 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
                 InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey("standard-acl", VppAcl.class));
         validMacipId =
                 InstanceIdentifier.create(AccessLists.class).child(Acl.class, new AclKey("macip-acl", VppAcl.class));
-        standardAclContext = new NamingContext("acl", "acl-context");
-        macIpAclContext = new NamingContext("macip", "macip-context");
         aclCustomizer = new VppAclCustomizer(aclApi, standardAclContext, macIpAclContext);
 
         when(aclApi.aclAddReplace(any())).thenReturn(future(new AclAddReplaceReply()));
@@ -122,13 +123,14 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
     @Test
     public void updateCurrentAttributesIcmpIpv4(@InjectTestData(resourcePath = "/acl/standard/standard-acl-icmp.json")
                                                         AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         final Acl data = standardAcls.getAcl().get(0);
 
         aclCustomizer.updateCurrentAttributes(validId, data, data, writeContext);
 
         verify(aclApi, times(1)).aclAddReplace(aclAddReplaceRequestCaptor.capture());
-        verifyIcmpIpv4Request(4);
+        verifyIcmpIpv4Request(aclIndex);
     }
 
 
@@ -145,12 +147,13 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
     public void updateCurrentAttributesIcmpIpv6(
             @InjectTestData(resourcePath = "/acl/standard/standard-acl-icmp-v6.json")
                     AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         final Acl data = standardAcls.getAcl().get(0);
         aclCustomizer.updateCurrentAttributes(validId, data, data, writeContext);
 
         verify(aclApi, times(1)).aclAddReplace(aclAddReplaceRequestCaptor.capture());
-        verifyIcmpv6Request(4);
+        verifyIcmpv6Request(aclIndex);
     }
 
 
@@ -166,12 +169,13 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
     @Test
     public void updateCurrentAttributesTcp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-tcp.json")
                                                    AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         final Acl data = standardAcls.getAcl().get(0);
         aclCustomizer.updateCurrentAttributes(validId, data, data, writeContext);
 
         verify(aclApi, times(1)).aclAddReplace(aclAddReplaceRequestCaptor.capture());
-        verifyTcpRequest(4);
+        verifyTcpRequest(aclIndex);
     }
 
 
@@ -188,54 +192,59 @@ public class VppAclCustomizerTest extends WriterCustomizerTest implements AclTes
     @Test
     public void updateCurrentAttributesUdp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-udp.json")
                                                    AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         final Acl data = standardAcls.getAcl().get(0);
         aclCustomizer.updateCurrentAttributes(validId, data, data, writeContext);
 
         verify(aclApi, times(1)).aclAddReplace(aclAddReplaceRequestCaptor.capture());
-        verifyUdpRequest(4);
+        verifyUdpRequest(aclIndex);
     }
 
 
     @Test
     public void deleteCurrentAttributesIcmpIpv4(@InjectTestData(resourcePath = "/acl/standard/standard-acl-icmp.json")
                                                         AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         aclCustomizer.deleteCurrentAttributes(validId, standardAcls.getAcl().get(0), writeContext);
 
         verify(aclApi, times(1)).aclDel(aclDelRequestCaptor.capture());
-        assertEquals(4, aclDelRequestCaptor.getValue().aclIndex);
+        assertEquals(aclIndex, aclDelRequestCaptor.getValue().aclIndex);
     }
 
     @Test
     public void deleteCurrentAttributesIcmpIpv6(
             @InjectTestData(resourcePath = "/acl/standard/standard-acl-icmp-v6.json")
                     AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         aclCustomizer.deleteCurrentAttributes(validId, standardAcls.getAcl().get(0), writeContext);
 
         verify(aclApi, times(1)).aclDel(aclDelRequestCaptor.capture());
-        assertEquals(4, aclDelRequestCaptor.getValue().aclIndex);
+        assertEquals(aclIndex, aclDelRequestCaptor.getValue().aclIndex);
     }
 
     @Test
     public void deleteCurrentAttributesTcp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-tcp.json")
                                                    AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         aclCustomizer.deleteCurrentAttributes(validId, standardAcls.getAcl().get(0), writeContext);
 
         verify(aclApi, times(1)).aclDel(aclDelRequestCaptor.capture());
-        assertEquals(4, aclDelRequestCaptor.getValue().aclIndex);
+        assertEquals(aclIndex, aclDelRequestCaptor.getValue().aclIndex);
     }
 
     @Test
     public void deleteCurrentAttributesUdp(@InjectTestData(resourcePath = "/acl/standard/standard-acl-udp.json")
                                                    AccessLists standardAcls) throws Exception {
-        defineMapping(mappingContext, "standard-acl", 4, "acl-context");
+        final int aclIndex = 4;
+        when(standardAclContext.getAclIndex("standard-acl", mappingContext)).thenReturn(aclIndex);
         aclCustomizer.deleteCurrentAttributes(validId, standardAcls.getAcl().get(0), writeContext);
 
         verify(aclApi, times(1)).aclDel(aclDelRequestCaptor.capture());
-        assertEquals(4, aclDelRequestCaptor.getValue().aclIndex);
+        assertEquals(aclIndex, aclDelRequestCaptor.getValue().aclIndex);
     }
 
     private void verifyUdpRequest(final int aclIndex) {
index 2d0b51b..396391d 100644 (file)
@@ -141,6 +141,18 @@ public interface Ipv6Translator extends ByteDataTranslator {
         return address.getIpv6Prefix() != null;
     }
 
+    /**
+     * Sets correct length of ip4 array in case vpp returns array of length greater than 4.
+     * @param ip array to be truncated
+     * @return ip array of length 4
+     */
+    default byte[] truncateIp4Array(final byte[] ip) {
+        //  16, which causes problems for toIpv4Prefix
+        final byte[] result = new byte[4];
+        System.arraycopy(ip, 0, result, 0, 4);
+        return result;
+    }
+
     default Ipv6Prefix toIpv6Prefix(final byte[] address, final int prefix) {
         try {
             return new Ipv6Prefix(