From 8649ade681da840c633141fda46c0bd51ef0800f Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Thu, 22 Dec 2016 12:02:39 +0100 Subject: Fix ingress/egress acl assignment read Ingress and egress acls are not anymore mixed on the same list when reading interface state Change-Id: I2f775db4482e61593aa9689afcb687f7db7b4e73 Signed-off-by: Marek Gradzki --- .../hc2vpp/acl/read/AbstractVppAclCustomizer.java | 163 ++++++++++++++++ .../fd/hc2vpp/acl/read/EgressVppAclCustomizer.java | 48 +++++ .../hc2vpp/acl/read/IngressVppAclCustomizer.java | 48 +++++ .../io/fd/hc2vpp/acl/read/VppAclCustomizer.java | 204 --------------------- .../read/factory/InterfaceAclReaderFactory.java | 7 +- .../acl/read/AbstractVppAclCustomizerTest.java | 89 ++++++++- .../acl/read/EgressVppAclCustomizerTest.java | 68 +++++++ .../acl/read/IngressVppAclCustomizerTest.java | 68 +++++++ .../acl/read/VppEgressAclCustomizerTest.java | 63 ------- .../acl/read/VppIngressAclCustomizerTest.java | 64 ------- 10 files changed, 478 insertions(+), 344 deletions(-) create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizer.java create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizer.java create mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizer.java delete mode 100644 acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java create mode 100644 acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizerTest.java create mode 100644 acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizerTest.java delete mode 100644 acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppEgressAclCustomizerTest.java delete mode 100644 acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppIngressAclCustomizerTest.java (limited to 'acl') diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizer.java new file mode 100644 index 000000000..ed853eeea --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizer.java @@ -0,0 +1,163 @@ +/* + * 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.read; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; +import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer; +import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; +import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.honeycomb.translate.util.read.cache.TypeAwareIdentifierCacheKeyFactory; +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.AclInterfaceListDetails; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDump; +import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +abstract class AbstractVppAclCustomizer extends FutureJVppAclCustomizer + implements ListReaderCustomizer, JvppReplyConsumer, ByteDataTranslator { + + private final NamingContext interfaceContext; + private final NamingContext standardAclContext; + + private final DumpCacheManager aclReferenceDumpManager; + private final DumpCacheManager aclDumpManager; + + protected AbstractVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext standardAclContext) { + super(jVppAclFacade); + this.interfaceContext = interfaceContext; + this.standardAclContext = standardAclContext; + + aclReferenceDumpManager = + new DumpCacheManagerBuilder() + .withExecutor(createAclReferenceDumpExecutor()) + // Key needs to contain interface ID to distinguish dumps between interfaces + .withCacheKeyFactory(new TypeAwareIdentifierCacheKeyFactory(AclInterfaceListDetailsReplyDump.class, + ImmutableSet.of(Interface.class))) + .build(); + + aclDumpManager = new DumpCacheManagerBuilder() + .withExecutor(createAclExecutor()) + .acceptOnly(AclDetailsReplyDump.class) + .build(); + } + + private EntityDumpExecutor createAclExecutor() { + return (identifier, params) -> { + AclDump request = new AclDump(); + request.aclIndex = params; + return getReplyForRead(getjVppAclFacade().aclDump(request).toCompletableFuture(), identifier); + }; + } + + private EntityDumpExecutor createAclReferenceDumpExecutor() { + return (identifier, params) -> { + AclInterfaceListDump dumpRequest = new AclInterfaceListDump(); + dumpRequest.swIfIndex = params; + return getReplyForRead(getjVppAclFacade().aclInterfaceListDump(dumpRequest).toCompletableFuture(), + identifier); + }; + } + + @Nonnull + @Override + public final List getAllIds(@Nonnull final InstanceIdentifier id, + @Nonnull final ReadContext context) + throws ReadFailedException { + + final String parentInterfaceName = id.firstKeyOf(Interface.class).getName(); + final int parentInterfaceIndex = interfaceContext.getIndex(parentInterfaceName, context.getMappingContext()); + + final Optional dumpReply = + aclReferenceDumpManager.getDump(id, context.getModificationCache(), parentInterfaceIndex); + + if (dumpReply.isPresent() && !dumpReply.get().aclInterfaceListDetails.isEmpty()) { + // if dumpReply is present, then aclInterfaceListDetails contains single element (actually it should not be + // dump message in vpp) + final AclInterfaceListDetails aclDetails = dumpReply.get().aclInterfaceListDetails.get(0); + return filterAcls(aclDetails) + .mapToObj(aclIndex -> standardAclContext.getName(aclIndex, context.getMappingContext())) + .map(aclName -> new VppAclsKey(aclName, VppAcl.class)) + .collect(Collectors.toList()); + } else { + return Collections.emptyList(); + } + } + + /** + * Streams ids of ACLs. + * + * @param aclDetails describes ACLs assigned to interface + * @return sequence of acl ids + */ + protected abstract IntStream filterAcls(@Nonnull final AclInterfaceListDetails aclDetails); + + @Nonnull + @Override + public final VppAclsBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new VppAclsBuilder(); + } + + @Override + public final void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final VppAclsBuilder builder, + @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 Optional 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) + // decide how tag should be handled (model change might be needed). + builder.setName(aclName); + builder.setType(vppAclsKey.getType()); + final AclDetails aclDetails = dumpReply.get().aclDetails.get(0); + if (aclDetails.tag != null && aclDetails.tag.length > 0) { + builder.setTag(new HexString(printHexBinary(aclDetails.tag))); + } + } else { + throw new ReadFailedException(id, + new IllegalArgumentException(String.format("Acl with name %s not found", aclName))); + } + } +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizer.java new file mode 100644 index 000000000..536b27fcc --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizer.java @@ -0,0 +1,48 @@ +/* + * 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.read; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; +import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.EgressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; + +public final class EgressVppAclCustomizer extends AbstractVppAclCustomizer { + + public EgressVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext standardAclContext) { + super(jVppAclFacade, interfaceContext, standardAclContext); + } + + @Override + protected IntStream filterAcls(@Nonnull final AclInterfaceListDetails aclDetails) { + return Arrays.stream(aclDetails.acls).skip(aclDetails.nInput); + } + + @Override + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + EgressBuilder.class.cast(builder).setVppAcls(readData); + } +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizer.java new file mode 100644 index 000000000..8a31032d7 --- /dev/null +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizer.java @@ -0,0 +1,48 @@ +/* + * 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.read; + +import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; +import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; +import java.util.Arrays; +import java.util.List; +import java.util.stream.IntStream; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; + +public final class IngressVppAclCustomizer extends AbstractVppAclCustomizer { + + public IngressVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade, + @Nonnull final NamingContext interfaceContext, + @Nonnull final NamingContext standardAclContext) { + super(jVppAclFacade, interfaceContext, standardAclContext); + } + + @Override + protected IntStream filterAcls(@Nonnull final AclInterfaceListDetails aclDetails) { + return Arrays.stream(aclDetails.acls).limit(aclDetails.nInput); + } + + @Override + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + IngressBuilder.class.cast(builder).setVppAcls(readData); + } +} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java deleted file mode 100644 index 948b6408a..000000000 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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.read; - - -import com.google.common.base.Optional; -import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer; -import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; -import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; -import io.fd.hc2vpp.common.translate.util.NamingContext; -import io.fd.honeycomb.translate.read.ReadContext; -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer; -import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; -import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; -import io.fd.honeycomb.translate.util.read.cache.EntityDumpPostProcessingFunction; -import io.fd.vpp.jvpp.acl.dto.AclDetailsReplyDump; -import io.fd.vpp.jvpp.acl.dto.AclDump; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDump; -import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.EgressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; - -public class VppAclCustomizer extends FutureJVppAclCustomizer - implements ListReaderCustomizer, JvppReplyConsumer, ByteDataTranslator { - - private final NamingContext interfaceContext; - private final NamingContext standardAclContext; - /** - * true == ingress - * false == egress - */ - private final boolean input; - private final DumpCacheManager aclReferenceDumpManager; - private final DumpCacheManager aclDumpManager; - - public VppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade, - @Nonnull final NamingContext interfaceContext, - @Nonnull final NamingContext standardAclContext, - final boolean input) { - super(jVppAclFacade); - this.interfaceContext = interfaceContext; - this.standardAclContext = standardAclContext; - this.input = input; - - aclReferenceDumpManager = - new DumpCacheManagerBuilder() - .withExecutor(createAclReferenceDumpExecutor()) - .withPostProcessingFunction(input - ? createInputAclFilter() - : createOutputAclFilter()) - .acceptOnly(AclInterfaceListDetailsReplyDump.class) - .build(); - - aclDumpManager = new DumpCacheManagerBuilder() - .withExecutor(createAclExecutor()) - .acceptOnly(AclDetailsReplyDump.class) - .build(); - } - - private EntityDumpExecutor createAclExecutor() { - return (identifier, params) -> { - AclDump request = new AclDump(); - request.aclIndex = params; - return getReplyForRead(getjVppAclFacade().aclDump(request).toCompletableFuture(), identifier); - }; - } - - private EntityDumpPostProcessingFunction createInputAclFilter() { - return dump -> { - // filters acl's to first N(those are input ones) - dump.aclInterfaceListDetails = dump.aclInterfaceListDetails - .stream() - .map(iface -> { - if (iface.acls != null && iface.acls.length > 0) { - if (iface.nInput <= 0) { - iface.acls = new int[0]; - } else { - iface.acls = Arrays.copyOfRange(iface.acls, 0, iface.nInput); - } - } - return iface; - }) - .collect(Collectors.toList()); - return dump; - }; - } - - private EntityDumpPostProcessingFunction createOutputAclFilter() { - return dump -> { - // filters acl's to last N(those are output ones) - dump.aclInterfaceListDetails = dump.aclInterfaceListDetails - .stream() - .map(iface -> { - if (iface.nInput >= iface.acls.length) { - iface.acls = new int[0]; - } else { - iface.acls = Arrays.copyOfRange(iface.acls, iface.nInput, iface.acls.length); - } - return iface; - }) - .collect(Collectors.toList()); - return dump; - }; - } - - private EntityDumpExecutor createAclReferenceDumpExecutor() { - return (identifier, params) -> { - AclInterfaceListDump dumpRequest = new AclInterfaceListDump(); - dumpRequest.swIfIndex = params; - return getReplyForRead(getjVppAclFacade().aclInterfaceListDump(dumpRequest).toCompletableFuture(), - identifier); - }; - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext context) - throws ReadFailedException { - - final String parentInterfaceName = id.firstKeyOf(Interface.class).getName(); - final int parentInterfaceIndex = interfaceContext.getIndex(parentInterfaceName, context.getMappingContext()); - - final Optional dumpReply = - aclReferenceDumpManager.getDump(id, context.getModificationCache(), parentInterfaceIndex); - - if (dumpReply.isPresent() && !dumpReply.get().aclInterfaceListDetails.isEmpty()) { - return Arrays.stream(dumpReply.get().aclInterfaceListDetails.get(0).acls) - .mapToObj(aclIndex -> standardAclContext.getName(aclIndex, context.getMappingContext())) - .map(aclName -> new VppAclsKey(aclName, VppAcl.class)) - .collect(Collectors.toList()); - } else { - return Collections.emptyList(); - } - } - - @Override - public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - if (input) { - IngressBuilder.class.cast(builder).setVppAcls(readData); - } else { - EgressBuilder.class.cast(builder).setVppAcls(readData); - } - } - - @Nonnull - @Override - public VppAclsBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new VppAclsBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final VppAclsBuilder builder, - @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 Optional 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) - // decide how tag should be handled (model change might be needed). - builder.setName(aclName); - builder.setType(vppAclsKey.getType()); - builder.setTag(new HexString(printHexBinary(dumpReply.get().aclDetails.get(0).tag))); - } else { - throw new ReadFailedException(id, - new IllegalArgumentException(String.format("Acl with name %s not found", aclName))); - } - } -} diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java index 89520620d..691479e64 100644 --- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java +++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java @@ -19,7 +19,8 @@ package io.fd.hc2vpp.acl.read.factory; import com.google.inject.Inject; import com.google.inject.name.Named; import io.fd.hc2vpp.acl.AclModule; -import io.fd.hc2vpp.acl.read.VppAclCustomizer; +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.common.translate.util.NamingContext; import io.fd.honeycomb.translate.impl.read.GenericListReader; @@ -73,13 +74,13 @@ public class InterfaceAclReaderFactory implements ReaderFactory { final InstanceIdentifier ingressInstanceIdentifier = ACL_IID.child(Ingress.class); registry.addStructuralReader(ingressInstanceIdentifier, IngressBuilder.class); registry.addAfter(new GenericListReader<>(ingressInstanceIdentifier.child(VppAcls.class), - new VppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext, true)), IFC_ID); + new IngressVppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)), IFC_ID); registry.addAfter(new GenericReader<>(ingressInstanceIdentifier.child(VppMacipAcl.class), new VppMacIpAclCustomizer(futureAclFacade, interfaceContext, macIpAClContext)), IFC_ID); final InstanceIdentifier egressInstanceIdentifier = ACL_IID.child(Egress.class); registry.addStructuralReader(egressInstanceIdentifier, EgressBuilder.class); registry.addAfter(new GenericListReader<>(egressInstanceIdentifier.child(VppAcls.class), - new VppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext, false)), IFC_ID); + new EgressVppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)), IFC_ID); } } diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizerTest.java index 7bfffb63b..85ea0f87f 100644 --- a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizerTest.java +++ b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/AbstractVppAclCustomizerTest.java @@ -16,16 +16,25 @@ package io.fd.hc2vpp.acl.read; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.vpp.jvpp.acl.dto.AclDetails; +import io.fd.vpp.jvpp.acl.dto.AclDetailsReplyDump; import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDump; import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade; +import java.util.ArrayList; +import javax.annotation.Nonnull; import org.junit.Test; import org.mockito.Mock; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState; @@ -33,22 +42,23 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceStateAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.Acl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.Ingress; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -public abstract class AbstractVppAclCustomizerTest extends ListReaderCustomizerTest { +public abstract class AbstractVppAclCustomizerTest + extends ListReaderCustomizerTest { protected static final String IF_NAME = "eth1"; protected static final int IF_ID = 1; - protected static final InstanceIdentifier IID = - InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(IF_NAME)) - .augmentation(VppAclInterfaceStateAugmentation.class).child(Acl.class).child(Ingress.class) - .child(VppAcls.class); + + 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"; @@ -65,15 +75,74 @@ public abstract class AbstractVppAclCustomizerTest extends ListReaderCustomizerT @Override protected void setUp() throws Exception { defineMapping(mappingContext, IF_NAME, IF_ID, IFC_CTX_NAME); + defineMapping(mappingContext, IF_NAME_NO_ACL, IF_ID_NO_ACL, IFC_CTX_NAME); } @Test public void testGetAllIdsNoAclConfigured() throws ReadFailedException { - AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump((byte) 0); + when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); + assertTrue(getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).isEmpty()); + } + + @Test + public void testRead() throws ReadFailedException { + final String aclName = "acl-name"; + final Class aclType = VppAcl.class; + defineMapping(mappingContext, aclName, 1, ACL_CTX_NAME); + + final AclDetailsReplyDump reply = new AclDetailsReplyDump(); + reply.aclDetails = new ArrayList<>(); + final AclDetails detail = new AclDetails(); + detail.tag = new byte[0]; + reply.aclDetails.add(detail); + when(aclApi.aclDump(any())).thenReturn(future(reply)); + + final VppAclsBuilder builder = mock(VppAclsBuilder.class); + getCustomizer().readCurrentAttributes(getIid(IF_NAME, new VppAclsKey(aclName, aclType)), builder, ctx); + verify(builder).setName(aclName); + verify(builder).setType(aclType); + } + + @Test + public void testReadAllTwoIfacesInOneTx() throws ReadFailedException { + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump((byte) 2, "acl1", "acl2", "acl3"); + when(aclApi.aclInterfaceListDump(aclInterfaceRequest(IF_ID))).thenReturn(future(reply)); + + when(aclApi.aclInterfaceListDump(aclInterfaceRequest(IF_ID_NO_ACL))) + .thenReturn(future(aclInterfaceDump((byte) 0))); + + // read all for interface with defined ACLs: + assertFalse(getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).isEmpty()); + // read all for interface without ACLs defined: + assertEquals(0, getCustomizer().getAllIds(getWildcardedIid(IF_NAME_NO_ACL), ctx).size()); + } + + protected AclInterfaceListDump aclInterfaceRequest(final int swIfIndex) { + final AclInterfaceListDump request = new AclInterfaceListDump(); + request.swIfIndex = swIfIndex; + return request; + } + + protected AclInterfaceListDetailsReplyDump aclInterfaceDump(final byte nInput, final String... aclNames) { + final AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); final AclInterfaceListDetails details = new AclInterfaceListDetails(); - details.acls = new int[0]; + details.acls = new int[aclNames.length]; + for (int i = 0; i < aclNames.length; ++i) { + defineMapping(mappingContext, aclNames[i], i, ACL_CTX_NAME); + details.acls[i] = i; + } + details.nInput = nInput; reply.aclInterfaceListDetails.add(details); - when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); - assertTrue(getCustomizer().getAllIds(IID, ctx).isEmpty()); + return reply; + } + + protected InstanceIdentifier getAclId(final String ifName) { + return InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey(ifName)) + .augmentation(VppAclInterfaceStateAugmentation.class).child(Acl.class); } + + protected abstract InstanceIdentifier getWildcardedIid(@Nonnull final String ifName); + + protected abstract InstanceIdentifier getIid(@Nonnull final String ifName, @Nonnull final VppAclsKey key); } \ No newline at end of file diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizerTest.java new file mode 100644 index 000000000..967b8200a --- /dev/null +++ b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/EgressVppAclCustomizerTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.acl.read; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; +import javax.annotation.Nonnull; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.Egress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.EgressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class EgressVppAclCustomizerTest extends AbstractVppAclCustomizerTest { + + public EgressVppAclCustomizerTest() { + super(EgressBuilder.class); + } + + @Override + protected EgressVppAclCustomizer initCustomizer() { + return new EgressVppAclCustomizer(aclApi, interfaceContext, standardAclContext); + } + + @Test + public void testGetAllIdsNoOutputAclConfigured() throws ReadFailedException { + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump((byte) 1, "acl1"); + when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); + assertTrue(getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).isEmpty()); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump((byte) 2, "acl1", "acl2", "acl3"); + when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); + assertEquals(1, getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).size()); + } + + @Override + protected InstanceIdentifier getWildcardedIid(@Nonnull final String ifName) { + return getAclId(ifName).child(Egress.class).child(VppAcls.class); + } + + @Override + protected InstanceIdentifier getIid(@Nonnull final String ifName, @Nonnull final VppAclsKey key) { + return getAclId(ifName).child(Egress.class).child(VppAcls.class, key); + } +} \ No newline at end of file diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizerTest.java new file mode 100644 index 000000000..42a798e88 --- /dev/null +++ b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/IngressVppAclCustomizerTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.acl.read; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; +import javax.annotation.Nonnull; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.Ingress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class IngressVppAclCustomizerTest extends AbstractVppAclCustomizerTest { + + public IngressVppAclCustomizerTest() { + super(IngressBuilder.class); + } + + @Override + protected IngressVppAclCustomizer initCustomizer() { + return new IngressVppAclCustomizer(aclApi, interfaceContext, standardAclContext); + } + + @Test + public void testGetAllIdsNoInputAclConfigured() throws ReadFailedException { + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump((byte) 0, "acl1"); + when(aclApi.aclInterfaceListDump(aclInterfaceRequest(IF_ID))).thenReturn(future(reply)); + assertTrue(getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).isEmpty()); + } + + @Test + public void testGetAllIds() throws ReadFailedException { + final byte nInput = 2; + final AclInterfaceListDetailsReplyDump reply = aclInterfaceDump(nInput, "acl1", "acl2", "acl3"); + when(aclApi.aclInterfaceListDump(aclInterfaceRequest(IF_ID))).thenReturn(future(reply)); + assertEquals(nInput, getCustomizer().getAllIds(getWildcardedIid(IF_NAME), ctx).size()); + } + + @Override + protected InstanceIdentifier getWildcardedIid(@Nonnull final String ifName) { + return getAclId(ifName).child(Ingress.class).child(VppAcls.class); + } + + @Override + protected InstanceIdentifier getIid(@Nonnull final String ifName, @Nonnull final VppAclsKey key) { + return getAclId(ifName).child(Ingress.class).child(VppAcls.class, key); + } +} \ No newline at end of file diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppEgressAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppEgressAclCustomizerTest.java deleted file mode 100644 index b82a42896..000000000 --- a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppEgressAclCustomizerTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.read; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.EgressBuilder; - -public class VppEgressAclCustomizerTest extends AbstractVppAclCustomizerTest { - - public VppEgressAclCustomizerTest() { - super(EgressBuilder.class); - } - - @Override - protected VppAclCustomizer initCustomizer() { - return new VppAclCustomizer(aclApi, interfaceContext, standardAclContext, false); - } - - @Test - public void testGetAllIdsNoOutputAclConfigured() throws ReadFailedException { - AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); - final AclInterfaceListDetails details = new AclInterfaceListDetails(); - details.acls = new int[1]; - details.nInput = 1; - reply.aclInterfaceListDetails.add(details); - when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); - assertTrue(getCustomizer().getAllIds(IID, ctx).isEmpty()); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); - final AclInterfaceListDetails details = new AclInterfaceListDetails(); - defineMapping(mappingContext, "acl3", 3, ACL_CTX_NAME); - details.acls = new int[]{1,2,3}; - details.nInput = 2; - reply.aclInterfaceListDetails.add(details); - when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); - assertEquals(details.acls.length - details.nInput, getCustomizer().getAllIds(IID, ctx).size()); - } -} \ No newline at end of file diff --git a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppIngressAclCustomizerTest.java b/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppIngressAclCustomizerTest.java deleted file mode 100644 index 773a9fa54..000000000 --- a/acl/acl-impl/src/test/java/io/fd/hc2vpp/acl/read/VppIngressAclCustomizerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.read; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -import io.fd.honeycomb.translate.read.ReadFailedException; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetails; -import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump; -import org.junit.Test; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder; - -public class VppIngressAclCustomizerTest extends AbstractVppAclCustomizerTest { - - public VppIngressAclCustomizerTest() { - super(IngressBuilder.class); - } - - @Override - protected VppAclCustomizer initCustomizer() { - return new VppAclCustomizer(aclApi, interfaceContext, standardAclContext, true); - } - - @Test - public void testGetAllIdsNoInputAclConfigured() throws ReadFailedException { - AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); - final AclInterfaceListDetails details = new AclInterfaceListDetails(); - details.acls = new int[1]; - details.nInput = 0; - reply.aclInterfaceListDetails.add(details); - when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); - assertTrue(getCustomizer().getAllIds(IID, ctx).isEmpty()); - } - - @Test - public void testGetAllIds() throws ReadFailedException { - AclInterfaceListDetailsReplyDump reply = new AclInterfaceListDetailsReplyDump(); - final AclInterfaceListDetails details = new AclInterfaceListDetails(); - defineMapping(mappingContext, "acl1", 1, ACL_CTX_NAME); - defineMapping(mappingContext, "acl2", 2, ACL_CTX_NAME); - details.acls = new int[]{1,2,3}; - details.nInput = 2; - reply.aclInterfaceListDetails.add(details); - when(aclApi.aclInterfaceListDump(any())).thenReturn(future(reply)); - assertEquals(details.nInput, getCustomizer().getAllIds(IID, ctx).size()); - } -} \ No newline at end of file -- cgit 1.2.3-korg