From 2b1748599e4c820730eef2deb7f59489bab82f82 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 12 Apr 2016 10:13:18 +0200 Subject: HONEYCOMB-9: Remove references to VPP from translation layer Change-Id: I281db366a112edc08203e8cb392a212708d4552a Signed-off-by: Maros Marsalek --- v3po/v3po2vpp/pom.xml | 11 +- .../translate/v3po/vpp/BridgeDomainCustomizer.java | 138 +++++++++++ .../v3po/vppstate/BridgeDomainCustomizer.java | 136 +++++++++++ .../translate/v3po/vppstate/VersionCustomizer.java | 59 +++++ .../facade/v3po/vpp/BridgeDomainCustomizer.java | 138 ----------- .../v3po/vppstate/BridgeDomainCustomizer.java | 136 ----------- .../facade/v3po/vppstate/VersionCustomizer.java | 59 ----- .../v3po/vpp/BridgeDomainCustomizerTest.java | 264 ++++++++++++++++++++ .../translate/v3po/vpp/BridgeDomainTestUtils.java | 64 +++++ .../honeycomb/v3po/translate/v3po/vpp/VppTest.java | 173 +++++++++++++ .../v3po/translate/v3po/vpp/VppUtils.java | 62 +++++ .../v3po/translate/v3po/vppstate/VppStateTest.java | 259 ++++++++++++++++++++ .../translate/v3po/vppstate/VppStateUtils.java | 77 ++++++ .../v3po/vpp/BridgeDomainCustomizerTest.java | 269 --------------------- .../vpp/facade/v3po/vpp/BridgeDomainTestUtils.java | 64 ----- .../v3po/vpp/facade/v3po/vpp/VppTest.java | 174 ------------- .../v3po/vpp/facade/v3po/vpp/VppUtils.java | 62 ----- .../vpp/facade/v3po/vppstate/VppStateTest.java | 259 -------------------- .../vpp/facade/v3po/vppstate/VppStateUtils.java | 77 ------ 19 files changed, 1240 insertions(+), 1241 deletions(-) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/BridgeDomainCustomizer.java delete mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VersionCustomizer.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainTestUtils.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java create mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizerTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainTestUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppUtils.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateTest.java delete mode 100644 v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateUtils.java (limited to 'v3po/v3po2vpp') diff --git a/v3po/v3po2vpp/pom.xml b/v3po/v3po2vpp/pom.xml index eb4aca7fa..e14730594 100644 --- a/v3po/v3po2vpp/pom.xml +++ b/v3po/v3po2vpp/pom.xml @@ -31,12 +31,17 @@ ${project.groupId} - vpp-facade-spi + translate-spi ${project.version} ${project.groupId} - vpp-facade-utils + translate-utils + ${project.version} + + + ${project.groupId} + vpp-translate-utils ${project.version} @@ -53,7 +58,7 @@ ${project.groupId} - vpp-facade-impl + translate-impl ${project.version} test diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java new file mode 100644 index 000000000..ffbc95beb --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vpp; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.Context; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BridgeDomainCustomizer + extends VppApiCustomizer + implements ListWriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); + + private static final byte ADD_OR_UPDATE_BD = (byte) 1; + private static final int RESPONSE_NOT_READY = -77; + private static final int RELEASE = 1; + + public BridgeDomainCustomizer(final org.openvpp.vppjapi.vppApi api) { + super(api); + } + + @Nonnull + @Override + public List extract(@Nonnull final InstanceIdentifier currentId, + @Nonnull final DataObject parentData) { + return ((BridgeDomains) parentData).getBridgeDomain(); + } + + private int waitForResponse(final int ctxId) { + int rv; + while ((rv = getVppApi().getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) { + // TODO limit attempts + } + return rv; + } + + private int addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) { + byte flood = booleanToByte(bd.isFlood()); + byte forward = booleanToByte(bd.isForward()); + byte learn = booleanToByte(bd.isLearn()); + byte uuf = booleanToByte(bd.isUnknownUnicastFlood()); + byte arpTerm = booleanToByte(bd.isArpTermination()); + + int ctxId = getVppApi().bridgeDomainAddDel(bdId, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); + return waitForResponse(ctxId); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain current, + @Nonnull final Context ctx) { + LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, current, ctx); + final String bdName = current.getName(); + int bdId = getVppApi().findOrAddBridgeDomainId(bdName); + checkState(bdId > 0, "Unable to find or create bridge domain. Return code: %s", bdId); + + int rv = addOrUpdateBridgeDomain(bdId, current); + + checkState(rv >= 0, "Bridge domain %s(%s) write failed. Return code: %s", bdName, bdId, rv); + LOG.debug("Bridge domain {} written as {} successfully", bdName, bdId); + } + + private byte booleanToByte(@Nullable final Boolean aBoolean) { + return aBoolean != null && aBoolean ? (byte) 1 : (byte) 0; + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, + @Nonnull final Context ctx) { + LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); + String bdName = id.firstKeyOf(BridgeDomain.class).getName(); + + int bdId = getVppApi().bridgeDomainIdFromName(bdName); + checkState(bdId > 0, "Unable to delete bridge domain. Does not exist. Return code: %s", bdId); + + int ctxId = getVppApi().bridgeDomainAddDel(bdId, + (byte) 0 /* flood */, + (byte) 0 /* forward */, + (byte) 0 /* learn */, + (byte) 0 /* uuf */, + (byte) 0 /* arpTerm */, + (byte) 0 /* isAdd */); + + int rv = waitForResponse(ctxId); + + checkState(rv >= 0, "Bridge domain delete failed. Return code: %s", rv); + LOG.debug("Bridge domain {} deleted as {} successfully", bdName, bdId); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, + @Nonnull final Context ctx) { + LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, ctx); + + final String bdName = checkNotNull(dataAfter.getName()); + checkArgument(bdName.equals(dataBefore.getName()), "BridgeDomain name changed. It should be deleted and then created."); + + int bdId = getVppApi().bridgeDomainIdFromName(bdName); + checkState(bdId > 0, "Unable to find bridge domain. Return code: %s", bdId); + + final int rv = addOrUpdateBridgeDomain(bdId, dataAfter); + + checkState(rv >= 0, "Bridge domain %s(%s) update failed. Return code: %s", bdName, bdId, rv); + LOG.debug("Bridge domain {}({}) updated successfully", bdName, bdId); + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java new file mode 100644 index 000000000..36e1da366 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vppstate; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.Context; +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.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.Interface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppBridgeDomainDetails; +import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; +import org.openvpp.vppjapi.vppL2Fib; + +public final class BridgeDomainCustomizer extends VppApiCustomizer + implements ListReaderCustomizer { + + public BridgeDomainCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Override + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context) { + final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); + // TODO find out if bd exists based on name and if not return + + final int bdId = getVppApi().bridgeDomainIdFromName(key.getName()); + final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bdId); + + builder.setName(key.getName()); + // builder.setName(bridgeDomainDetails.name); + builder.setArpTermination(bridgeDomainDetails.arpTerm); + builder.setFlood(bridgeDomainDetails.flood); + builder.setForward(bridgeDomainDetails.forward); + builder.setLearn(bridgeDomainDetails.learn); + builder.setUnknownUnicastFlood(bridgeDomainDetails.uuFlood); + + builder.setInterface(getIfcs(bridgeDomainDetails)); + + final vppL2Fib[] vppL2Fibs = getVppApi().l2FibTableDump(bdId); + + final List l2Fibs = Lists.newArrayListWithCapacity(vppL2Fibs.length); + for (vppL2Fib vppL2Fib : vppL2Fibs) { + l2Fibs.add(new L2FibBuilder() + .setAction((vppL2Fib.filter + ? L2Fib.Action.Filter + : L2Fib.Action.Forward)) + .setBridgedVirtualInterface(vppL2Fib.bridgedVirtualInterface) + .setOutgoingInterface(vppL2Fib.outgoingInterface) + .setPhysAddress(new PhysAddress(getMacAddress(vppL2Fib.physAddress))) + .setStaticConfig(vppL2Fib.staticConfig) + .build()); + } + builder.setL2Fib(l2Fibs); + } + + private static String getMacAddress(byte[] mac) { + StringBuilder sb = new StringBuilder(18); + for (byte b : mac) { + if (sb.length() > 0) { + sb.append(':'); + } + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } + + private List getIfcs(final vppBridgeDomainDetails bridgeDomainDetails) { + final List ifcs = new ArrayList<>(bridgeDomainDetails.interfaces.length); + for (vppBridgeDomainInterfaceDetails anInterface : bridgeDomainDetails.interfaces) { + ifcs.add(new InterfaceBuilder() + .setBridgedVirtualInterface(bridgeDomainDetails.bviInterfaceName.equals(anInterface.interfaceName)) + .setName(anInterface.interfaceName) + .setKey(new InterfaceKey(anInterface.interfaceName)) + .build()); + } + return ifcs; + } + + @Nonnull + @Override + public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new BridgeDomainBuilder(); + } + + @Nonnull + @Override + public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final Context context) { + final int[] bIds = getVppApi().bridgeDomainDump(-1); + final List allIds = new ArrayList<>(bIds.length); + for (int bId : bIds) { + // FIXME this is highly inefficient having to dump all of the bridge domain details + // Use context to store already read information + // TODO Or just remove the getAllIds method and replace with a simple readAll + final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bId); + final String bName = bridgeDomainDetails.name; + allIds.add(new BridgeDomainKey(bName)); + } + + return allIds; + } + + @Override + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + ((BridgeDomainsBuilder) builder).setBridgeDomain(readData); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java new file mode 100644 index 000000000..31e3166bb --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vppstate; + +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppVersion; + +public final class VersionCustomizer + extends VppApiCustomizer + implements ChildReaderCustomizer { + + public VersionCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Override + public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Version readValue) { + ((VppStateBuilder) parentBuilder).setVersion(readValue); + } + + @Nonnull + @Override + public VersionBuilder getBuilder(@Nonnull InstanceIdentifier id) { + return new VersionBuilder(); + } + + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull final VersionBuilder builder, + @Nonnull final Context context) { + final vppVersion vppVersion = getVppApi().getVppVersion(); + builder.setBranch(vppVersion.gitBranch); + builder.setName(vppVersion.programName); + builder.setBuildDate(vppVersion.buildDate); + builder.setBuildDirectory(vppVersion.buildDirectory); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizer.java deleted file mode 100644 index 2c394fe77..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizer.java +++ /dev/null @@ -1,138 +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.honeycomb.v3po.vpp.facade.v3po.vpp; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import io.fd.honeycomb.v3po.vpp.facade.impl.util.VppApiCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.Context; -import io.fd.honeycomb.v3po.vpp.facade.spi.write.ListVppWriterCustomizer; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class BridgeDomainCustomizer - extends VppApiCustomizer - implements ListVppWriterCustomizer { - - private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); - - private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private static final int RESPONSE_NOT_READY = -77; - private static final int RELEASE = 1; - - public BridgeDomainCustomizer(final org.openvpp.vppjapi.vppApi api) { - super(api); - } - - @Nonnull - @Override - public List extract(@Nonnull final InstanceIdentifier currentId, - @Nonnull final DataObject parentData) { - return ((BridgeDomains) parentData).getBridgeDomain(); - } - - private int waitForResponse(final int ctxId) { - int rv; - while ((rv = getVppApi().getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) { - // TODO limit attempts - } - return rv; - } - - private int addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) { - byte flood = booleanToByte(bd.isFlood()); - byte forward = booleanToByte(bd.isForward()); - byte learn = booleanToByte(bd.isLearn()); - byte uuf = booleanToByte(bd.isUnknownUnicastFlood()); - byte arpTerm = booleanToByte(bd.isArpTermination()); - - int ctxId = getVppApi().bridgeDomainAddDel(bdId, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); - return waitForResponse(ctxId); - } - - @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain current, - @Nonnull final Context ctx) { - LOG.debug("writeCurrentAttributes: id={}, current={}, ctx={}", id, current, ctx); - final String bdName = current.getName(); - int bdId = getVppApi().findOrAddBridgeDomainId(bdName); - checkState(bdId > 0, "Unable to find or create bridge domain. Return code: %s", bdId); - - int rv = addOrUpdateBridgeDomain(bdId, current); - - checkState(rv >= 0, "Bridge domain %s(%s) write failed. Return code: %s", bdName, bdId, rv); - LOG.debug("Bridge domain {} written as {} successfully", bdName, bdId); - } - - private byte booleanToByte(@Nullable final Boolean aBoolean) { - return aBoolean != null && aBoolean ? (byte) 1 : (byte) 0; - } - - @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, - @Nonnull final Context ctx) { - LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx); - String bdName = id.firstKeyOf(BridgeDomain.class).getName(); - - int bdId = getVppApi().bridgeDomainIdFromName(bdName); - checkState(bdId > 0, "Unable to delete bridge domain. Does not exist. Return code: %s", bdId); - - int ctxId = getVppApi().bridgeDomainAddDel(bdId, - (byte) 0 /* flood */, - (byte) 0 /* forward */, - (byte) 0 /* learn */, - (byte) 0 /* uuf */, - (byte) 0 /* arpTerm */, - (byte) 0 /* isAdd */); - - int rv = waitForResponse(ctxId); - - checkState(rv >= 0, "Bridge domain delete failed. Return code: %s", rv); - LOG.debug("Bridge domain {} deleted as {} successfully", bdName, bdId); - } - - @Override - public void updateCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomain dataBefore, @Nonnull final BridgeDomain dataAfter, - @Nonnull final Context ctx) { - LOG.debug("updateCurrentAttributes: id={}, dataBefore={}, dataAfter={}, ctx={}", id, dataBefore, dataAfter, ctx); - - final String bdName = checkNotNull(dataAfter.getName()); - checkArgument(bdName.equals(dataBefore.getName()), "BridgeDomain name changed. It should be deleted and then created."); - - int bdId = getVppApi().bridgeDomainIdFromName(bdName); - checkState(bdId > 0, "Unable to find bridge domain. Return code: %s", bdId); - - final int rv = addOrUpdateBridgeDomain(bdId, dataAfter); - - checkState(rv >= 0, "Bridge domain %s(%s) update failed. Return code: %s", bdName, bdId, rv); - LOG.debug("Bridge domain {}({}) updated successfully", bdName, bdId); - } - -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/BridgeDomainCustomizer.java deleted file mode 100644 index 178deaddf..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/BridgeDomainCustomizer.java +++ /dev/null @@ -1,136 +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.honeycomb.v3po.vpp.facade.v3po.vppstate; - -import com.google.common.collect.Lists; -import io.fd.honeycomb.v3po.vpp.facade.impl.util.VppApiCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.Context; -import io.fd.honeycomb.v3po.vpp.facade.spi.read.ListVppReaderCustomizer; -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.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppBridgeDomainDetails; -import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; -import org.openvpp.vppjapi.vppL2Fib; - -public final class BridgeDomainCustomizer extends VppApiCustomizer - implements ListVppReaderCustomizer { - - public BridgeDomainCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { - super(vppApi); - } - - @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context) { - final BridgeDomainKey key = id.firstKeyOf(id.getTargetType()); - // TODO find out if bd exists based on name and if not return - - final int bdId = getVppApi().bridgeDomainIdFromName(key.getName()); - final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bdId); - - builder.setName(key.getName()); - // builder.setName(bridgeDomainDetails.name); - builder.setArpTermination(bridgeDomainDetails.arpTerm); - builder.setFlood(bridgeDomainDetails.flood); - builder.setForward(bridgeDomainDetails.forward); - builder.setLearn(bridgeDomainDetails.learn); - builder.setUnknownUnicastFlood(bridgeDomainDetails.uuFlood); - - builder.setInterface(getIfcs(bridgeDomainDetails)); - - final vppL2Fib[] vppL2Fibs = getVppApi().l2FibTableDump(bdId); - - final List l2Fibs = Lists.newArrayListWithCapacity(vppL2Fibs.length); - for (vppL2Fib vppL2Fib : vppL2Fibs) { - l2Fibs.add(new L2FibBuilder() - .setAction((vppL2Fib.filter - ? L2Fib.Action.Filter - : L2Fib.Action.Forward)) - .setBridgedVirtualInterface(vppL2Fib.bridgedVirtualInterface) - .setOutgoingInterface(vppL2Fib.outgoingInterface) - .setPhysAddress(new PhysAddress(getMacAddress(vppL2Fib.physAddress))) - .setStaticConfig(vppL2Fib.staticConfig) - .build()); - } - builder.setL2Fib(l2Fibs); - } - - private static String getMacAddress(byte[] mac) { - StringBuilder sb = new StringBuilder(18); - for (byte b : mac) { - if (sb.length() > 0) { - sb.append(':'); - } - sb.append(String.format("%02x", b)); - } - return sb.toString(); - } - - private List getIfcs(final vppBridgeDomainDetails bridgeDomainDetails) { - final List ifcs = new ArrayList<>(bridgeDomainDetails.interfaces.length); - for (vppBridgeDomainInterfaceDetails anInterface : bridgeDomainDetails.interfaces) { - ifcs.add(new InterfaceBuilder() - .setBridgedVirtualInterface(bridgeDomainDetails.bviInterfaceName.equals(anInterface.interfaceName)) - .setName(anInterface.interfaceName) - .setKey(new InterfaceKey(anInterface.interfaceName)) - .build()); - } - return ifcs; - } - - @Nonnull - @Override - public BridgeDomainBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new BridgeDomainBuilder(); - } - - @Nonnull - @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final Context context) { - final int[] bIds = getVppApi().bridgeDomainDump(-1); - final List allIds = new ArrayList<>(bIds.length); - for (int bId : bIds) { - // FIXME this is highly inefficient having to dump all of the bridge domain details - // Use context to store already read information - // TODO Or just remove the getAllIds method and replace with a simple readAll - final vppBridgeDomainDetails bridgeDomainDetails = getVppApi().getBridgeDomainDetails(bId); - final String bName = bridgeDomainDetails.name; - allIds.add(new BridgeDomainKey(bName)); - } - - return allIds; - } - - @Override - public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((BridgeDomainsBuilder) builder).setBridgeDomain(readData); - } -} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VersionCustomizer.java deleted file mode 100644 index 3e928176e..000000000 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VersionCustomizer.java +++ /dev/null @@ -1,59 +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.honeycomb.v3po.vpp.facade.v3po.vppstate; - -import io.fd.honeycomb.v3po.vpp.facade.Context; -import io.fd.honeycomb.v3po.vpp.facade.impl.util.VppApiCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.spi.read.ChildVppReaderCustomizer; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; -import org.opendaylight.yangtools.concepts.Builder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppVersion; - -public final class VersionCustomizer - extends VppApiCustomizer - implements ChildVppReaderCustomizer { - - public VersionCustomizer(@Nonnull final org.openvpp.vppjapi.vppApi vppApi) { - super(vppApi); - } - - @Override - public void merge(@Nonnull final Builder parentBuilder, @Nonnull final Version readValue) { - ((VppStateBuilder) parentBuilder).setVersion(readValue); - } - - @Nonnull - @Override - public VersionBuilder getBuilder(@Nonnull InstanceIdentifier id) { - return new VersionBuilder(); - } - - @Override - public void readCurrentAttributes(@Nonnull InstanceIdentifier id, @Nonnull final VersionBuilder builder, - @Nonnull final Context context) { - final vppVersion vppVersion = getVppApi().getVppVersion(); - builder.setBranch(vppVersion.gitBranch); - builder.setName(vppVersion.programName); - builder.setBuildDate(vppVersion.buildDate); - builder.setBuildDirectory(vppVersion.buildDirectory); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java new file mode 100644 index 000000000..f504918a8 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vpp; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.MockitoAnnotations.initMocks; + +import io.fd.honeycomb.v3po.translate.Context; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +import org.openvpp.vppjapi.vppApi; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") +@PrepareForTest(vppApi.class) +public class BridgeDomainCustomizerTest { + + private static final int RESPONSE_NOT_READY = -77; + private static final byte ADD_OR_UPDATE_BD = (byte) 1; + private static final byte ZERO = 0; + private vppApi api; + + @Mock + private Context ctx; + + private BridgeDomainCustomizer customizer; + + @Before + public void setUp() throws Exception { + // TODO create base class for tests using vppApi + api = PowerMockito.mock(vppApi.class); + initMocks(this); + customizer = new BridgeDomainCustomizer(api); + + PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString()); + PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString()); + PowerMockito.when(api.getRetval(anyInt(), anyInt())).thenReturn(RESPONSE_NOT_READY).thenReturn(0); + PowerMockito.doReturn(0).when(api).getRetval(anyInt(), anyInt()); + } + + private BridgeDomain generateBridgeDomain(final String bdName) { + final byte arpTerm = 0; + final byte flood = 1; + final byte forward = 0; + final byte learn = 1; + final byte uuf = 0; + return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf); + } + + private BridgeDomain generateBridgeDomain(final String bdName, final int arpTerm, final int flood, + final int forward, final int learn, final int uuf) { + return new BridgeDomainBuilder() + .setName(bdName) + .setArpTermination(BridgeDomainTestUtils.intToBoolean(arpTerm)) + .setFlood(BridgeDomainTestUtils.intToBoolean(flood)) + .setForward(BridgeDomainTestUtils.intToBoolean(forward)) + .setLearn(BridgeDomainTestUtils.intToBoolean(learn)) + .setUnknownUnicastFlood(BridgeDomainTestUtils.intToBoolean(uuf)) + .build(); + } + + private final int verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd) { + final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName()); + final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination()); + final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood()); + final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward()); + final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn()); + final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood()); + return verify(api).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); + } + + private int verifyBridgeDomainAddOrUpdateWasNotInvoked(final BridgeDomain bd) { + final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName()); + final byte arpTerm = BridgeDomainTestUtils.booleanToByte(bd.isArpTermination()); + final byte flood = BridgeDomainTestUtils.booleanToByte(bd.isFlood()); + final byte forward = BridgeDomainTestUtils.booleanToByte(bd.isForward()); + final byte learn = BridgeDomainTestUtils.booleanToByte(bd.isLearn()); + final byte uuf = BridgeDomainTestUtils.booleanToByte(bd.isUnknownUnicastFlood()); + return verify(api, never()).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); + } + + private int verifyBridgeDomainDeletedWasInvoked(final BridgeDomain bd) { + final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName()); + return verify(api).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO); + } + + private int verifyBridgeDomainDeletedWasNotInvoked(final BridgeDomain bd) { + final int bdn1Id = BridgeDomainTestUtils.bdNameToID(bd.getName()); + return verify(api, never()).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO); + } + + @Test + public void testAddBridgeDomain() { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + + customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + + verifyBridgeDomainAddOrUpdateWasInvoked(bd); + } + + @Test + public void testBridgeDomainNameCreateFailed() { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + + // make vpp api fail to create id for our bd name + PowerMockito.doReturn(-1).when(api).findOrAddBridgeDomainId(bdName); + + try { + customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainAddOrUpdateWasNotInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + + @Test + public void testAddBridgeDomainFailed() { + // make any call to vpp fail + PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); + + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + + try { + customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainAddOrUpdateWasInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + + @Test + public void testDeleteBridgeDomain() { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + + customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + + verifyBridgeDomainDeletedWasInvoked(bd); + } + + @Test + public void testDeleteUnknownBridgeDomain() { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + + // make vpp api not find our bd + PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName); + + try { + customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainDeletedWasNotInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + + @Test + public void testDeleteBridgeDomainFailed() { + // make any call to vpp fail + PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); + + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + + try { + customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainDeletedWasInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + + @Test + public void testUpdateBridgeDomain() throws Exception { + final String bdName = "bd1"; + final byte arpTermBefore = 1; + final byte floodBefore = 1; + final byte forwardBefore = 0; + final byte learnBefore = 1; + final byte uufBefore = 0; + + final BridgeDomain dataBefore = + generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); + final BridgeDomain dataAfter = + generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, + uufBefore ^ 1); + + final KeyedInstanceIdentifier id = BridgeDomainTestUtils.bdIdentifierForName(bdName); + + customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx); + + verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter); + } + + @Test + public void testUpdateUnknownBridgeDomain() throws Exception { + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain("bd1"); + + // make vpp api not find our bd + PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName); + + try { + customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainAddOrUpdateWasNotInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + + @Test + public void testUpdateBridgeDomainFailed() { + // make any call to vpp fail + PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); + + final String bdName = "bd1"; + final BridgeDomain bd = generateBridgeDomain(bdName); + + try { + customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, bd, ctx); + } catch (IllegalStateException e) { + verifyBridgeDomainAddOrUpdateWasInvoked(bd); + return; + } + fail("IllegalStateException was expected"); + } + +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainTestUtils.java new file mode 100644 index 000000000..ba4df9e49 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainTestUtils.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vpp; + +import javax.annotation.Nullable; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; + +final class BridgeDomainTestUtils { + + private BridgeDomainTestUtils() { + throw new UnsupportedOperationException("Utility class cannot be instantiated."); + } + + public static byte booleanToByte(@Nullable final Boolean value) { + return value != null && value ? (byte) 1 : (byte) 0; + } + + @Nullable + public static Boolean intToBoolean(final int value) { + if (value == 0) { + return Boolean.FALSE; + } + if (value == 1) { + return Boolean.TRUE; + } + return null; + } + + public static int bdNameToID(String bName) { + return Integer.parseInt(((Character)bName.charAt(bName.length() - 1)).toString()); + } + + public static KeyedInstanceIdentifier bdIdentifierForName( + final String bdName) { + return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)); + } + + public static final Answer BD_NAME_TO_ID_ANSWER = new Answer() { + @Override + public Integer answer(final InvocationOnMock invocationOnMock) throws Throwable { + return bdNameToID((String) invocationOnMock.getArguments()[0]); + } + }; +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java new file mode 100644 index 000000000..0ff3ba16d --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vpp; + +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter; +import io.fd.honeycomb.v3po.translate.write.WriteContext; +import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry; +import io.fd.honeycomb.v3po.translate.write.Writer; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") +@PrepareForTest(vppApi.class) +public class VppTest { + + private vppApi api; + private DelegatingWriterRegistry rootRegistry; + private CompositeRootWriter vppWriter; + private WriteContext ctx; + + final byte zero = (byte) 0; + final byte flood = (byte) 1; + final byte forward = (byte) 0; + final byte learn = (byte) 1; + final byte uuf = (byte) 0; + final byte arpTerm = (byte) 0; + final byte add = (byte) 1; + + @Before + public void setUp() throws Exception { + api = PowerMockito.mock(vppApi.class); + ctx = mock(WriteContext.class); + PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString()); + PowerMockito.doAnswer(BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString()); + PowerMockito.doReturn(1).when(api).getRetval(anyInt(), anyInt()); + vppWriter = VppUtils.getVppWriter(api); + rootRegistry = new DelegatingWriterRegistry( + Collections.>singletonList(vppWriter)); + } + + @Test + public void writeVpp() throws Exception { + rootRegistry.update( + InstanceIdentifier.create(Vpp.class), + null, + new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), + ctx); + + verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); + + vppWriter.update(InstanceIdentifier.create(Vpp.class), + null, + new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), + ctx); + + verify(api, times(2)).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); + } + + @Test + public void writeVppFromRoot() throws Exception { + final Vpp vpp = new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(); + + rootRegistry.update(Collections., DataObject>emptyMap(), + Collections., DataObject>singletonMap(InstanceIdentifier.create(Vpp.class), + vpp), ctx); + + verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); + } + + private BridgeDomains getBridgeDomains(String... name) { + final List bdmns = Lists.newArrayList(); + for (String s : name) { + bdmns.add(new BridgeDomainBuilder() + .setName(s) + .setArpTermination(false) + .setFlood(true) + .setForward(false) + .setLearn(true) + .build()); + } + return new BridgeDomainsBuilder() + .setBridgeDomain(bdmns) + .build(); + } + + @Test + public void deleteVpp() throws Exception { + rootRegistry.update( + InstanceIdentifier.create(Vpp.class), + new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), + null, + ctx); + + final byte zero = (byte) 0; + + verify(api).bridgeDomainAddDel(1, zero, zero, zero, zero, zero, zero); + } + + @Test + public void updateVppNoActualChange() throws Exception { + rootRegistry.update( + InstanceIdentifier.create(Vpp.class), + new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), + new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), + ctx); + + verifyZeroInteractions(api); + } + + @Test + public void writeUpdate() throws Exception { + final BridgeDomains domainsBefore = getBridgeDomains("bdn1"); + final BridgeDomain bdn1Before = domainsBefore.getBridgeDomain().get(0); + + final BridgeDomain bdn1After = new BridgeDomainBuilder(bdn1Before).setFlood(!bdn1Before.isFlood()).build(); + final BridgeDomains domainsAfter = new BridgeDomainsBuilder() + .setBridgeDomain(Collections.singletonList(bdn1After)) + .build(); + + rootRegistry.update( + InstanceIdentifier.create(Vpp.class), + new VppBuilder().setBridgeDomains(domainsBefore).build(), + new VppBuilder().setBridgeDomains(domainsAfter).build(), + ctx); + + final int bdn1Id = 1; + + // bdn1 is created with negated flood value + verify(api).bridgeDomainAddDel(bdn1Id, (byte) (flood ^ 1), forward, learn, uuf, arpTerm, add); + } + + // TODO test unkeyed list + // TODO test update of a child without dedicated writer +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java new file mode 100644 index 000000000..cb74314e3 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppUtils.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vpp; + +import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter; +import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer; +import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.write.ChildWriter; +import io.fd.honeycomb.v3po.translate.util.RWUtils; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.openvpp.vppjapi.vppApi; + +final class VppUtils { + + public VppUtils() {} + + /** + * Create root Vpp writer with all its children wired + */ + static CompositeRootWriter getVppWriter(@Nonnull final vppApi vppApi) { + + final CompositeListWriter bridgeDomainWriter = new CompositeListWriter<>( + BridgeDomain.class, + new BridgeDomainCustomizer(vppApi)); + + final ChildWriter bridgeDomainsReader = new CompositeChildWriter<>( + BridgeDomains.class, + RWUtils.singletonChildWriterList(bridgeDomainWriter), + new ReflexiveChildWriterCustomizer()); + + final List>> childWriters = new ArrayList<>(); + childWriters.add(bridgeDomainsReader); + + return new CompositeRootWriter<>( + Vpp.class, + childWriters, + new NoopWriterCustomizer()); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java new file mode 100644 index 000000000..6f53f6519 --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vppstate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; + +import com.google.common.base.Optional; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; +import io.fd.honeycomb.v3po.translate.util.read.DelegatingReaderRegistry; +import io.fd.honeycomb.v3po.translate.read.ReadContext; +import io.fd.honeycomb.v3po.translate.read.Reader; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; +import org.openvpp.vppjapi.vppBridgeDomainDetails; +import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; +import org.openvpp.vppjapi.vppL2Fib; +import org.openvpp.vppjapi.vppVersion; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") +@PrepareForTest(vppApi.class) +public class VppStateTest { + + public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33"); + + private vppApi api; + private CompositeRootReader vppStateReader; + private DelegatingReaderRegistry readerRegistry; + private vppBridgeDomainDetails bdDetails; + private vppBridgeDomainDetails bdDetails2; + private ReadContext ctx; + + @Before + public void setUp() throws Exception { + api = PowerMockito.mock(vppApi.class); + + ctx = mock(ReadContext.class); + + bdDetails = new vppBridgeDomainDetails(); + setIfcs(bdDetails); + setBaseAttrs(bdDetails, "bdn1", 1); + + bdDetails2 = new vppBridgeDomainDetails(); + setIfcs(bdDetails2); + setBaseAttrs(bdDetails2, "bdn2", 2); + + final vppL2Fib[] l2Fibs = getL2Fibs(); + PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt()); + PowerMockito.doAnswer(new Answer() { + + @Override + public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable { + final Integer idx = (Integer) invocationOnMock.getArguments()[0]; + switch (idx) { + case 1 : return bdDetails; + case 2 : return bdDetails2; + default: return null; + } + } + }).when(api).getBridgeDomainDetails(Matchers.anyInt()); + + PowerMockito.doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { + final String name = (String) invocationOnMock.getArguments()[0]; + switch (name) { + case "bdn1" : return 1; + case "bdn2" : return 2; + default: return null; + } + } + }).when(api).bridgeDomainIdFromName(anyString()); + PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt()); + PowerMockito.doReturn(VERSION).when(api).getVppVersion(); + vppStateReader = VppStateUtils.getVppStateReader(api); + readerRegistry = new DelegatingReaderRegistry(Collections.>singletonList(vppStateReader)); + } + + private vppL2Fib[] getL2Fibs() { + return new vppL2Fib[] { + new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true), + new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true), + }; + } + + private void setIfcs(final vppBridgeDomainDetails bdDetails) { + final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails(); + ifcDetails.interfaceName = "ifc"; + ifcDetails.splitHorizonGroup = 2; + bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails}; + } + + private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) { + bdDetails.name = bdn; + bdDetails.arpTerm = true; + bdDetails.bdId = i; + bdDetails.bviInterfaceName = "ifc"; + bdDetails.flood = true; + bdDetails.forward = true; + bdDetails.learn = true; + bdDetails.uuFlood = true; + } + + @Test + public void testReadAll() throws Exception { + final Multimap, ? extends DataObject> dataObjects = readerRegistry.readAll(ctx); + assertEquals(dataObjects.size(), 1); + final DataObject dataObject = Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet()))); + assertTrue(dataObject instanceof VppState); + assertVersion((VppState) dataObject); + assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size()); + } + + private void assertVersion(final VppState dataObject) { + assertEquals( + new VersionBuilder() + .setName("test") + .setBuildDirectory("1") + .setBranch("2") + .setBuildDate("33") + .build(), + dataObject.getVersion()); + } + + @Test + public void testReadSpecific() throws Exception { + final Optional read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx); + assertTrue(read.isPresent()); + assertVersion((VppState) read.get()); + } + + @Test + public void testReadBridgeDomains() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class), ctx); + assertTrue(read.isPresent()); + assertEquals(readRoot.getBridgeDomains(), read.get()); + } + + /** + * L2fib does not have a dedicated reader, relying on auto filtering + */ + @Test + public void testReadL2Fib() throws Exception { + // Deep child without a dedicated reader with specific l2fib key + Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")) + .child(L2Fib.class, new L2FibKey(new PhysAddress("01:02:03:04:05:06"))), ctx); + assertTrue(read.isPresent()); + + // non existing l2fib + read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")) + .child(L2Fib.class, new L2FibKey(new PhysAddress("FF:FF:FF:04:05:06"))), ctx); + assertFalse(read.isPresent()); + } + + @Test + public void testReadBridgeDomainAll() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + final CompositeListReader bridgeDomainReader = + VppStateUtils.getBridgeDomainReader(api); + + final List read = + bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class), ctx); + + assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); + } + + @Test + public void testReadBridgeDomain() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + final Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("bdn1")), ctx); + + assertTrue(read.isPresent()); + assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate() { + @Override + public boolean apply(final BridgeDomain input) { + return input.getKey().getName().equals("bdn1"); + } + }), read.get()); + } + + // FIXME + @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there") + @Test + public void testReadBridgeDomainNotExisting() throws Exception { + final Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( + BridgeDomain.class, new BridgeDomainKey("NOT EXISTING")), ctx); + assertFalse(read.isPresent()); + } + + @Test + public void testReadVersion() throws Exception { + VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); + + Optional read = + readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx); + assertTrue(read.isPresent()); + assertEquals(readRoot.getVersion(), read.get()); + } +} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java new file mode 100644 index 000000000..5c619d84d --- /dev/null +++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateUtils.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.vppstate; + +import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; +import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; +import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer; +import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; +import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.read.ChildReader; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.openvpp.vppjapi.vppApi; + +final class VppStateUtils { + + public VppStateUtils() {} + + /** + * Create root VppState reader with all its children wired + */ + static CompositeRootReader getVppStateReader(@Nonnull final vppApi vppApi) { + + final ChildReader versionReader = new CompositeChildReader<>( + Version.class, new VersionCustomizer(vppApi)); + + final CompositeListReader bridgeDomainReader = + getBridgeDomainReader(vppApi); + + final ChildReader bridgeDomainsReader = new CompositeChildReader<>( + BridgeDomains.class, + RWUtils.singletonChildReaderList(bridgeDomainReader), + new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class)); + + final List>> childVppReaders = new ArrayList<>(); + childVppReaders.add(versionReader); + childVppReaders.add(bridgeDomainsReader); + + return new CompositeRootReader<>( + VppState.class, + childVppReaders, + RWUtils.emptyAugReaderList(), + new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)); + } + + static CompositeListReader getBridgeDomainReader( + final @Nonnull vppApi vppApi) { + return new CompositeListReader<>( + BridgeDomain.class, + new BridgeDomainCustomizer(vppApi)); + } +} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizerTest.java deleted file mode 100644 index 059713544..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainCustomizerTest.java +++ /dev/null @@ -1,269 +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.honeycomb.v3po.vpp.facade.v3po.vpp; - -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER; -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.bdIdentifierForName; -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.bdNameToID; -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.booleanToByte; -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.intToBoolean; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.MockitoAnnotations.initMocks; - -import io.fd.honeycomb.v3po.vpp.facade.Context; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.openvpp.vppjapi.vppApi; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") -@PrepareForTest(vppApi.class) -public class BridgeDomainCustomizerTest { - - private static final int RESPONSE_NOT_READY = -77; - private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private static final byte ZERO = 0; - private vppApi api; - - @Mock - private Context ctx; - - private BridgeDomainCustomizer customizer; - - @Before - public void setUp() throws Exception { - // TODO create base class for tests using vppApi - api = PowerMockito.mock(vppApi.class); - initMocks(this); - customizer = new BridgeDomainCustomizer(api); - - PowerMockito.doAnswer(BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString()); - PowerMockito.doAnswer(BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString()); - PowerMockito.when(api.getRetval(anyInt(), anyInt())).thenReturn(RESPONSE_NOT_READY).thenReturn(0); - PowerMockito.doReturn(0).when(api).getRetval(anyInt(), anyInt()); - } - - private BridgeDomain generateBridgeDomain(final String bdName) { - final byte arpTerm = 0; - final byte flood = 1; - final byte forward = 0; - final byte learn = 1; - final byte uuf = 0; - return generateBridgeDomain(bdName, arpTerm, flood, forward, learn, uuf); - } - - private BridgeDomain generateBridgeDomain(final String bdName, final int arpTerm, final int flood, - final int forward, final int learn, final int uuf) { - return new BridgeDomainBuilder() - .setName(bdName) - .setArpTermination(intToBoolean(arpTerm)) - .setFlood(intToBoolean(flood)) - .setForward(intToBoolean(forward)) - .setLearn(intToBoolean(learn)) - .setUnknownUnicastFlood(intToBoolean(uuf)) - .build(); - } - - private final int verifyBridgeDomainAddOrUpdateWasInvoked(final BridgeDomain bd) { - final int bdn1Id = bdNameToID(bd.getName()); - final byte arpTerm = booleanToByte(bd.isArpTermination()); - final byte flood = booleanToByte(bd.isFlood()); - final byte forward = booleanToByte(bd.isForward()); - final byte learn = booleanToByte(bd.isLearn()); - final byte uuf = booleanToByte(bd.isUnknownUnicastFlood()); - return verify(api).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); - } - - private int verifyBridgeDomainAddOrUpdateWasNotInvoked(final BridgeDomain bd) { - final int bdn1Id = bdNameToID(bd.getName()); - final byte arpTerm = booleanToByte(bd.isArpTermination()); - final byte flood = booleanToByte(bd.isFlood()); - final byte forward = booleanToByte(bd.isForward()); - final byte learn = booleanToByte(bd.isLearn()); - final byte uuf = booleanToByte(bd.isUnknownUnicastFlood()); - return verify(api, never()).bridgeDomainAddDel(bdn1Id, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); - } - - private int verifyBridgeDomainDeletedWasInvoked(final BridgeDomain bd) { - final int bdn1Id = bdNameToID(bd.getName()); - return verify(api).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO); - } - - private int verifyBridgeDomainDeletedWasNotInvoked(final BridgeDomain bd) { - final int bdn1Id = bdNameToID(bd.getName()); - return verify(api, never()).bridgeDomainAddDel(bdn1Id, ZERO, ZERO, ZERO, ZERO, ZERO, ZERO); - } - - @Test - public void testAddBridgeDomain() { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - - verifyBridgeDomainAddOrUpdateWasInvoked(bd); - } - - @Test - public void testBridgeDomainNameCreateFailed() { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - - // make vpp api fail to create id for our bd name - PowerMockito.doReturn(-1).when(api).findOrAddBridgeDomainId(bdName); - - try { - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainAddOrUpdateWasNotInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - - @Test - public void testAddBridgeDomainFailed() { - // make any call to vpp fail - PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); - - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - - try { - customizer.writeCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainAddOrUpdateWasInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - - @Test - public void testDeleteBridgeDomain() { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - - verifyBridgeDomainDeletedWasInvoked(bd); - } - - @Test - public void testDeleteUnknownBridgeDomain() { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - - // make vpp api not find our bd - PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName); - - try { - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainDeletedWasNotInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - - @Test - public void testDeleteBridgeDomainFailed() { - // make any call to vpp fail - PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); - - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - - try { - customizer.deleteCurrentAttributes(bdIdentifierForName(bdName), bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainDeletedWasInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - - @Test - public void testUpdateBridgeDomain() throws Exception { - final String bdName = "bd1"; - final byte arpTermBefore = 1; - final byte floodBefore = 1; - final byte forwardBefore = 0; - final byte learnBefore = 1; - final byte uufBefore = 0; - - final BridgeDomain dataBefore = - generateBridgeDomain(bdName, arpTermBefore, floodBefore, forwardBefore, learnBefore, uufBefore); - final BridgeDomain dataAfter = - generateBridgeDomain(bdName, arpTermBefore ^ 1, floodBefore ^ 1, forwardBefore ^ 1, learnBefore ^ 1, - uufBefore ^ 1); - - final KeyedInstanceIdentifier id = bdIdentifierForName(bdName); - - customizer.updateCurrentAttributes(id, dataBefore, dataAfter, ctx); - - verifyBridgeDomainAddOrUpdateWasInvoked(dataAfter); - } - - @Test - public void testUpdateUnknownBridgeDomain() throws Exception { - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain("bd1"); - - // make vpp api not find our bd - PowerMockito.doReturn(-1).when(api).bridgeDomainIdFromName(bdName); - - try { - customizer.updateCurrentAttributes(bdIdentifierForName(bdName), bd, bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainAddOrUpdateWasNotInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - - @Test - public void testUpdateBridgeDomainFailed() { - // make any call to vpp fail - PowerMockito.doReturn(-1).when(api).getRetval(anyInt(), anyInt()); - - final String bdName = "bd1"; - final BridgeDomain bd = generateBridgeDomain(bdName); - - try { - customizer.updateCurrentAttributes(bdIdentifierForName(bdName), bd, bd, ctx); - } catch (IllegalStateException e) { - verifyBridgeDomainAddOrUpdateWasInvoked(bd); - return; - } - fail("IllegalStateException was expected"); - } - -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainTestUtils.java deleted file mode 100644 index 51a6b023e..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/BridgeDomainTestUtils.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.honeycomb.v3po.vpp.facade.v3po.vpp; - -import javax.annotation.Nullable; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; - -final class BridgeDomainTestUtils { - - private BridgeDomainTestUtils() { - throw new UnsupportedOperationException("Utility class cannot be instantiated."); - } - - public static byte booleanToByte(@Nullable final Boolean value) { - return value != null && value ? (byte) 1 : (byte) 0; - } - - @Nullable - public static Boolean intToBoolean(final int value) { - if (value == 0) { - return Boolean.FALSE; - } - if (value == 1) { - return Boolean.TRUE; - } - return null; - } - - public static int bdNameToID(String bName) { - return Integer.parseInt(((Character)bName.charAt(bName.length() - 1)).toString()); - } - - public static KeyedInstanceIdentifier bdIdentifierForName( - final String bdName) { - return InstanceIdentifier.create(BridgeDomains.class).child(BridgeDomain.class, new BridgeDomainKey(bdName)); - } - - public static final Answer BD_NAME_TO_ID_ANSWER = new Answer() { - @Override - public Integer answer(final InvocationOnMock invocationOnMock) throws Throwable { - return bdNameToID((String) invocationOnMock.getArguments()[0]); - } - }; -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppTest.java deleted file mode 100644 index bc5bda383..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppTest.java +++ /dev/null @@ -1,174 +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.honeycomb.v3po.vpp.facade.v3po.vpp; - -import static io.fd.honeycomb.v3po.vpp.facade.v3po.vpp.BridgeDomainTestUtils.BD_NAME_TO_ID_ANSWER; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -import com.google.common.collect.Lists; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.CompositeRootVppWriter; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.util.DelegatingWriterRegistry; -import io.fd.honeycomb.v3po.vpp.facade.write.VppWriter; -import io.fd.honeycomb.v3po.vpp.facade.write.WriteContext; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppApi; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") -@PrepareForTest(vppApi.class) -public class VppTest { - - private vppApi api; - private DelegatingWriterRegistry rootRegistry; - private CompositeRootVppWriter vppWriter; - private WriteContext ctx; - - final byte zero = (byte) 0; - final byte flood = (byte) 1; - final byte forward = (byte) 0; - final byte learn = (byte) 1; - final byte uuf = (byte) 0; - final byte arpTerm = (byte) 0; - final byte add = (byte) 1; - - @Before - public void setUp() throws Exception { - api = PowerMockito.mock(vppApi.class); - ctx = mock(WriteContext.class); - PowerMockito.doAnswer(BD_NAME_TO_ID_ANSWER).when(api).findOrAddBridgeDomainId(anyString()); - PowerMockito.doAnswer(BD_NAME_TO_ID_ANSWER).when(api).bridgeDomainIdFromName(anyString()); - PowerMockito.doReturn(1).when(api).getRetval(anyInt(), anyInt()); - vppWriter = VppUtils.getVppWriter(api); - rootRegistry = new DelegatingWriterRegistry( - Collections.>singletonList(vppWriter)); - } - - @Test - public void writeVpp() throws Exception { - rootRegistry.update( - InstanceIdentifier.create(Vpp.class), - null, - new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), - ctx); - - verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); - - vppWriter.update(InstanceIdentifier.create(Vpp.class), - null, - new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), - ctx); - - verify(api, times(2)).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); - } - - @Test - public void writeVppFromRoot() throws Exception { - final Vpp vpp = new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(); - - rootRegistry.update(Collections., DataObject>emptyMap(), - Collections., DataObject>singletonMap(InstanceIdentifier.create(Vpp.class), - vpp), ctx); - - verify(api).bridgeDomainAddDel(1, flood, forward, learn, uuf, arpTerm, add); - } - - private BridgeDomains getBridgeDomains(String... name) { - final List bdmns = Lists.newArrayList(); - for (String s : name) { - bdmns.add(new BridgeDomainBuilder() - .setName(s) - .setArpTermination(false) - .setFlood(true) - .setForward(false) - .setLearn(true) - .build()); - } - return new BridgeDomainsBuilder() - .setBridgeDomain(bdmns) - .build(); - } - - @Test - public void deleteVpp() throws Exception { - rootRegistry.update( - InstanceIdentifier.create(Vpp.class), - new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), - null, - ctx); - - final byte zero = (byte) 0; - - verify(api).bridgeDomainAddDel(1, zero, zero, zero, zero, zero, zero); - } - - @Test - public void updateVppNoActualChange() throws Exception { - rootRegistry.update( - InstanceIdentifier.create(Vpp.class), - new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), - new VppBuilder().setBridgeDomains(getBridgeDomains("bdn1")).build(), - ctx); - - verifyZeroInteractions(api); - } - - @Test - public void writeUpdate() throws Exception { - final BridgeDomains domainsBefore = getBridgeDomains("bdn1"); - final BridgeDomain bdn1Before = domainsBefore.getBridgeDomain().get(0); - - final BridgeDomain bdn1After = new BridgeDomainBuilder(bdn1Before).setFlood(!bdn1Before.isFlood()).build(); - final BridgeDomains domainsAfter = new BridgeDomainsBuilder() - .setBridgeDomain(Collections.singletonList(bdn1After)) - .build(); - - rootRegistry.update( - InstanceIdentifier.create(Vpp.class), - new VppBuilder().setBridgeDomains(domainsBefore).build(), - new VppBuilder().setBridgeDomains(domainsAfter).build(), - ctx); - - final int bdn1Id = 1; - - // bdn1 is created with negated flood value - verify(api).bridgeDomainAddDel(bdn1Id, (byte) (flood ^ 1), forward, learn, uuf, arpTerm, add); - } - - // TODO test unkeyed list - // TODO test update of a child without dedicated writer -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppUtils.java deleted file mode 100644 index ccf19c81c..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vpp/VppUtils.java +++ /dev/null @@ -1,62 +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.honeycomb.v3po.vpp.facade.v3po.vpp; - -import io.fd.honeycomb.v3po.vpp.facade.impl.util.VppRWUtils; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.CompositeChildVppWriter; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.CompositeListVppWriter; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.CompositeRootVppWriter; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.util.NoopWriterCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.impl.write.util.ReflexiveChildWriterCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.write.ChildVppWriter; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.openvpp.vppjapi.vppApi; - -final class VppUtils { - - public VppUtils() {} - - /** - * Create root Vpp writer with all its children wired - */ - static CompositeRootVppWriter getVppWriter(@Nonnull final vppApi vppApi) { - - final CompositeListVppWriter bridgeDomainWriter = new CompositeListVppWriter<>( - BridgeDomain.class, - new BridgeDomainCustomizer(vppApi)); - - final ChildVppWriter bridgeDomainsReader = new CompositeChildVppWriter<>( - BridgeDomains.class, - VppRWUtils.singletonChildWriterList(bridgeDomainWriter), - new ReflexiveChildWriterCustomizer()); - - final List>> childWriters = new ArrayList<>(); - childWriters.add(bridgeDomainsReader); - - return new CompositeRootVppWriter<>( - Vpp.class, - childWriters, - new NoopWriterCustomizer()); - } -} diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateTest.java deleted file mode 100644 index 059c98f56..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateTest.java +++ /dev/null @@ -1,259 +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.honeycomb.v3po.vpp.facade.v3po.vppstate; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; - -import com.google.common.base.Optional; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Multimap; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.CompositeListVppReader; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.CompositeRootVppReader; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.util.DelegatingReaderRegistry; -import io.fd.honeycomb.v3po.vpp.facade.read.ReadContext; -import io.fd.honeycomb.v3po.vpp.facade.read.VppReader; -import java.util.Collections; -import java.util.List; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.VersionBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2Fib; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.bridge.domain.L2FibKey; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.openvpp.vppjapi.vppApi; -import org.openvpp.vppjapi.vppBridgeDomainDetails; -import org.openvpp.vppjapi.vppBridgeDomainInterfaceDetails; -import org.openvpp.vppjapi.vppL2Fib; -import org.openvpp.vppjapi.vppVersion; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("org.openvpp.vppjapi.vppConn") -@PrepareForTest(vppApi.class) -public class VppStateTest { - - public static final vppVersion VERSION = new vppVersion("test", "1", "2", "33"); - - private vppApi api; - private CompositeRootVppReader vppStateReader; - private DelegatingReaderRegistry readerRegistry; - private vppBridgeDomainDetails bdDetails; - private vppBridgeDomainDetails bdDetails2; - private ReadContext ctx; - - @Before - public void setUp() throws Exception { - api = PowerMockito.mock(vppApi.class); - - ctx = mock(ReadContext.class); - - bdDetails = new vppBridgeDomainDetails(); - setIfcs(bdDetails); - setBaseAttrs(bdDetails, "bdn1", 1); - - bdDetails2 = new vppBridgeDomainDetails(); - setIfcs(bdDetails2); - setBaseAttrs(bdDetails2, "bdn2", 2); - - final vppL2Fib[] l2Fibs = getL2Fibs(); - PowerMockito.doReturn(l2Fibs).when(api).l2FibTableDump(Matchers.anyInt()); - PowerMockito.doAnswer(new Answer() { - - @Override - public vppBridgeDomainDetails answer(final InvocationOnMock invocationOnMock) throws Throwable { - final Integer idx = (Integer) invocationOnMock.getArguments()[0]; - switch (idx) { - case 1 : return bdDetails; - case 2 : return bdDetails2; - default: return null; - } - } - }).when(api).getBridgeDomainDetails(Matchers.anyInt()); - - PowerMockito.doAnswer(new Answer() { - @Override - public Object answer(final InvocationOnMock invocationOnMock) throws Throwable { - final String name = (String) invocationOnMock.getArguments()[0]; - switch (name) { - case "bdn1" : return 1; - case "bdn2" : return 2; - default: return null; - } - } - }).when(api).bridgeDomainIdFromName(anyString()); - PowerMockito.doReturn(new int[] {1, 2}).when(api).bridgeDomainDump(Matchers.anyInt()); - PowerMockito.doReturn(VERSION).when(api).getVppVersion(); - vppStateReader = VppStateUtils.getVppStateReader(api); - readerRegistry = new DelegatingReaderRegistry(Collections.>singletonList(vppStateReader)); - } - - private vppL2Fib[] getL2Fibs() { - return new vppL2Fib[] { - new vppL2Fib(new byte[]{1,2,3,4,5,6}, true, "ifc1", true, true), - new vppL2Fib(new byte[]{2,2,3,4,5,6}, true, "ifc2", true, true), - }; - } - - private void setIfcs(final vppBridgeDomainDetails bdDetails) { - final vppBridgeDomainInterfaceDetails ifcDetails = new vppBridgeDomainInterfaceDetails(); - ifcDetails.interfaceName = "ifc"; - ifcDetails.splitHorizonGroup = 2; - bdDetails.interfaces = new vppBridgeDomainInterfaceDetails[] {ifcDetails}; - } - - private void setBaseAttrs(final vppBridgeDomainDetails bdDetails, final String bdn, final int i) { - bdDetails.name = bdn; - bdDetails.arpTerm = true; - bdDetails.bdId = i; - bdDetails.bviInterfaceName = "ifc"; - bdDetails.flood = true; - bdDetails.forward = true; - bdDetails.learn = true; - bdDetails.uuFlood = true; - } - - @Test - public void testReadAll() throws Exception { - final Multimap, ? extends DataObject> dataObjects = readerRegistry.readAll(ctx); - assertEquals(dataObjects.size(), 1); - final DataObject dataObject = Iterables.getOnlyElement(dataObjects.get(Iterables.getOnlyElement(dataObjects.keySet()))); - assertTrue(dataObject instanceof VppState); - assertVersion((VppState) dataObject); - assertEquals(2, ((VppState) dataObject).getBridgeDomains().getBridgeDomain().size()); - } - - private void assertVersion(final VppState dataObject) { - assertEquals( - new VersionBuilder() - .setName("test") - .setBuildDirectory("1") - .setBranch("2") - .setBuildDate("33") - .build(), - dataObject.getVersion()); - } - - @Test - public void testReadSpecific() throws Exception { - final Optional read = readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx); - assertTrue(read.isPresent()); - assertVersion((VppState) read.get()); - } - - @Test - public void testReadBridgeDomains() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class), ctx); - assertTrue(read.isPresent()); - assertEquals(readRoot.getBridgeDomains(), read.get()); - } - - /** - * L2fib does not have a dedicated reader, relying on auto filtering - */ - @Test - public void testReadL2Fib() throws Exception { - // Deep child without a dedicated reader with specific l2fib key - Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")) - .child(L2Fib.class, new L2FibKey(new PhysAddress("01:02:03:04:05:06"))), ctx); - assertTrue(read.isPresent()); - - // non existing l2fib - read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")) - .child(L2Fib.class, new L2FibKey(new PhysAddress("FF:FF:FF:04:05:06"))), ctx); - assertFalse(read.isPresent()); - } - - @Test - public void testReadBridgeDomainAll() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - final CompositeListVppReader bridgeDomainReader = - VppStateUtils.getBridgeDomainReader(api); - - final List read = - bridgeDomainReader.readList(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class), ctx); - - assertEquals(readRoot.getBridgeDomains().getBridgeDomain(), read); - } - - @Test - public void testReadBridgeDomain() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - final Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("bdn1")), ctx); - - assertTrue(read.isPresent()); - assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(), new Predicate() { - @Override - public boolean apply(final BridgeDomain input) { - return input.getKey().getName().equals("bdn1"); - } - }), read.get()); - } - - // FIXME - @Ignore("Bridge domain customizer does not check whether the bd exists or not and fails with NPE, add it there") - @Test - public void testReadBridgeDomainNotExisting() throws Exception { - final Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child( - BridgeDomain.class, new BridgeDomainKey("NOT EXISTING")), ctx); - assertFalse(read.isPresent()); - } - - @Test - public void testReadVersion() throws Exception { - VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get(); - - Optional read = - readerRegistry.read(InstanceIdentifier.create(VppState.class).child(Version.class), ctx); - assertTrue(read.isPresent()); - assertEquals(readRoot.getVersion(), read.get()); - } -} \ No newline at end of file diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateUtils.java deleted file mode 100644 index 7d5441769..000000000 --- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/vpp/facade/v3po/vppstate/VppStateUtils.java +++ /dev/null @@ -1,77 +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.honeycomb.v3po.vpp.facade.v3po.vppstate; - -import io.fd.honeycomb.v3po.vpp.facade.impl.read.CompositeChildVppReader; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.CompositeListVppReader; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.CompositeRootVppReader; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.util.ReflexiveChildReaderCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.impl.read.util.ReflexiveRootReaderCustomizer; -import io.fd.honeycomb.v3po.vpp.facade.impl.util.VppRWUtils; -import io.fd.honeycomb.v3po.vpp.facade.read.ChildVppReader; -import java.util.ArrayList; -import java.util.List; -import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomainsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.Version; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomain; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; -import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.openvpp.vppjapi.vppApi; - -final class VppStateUtils { - - public VppStateUtils() {} - - /** - * Create root VppState reader with all its children wired - */ - static CompositeRootVppReader getVppStateReader(@Nonnull final vppApi vppApi) { - - final ChildVppReader versionReader = new CompositeChildVppReader<>( - Version.class, new VersionCustomizer(vppApi)); - - final CompositeListVppReader bridgeDomainReader = - getBridgeDomainReader(vppApi); - - final ChildVppReader bridgeDomainsReader = new CompositeChildVppReader<>( - BridgeDomains.class, - VppRWUtils.singletonChildReaderList(bridgeDomainReader), - new ReflexiveChildReaderCustomizer<>(BridgeDomainsBuilder.class)); - - final List>> childVppReaders = new ArrayList<>(); - childVppReaders.add(versionReader); - childVppReaders.add(bridgeDomainsReader); - - return new CompositeRootVppReader<>( - VppState.class, - childVppReaders, - VppRWUtils.emptyAugReaderList(), - new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class)); - } - - static CompositeListVppReader getBridgeDomainReader( - final @Nonnull vppApi vppApi) { - return new CompositeListVppReader<>( - BridgeDomain.class, - new BridgeDomainCustomizer(vppApi)); - } -} -- cgit 1.2.3-korg