From 24cda75577b8162a41718f0fff73b83994f1dcf4 Mon Sep 17 00:00:00 2001 From: Marek Ryznar Date: Thu, 9 Feb 2017 15:57:17 +0100 Subject: [PATCH] Refactoring of cisco-xr-driver and impl modules. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. Signed-off-by: Marek Ryznar Change-Id: I8c09e798d93bf29864025bfdd53e61e8bd2ef5c7 --- api/src/main/yang/cl-unimgr-mef.yang | 8 + cisco-xr-driver/pom.xml | 8 + .../helper/BandwidthProfileComposition.java | 182 ++++++++++++++ .../common/helper/BandwidthProfileHelper.java | 191 ++++++++++++++ .../xr/common/helper/InterfaceHelper.java | 2 +- .../cisco/xr/common/util/LoopbackUtils.java | 55 ++++- .../activator/AbstractL2vpnActivator.java | 61 ++--- .../l2vpn/activator/L2vpnBridgeActivator.java | 23 +- .../activator/L2vpnXconnectActivator.java | 24 +- .../driver/L2vpnBridgeDriverBuilder.java | 25 +- .../driver/L2vpnXconnectDriverBuilder.java | 29 ++- .../BandwidthProfileCompositionTest.java | 180 ++++++++++++++ .../helper/BandwidthProfileHelperTest.java | 223 +++++++++++++++++ .../xr/common/helper/InterfaceHelperTest.java | 6 +- .../xr/common/util/LoopbackUtilsTest.java | 134 ++++++++++ .../activator/L2vpnActivatorTestUtils.java | 72 ++++-- .../activator/L2vpnBridgeActivatorTest.java | 78 +++--- .../activator/L2vpnXconnectActivatorTest.java | 28 ++- .../driver/L2vpnBridgeDriverBuilderTest.java | 108 ++++++++ .../L2vpnXconnectDriverBuilderTest.java | 108 ++++++++ .../xr/l2vpn/helper/XConnectHelperTest.java | 1 - impl/pom.xml | 23 +- .../ForwardingConstructActivatorService.java | 2 + .../unimgr/mef/nrp/api/ActivationDriver.java | 6 +- .../mef/nrp/common/ResourceActivator.java | 5 +- .../common/ResourceActivatorException.java | 27 ++ .../common/ResourceNotAvailableException.java | 21 ++ .../unimgr/utils/CapabilitiesService.java | 153 ++++++++++++ .../opendaylight/unimgr/utils/MdsalUtils.java | 76 ++++++ .../unimgr/utils/NetconfConstants.java | 15 ++ .../utils/NullAwareDatastoreGetter.java | 83 +++++++ .../unimgr/utils/CapabilitiesServiceTest.java | 134 ++++++++++ .../unimgr/utils/MdsalUtilsTest.java | 95 ++++++- .../unimgr/utils/NodeTestUtils.java | 110 +++++++++ .../utils/NullAwareDatastoreGetterTest.java | 233 ++++++++++++++++++ 35 files changed, 2385 insertions(+), 144 deletions(-) create mode 100644 cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileComposition.java create mode 100644 cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelper.java create mode 100644 cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileCompositionTest.java create mode 100644 cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelperTest.java create mode 100644 cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtilsTest.java create mode 100644 cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilderTest.java create mode 100644 cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilderTest.java create mode 100644 impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivatorException.java create mode 100644 impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceNotAvailableException.java create mode 100644 impl/src/main/java/org/opendaylight/unimgr/utils/CapabilitiesService.java create mode 100644 impl/src/main/java/org/opendaylight/unimgr/utils/NetconfConstants.java create mode 100644 impl/src/main/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetter.java create mode 100644 impl/src/test/java/org/opendaylight/unimgr/utils/CapabilitiesServiceTest.java create mode 100644 impl/src/test/java/org/opendaylight/unimgr/utils/NodeTestUtils.java create mode 100644 impl/src/test/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetterTest.java diff --git a/api/src/main/yang/cl-unimgr-mef.yang b/api/src/main/yang/cl-unimgr-mef.yang index 2f6d84df..a2edb659 100755 --- a/api/src/main/yang/cl-unimgr-mef.yang +++ b/api/src/main/yang/cl-unimgr-mef.yang @@ -142,4 +142,12 @@ module cl-unimgr-mef { uses evc; } + augment "/topo:network-topology/topo:topology/topo:node" { + description "Augmentation for loopback address nodes under topology"; + ext:augment-identifier "loopback-augmentation"; + leaf loopback-address { + type inet:ip-address; + } + } + } diff --git a/cisco-xr-driver/pom.xml b/cisco-xr-driver/pom.xml index f1791d92..7dda412b 100644 --- a/cisco-xr-driver/pom.xml +++ b/cisco-xr-driver/pom.xml @@ -46,6 +46,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL ${project.version} + + ${project.groupId} + unimgr-impl + ${project.version} + test-jar + test + + ${project.groupId} diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileComposition.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileComposition.java new file mode 100644 index 00000000..22efeb4e --- /dev/null +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileComposition.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; + +import org.opendaylight.yang.gen.v1.urn.mef.nrp.bandwidth.profile.rev160630.GNRPBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.EgressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.IngressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.EgressBwpUni; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.IngressBwpUni; + +import java.util.Optional; + +public class BandwidthProfileComposition { + + public enum BwpDirection { + INGRESS, + EGRESS + } + + public enum BwpApplicability { + DEFAULT, + EVC, + UNI + } + + public static BandwidthProfileCompositionBuilder builder() { + return new BandwidthProfileCompositionBuilder(); + } + + private static Optional convert(Optional input) { + if(input.isPresent()) { + return Optional.of(input.get()); + } + + return Optional.empty(); + } + + private Optional ingressBwProfilePerEvc; + + private Optional egressBwProfilePerEvc; + + private Optional ingressBwProfilePerUni; + + private Optional egressBwProfilePerUni; + + private Optional defaultIngressBwProfile; + + private Optional defaultEgressBwProfile; + + private BandwidthProfileComposition(BandwidthProfileCompositionBuilder builder) { + this.ingressBwProfilePerEvc = builder.ingressBwProfilePerEvc; + this.egressBwProfilePerEvc = builder.egressBwProfilePerEvc; + this.ingressBwProfilePerUni = builder.ingressBwProfilePerUni; + this.egressBwProfilePerUni = builder.egressBwProfilePerUni; + this.defaultIngressBwProfile = builder.defaultIngressBwProfile; + this.defaultEgressBwProfile = builder.defaultEgressBwProfile; + } + + public Optional getIngressBwProfilePerEvc() { + return ingressBwProfilePerEvc; + } + + public Optional getEgressBwProfilePerEvc() { + return egressBwProfilePerEvc; + } + + public Optional getIngressBwProfilePerUni() { + return ingressBwProfilePerUni; + } + + public Optional getEgressBwProfilePerUni() { + return egressBwProfilePerUni; + } + + public Optional getDefaultIngressBwProfile() { + return defaultIngressBwProfile; + } + + public Optional getDefaultEgressBwProfile() { + return defaultEgressBwProfile; + } + + public Optional get(BwpDirection direction, BwpApplicability applicability) { + switch(direction) { + case INGRESS: + switch(applicability) { + case DEFAULT: + return convert(defaultIngressBwProfile); + case EVC: + return convert(ingressBwProfilePerEvc); + case UNI: + return convert(ingressBwProfilePerUni); + default: + return Optional.empty(); + } + case EGRESS: + switch(applicability) { + case DEFAULT: + return convert(defaultEgressBwProfile); + case EVC: + return convert(egressBwProfilePerEvc); + case UNI: + return convert(egressBwProfilePerUni); + default: + return Optional.empty(); + } + default: + return Optional.empty(); + } + } + + public boolean hasAnyProfileDefined() { + return ingressBwProfilePerEvc.isPresent() || + egressBwProfilePerEvc.isPresent() || + ingressBwProfilePerUni.isPresent() || + egressBwProfilePerUni.isPresent() || + defaultIngressBwProfile.isPresent() || + defaultEgressBwProfile.isPresent(); + } + + public static class BandwidthProfileCompositionBuilder { + private Optional ingressBwProfilePerEvc; + + private Optional egressBwProfilePerEvc; + + private Optional ingressBwProfilePerUni; + + private Optional egressBwProfilePerUni; + + private Optional defaultIngressBwProfile; + + private Optional defaultEgressBwProfile; + + private BandwidthProfileCompositionBuilder() { + ingressBwProfilePerEvc = Optional.empty(); + egressBwProfilePerEvc = Optional.empty(); + ingressBwProfilePerUni = Optional.empty(); + egressBwProfilePerUni = Optional.empty(); + defaultIngressBwProfile = Optional.empty(); + defaultEgressBwProfile = Optional.empty(); + } + + public BandwidthProfileCompositionBuilder ingressBwProfilePerEvc(Optional ingressBwProfilePerEvc) { + this.ingressBwProfilePerEvc = ingressBwProfilePerEvc; + return this; + } + + public BandwidthProfileCompositionBuilder egressBwProfilePerEvc(Optional egressBwProfilePerEvc) { + this.egressBwProfilePerEvc = egressBwProfilePerEvc; + return this; + } + + public BandwidthProfileCompositionBuilder ingressBwProfilePerUni(Optional ingressBwProfilePerUni) { + this.ingressBwProfilePerUni = ingressBwProfilePerUni; + return this; + } + + public BandwidthProfileCompositionBuilder egressBwProfilePerUni(Optional egressBwProfilePerUni) { + this.egressBwProfilePerUni = egressBwProfilePerUni; + return this; + } + + public BandwidthProfileCompositionBuilder defaultIngressBwProfile(Optional defaultIngressBwProfile) { + this.defaultIngressBwProfile = defaultIngressBwProfile; + return this; + } + + public BandwidthProfileCompositionBuilder defaultEgressBwProfile(Optional defaultEgressBwProfile) { + this.defaultEgressBwProfile = defaultEgressBwProfile; + return this; + } + + public BandwidthProfileComposition build() { + return new BandwidthProfileComposition(this); + } + } +} \ No newline at end of file diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelper.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelper.java new file mode 100644 index 00000000..07e13e12 --- /dev/null +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelper.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.unimgr.utils.MdsalUtils; +import org.opendaylight.unimgr.utils.NullAwareDatastoreGetter; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.PolicyManager; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.PolicyManagerBuilder; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.RateUnits; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.ThresholdUnits; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.manager.PolicyMapsBuilder; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.manager.policy.maps.PolicyMap; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.manager.policy.maps.PolicyMapBuilder; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.map.rule.PolicyMapRule; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.map.rule.PolicyMapRuleBuilder; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.map.rule.policy.map.rule.Police; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.map.rule.policy.map.rule.PoliceBuilder; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.policy.map.rule.policy.map.rule.police.*; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.bandwidth.profile.rev160630.GNRPBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.AdapterSpec1; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.TerminationSpec1; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.TerminationPoint1; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_layerprotocol.LpSpec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION; + + +public class BandwidthProfileHelper { + + private static final Logger LOG = LoggerFactory.getLogger(BandwidthProfileHelper.class); + + private static String SEPARATOR = "_"; + + private static String CLASS_DEFAULT = "class-default"; + + private static class PolicyMapNameGenerator { + + public static String generate(String fcName, BandwidthProfileComposition.BwpDirection direction, BandwidthProfileComposition.BwpApplicability applicability) { + //TODO naming convention + return new StringBuilder() + .append(fcName) + .append(SEPARATOR) + .append(direction.name().toLowerCase()) + .append(SEPARATOR) + .append(applicability.name().toLowerCase()) + .toString(); + } + } + + private static List retrieveBandwidthProfiles(DataBroker dataBroker, FcPort port) { + List bwCompositionList = new ArrayList<>(); + List> lpSpecNadgs = new NullAwareDatastoreGetter<>(MdsalUtils.readTerminationPoint(dataBroker, CONFIGURATION, port)) + .collect(x -> x::getAugmentation, TerminationPoint1.class) + .collect(x -> x::getLtpAttrs) + .collectMany(x -> x::getLpList) + .stream() + .map(nadg -> nadg.collect(x -> x::getLpSpec)) + .collect(Collectors.toList()); + + for(NullAwareDatastoreGetter lpSpecNadg : lpSpecNadgs) { + NullAwareDatastoreGetter adapterSpecNadg = lpSpecNadg + .collect(x -> x::getAdapterSpec) + .collect(x -> x::getAugmentation, AdapterSpec1.class); + + NullAwareDatastoreGetter terminationSpecNadg = lpSpecNadg + .collect(x -> x::getTerminationSpec) + .collect(x -> x::getAugmentation, TerminationSpec1.class); + + bwCompositionList.add( + BandwidthProfileComposition.builder() + .defaultIngressBwProfile(adapterSpecNadg.collect(x -> x::getNrpConnAdaptSpecAttrs).collect(x -> x::getIngressBwpFlow).get()) + .defaultEgressBwProfile(adapterSpecNadg.collect(x -> x::getNrpConnAdaptSpecAttrs).collect(x -> x::getEgressBwpFlow).get()) + .ingressBwProfilePerEvc(adapterSpecNadg.collect(x -> x::getNrpEvcEndpointConnAdaptSpecAttrs).collect(x -> x::getIngressBwpFlow).get()) + .egressBwProfilePerEvc(adapterSpecNadg.collect(x -> x::getNrpEvcEndpointConnAdaptSpecAttrs).collect(x -> x::getEgressBwpFlow).get()) + .ingressBwProfilePerUni(terminationSpecNadg.collect(x -> x::getNrpUniTerminationAttrs).collect(x -> x::getIngressBwpUni).get()) + .egressBwProfilePerUni(terminationSpecNadg.collect(x -> x::getNrpUniTerminationAttrs).collect(x -> x::getEgressBwpUni).get()) + .build() + ); + } + + return bwCompositionList; + } + + private List bandwidthProfiles; + + private List policyMaps; + + public BandwidthProfileHelper(DataBroker dataBroker, FcPort port) { + bandwidthProfiles = BandwidthProfileHelper.retrieveBandwidthProfiles(dataBroker, port); + policyMaps = new ArrayList<>(); + } + + public List getBandwidthProfiles() { + return bandwidthProfiles; + } + + public boolean isQosEnabled() { + for(BandwidthProfileComposition bandwidthProfileComposition : bandwidthProfiles) { + if(bandwidthProfileComposition.hasAnyProfileDefined()) { + return true; + } + } + + return false; + } + + private Police addPolice(GNRPBwpFlow bandwidthProfile) { + Long cir = bandwidthProfile.getCir().getValue(); + Long cbs = bandwidthProfile.getCbs().getValue(); + Long pir = bandwidthProfile.getEir().getValue() + cir; + Long pbs = bandwidthProfile.getEbs().getValue() + cbs; + + return new PoliceBuilder() + // CIR configuration + .setRate(new RateBuilder().setUnits(new RateUnits("bps")).setValue(cir).build()) + + // CBS configuration + .setBurst(new BurstBuilder().setUnits(new ThresholdUnits("bytes")).setValue(cbs).build()) + + // PIR configuration + .setPeakRate(new PeakRateBuilder().setUnits(new RateUnits("bps")).setValue(pir).build()) + + // PBS configuration + .setPeakBurst(new PeakBurstBuilder().setUnits(new ThresholdUnits("bytes")).setValue(pbs).build()) + + // GREEN-marked frames action configuration + .setConformAction(new ConformActionBuilder().setTransmit(true).build()) + + // YELLOW-marked frames action configuration + .setViolateAction(new ViolateActionBuilder().setTransmit(true).build()) + + // RED-marked frames action configuration + .setExceedAction(new ExceedActionBuilder().setDrop(true).build()) + + .build(); + } + + public BandwidthProfileHelper addPolicyMap(String fcName, BandwidthProfileComposition.BwpDirection direction, BandwidthProfileComposition.BwpApplicability applicability) { + if(bandwidthProfiles.size() > 0) { + //TODO .get(0) ? + Optional bwProfileOptional = bandwidthProfiles.get(0).get(direction, applicability); + + if (bwProfileOptional.isPresent()) { + List policyMapRules = new ArrayList<>(); + policyMapRules.add( + new PolicyMapRuleBuilder() + .setClassName(CLASS_DEFAULT) + .setPolice(addPolice(bwProfileOptional.get())) + .build() + ); + + + policyMaps.add(new PolicyMapBuilder() + .setName(PolicyMapNameGenerator.generate(fcName, direction, applicability)) + .setPolicyMapRule(policyMapRules) + .build() + ); + + return this; + } + } + + LOG.warn("Cannot configure policy map - there are no Bandwidth Profiles defined."); + return this; + } + + public Optional build() { + if (policyMaps.size() == 0) { + return Optional.empty(); + } + + return Optional.of(new PolicyManagerBuilder() + .setPolicyMaps(new PolicyMapsBuilder().setPolicyMap(policyMaps).build()) + .build() + ); + } +} \ No newline at end of file diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelper.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelper.java index 9ff582f3..83e4c93b 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelper.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelper.java @@ -7,7 +7,6 @@ */ package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; -import com.google.common.base.Optional; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceActive; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurationsBuilder; @@ -24,6 +23,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import java.util.LinkedList; import java.util.List; +import java.util.Optional; /** * Helper, designated to support interface configuration diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtils.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtils.java index 0bf002fc..6ceea565 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtils.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtils.java @@ -7,40 +7,69 @@ */ package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.util; -import com.google.common.collect.ImmutableMap; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.unimgr.utils.MdsalUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.LoopbackAugmentation; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Map; - /** * Tools designated to support operations on loopback interfaces data * * @author krzysztof.bijakowski@amartus.com + * @author marek.ryznar@amartus.com [modifications] */ public class LoopbackUtils { private static final Logger LOG = LoggerFactory.getLogger(LoopbackUtils.class); private static final String DEFAULT_LOOPBACK = "127.0.0.1"; - private static final Map loopbackMap = ImmutableMap.of( - "asr-101", "192.168.0.1", - "asr-102", "192.168.0.2", - "asr-103", "192.168.0.3" - ); + public static Ipv4AddressNoZone getIpv4Address(FcPort port, DataBroker dataBroker) { + String loopback = null; + NodeId nodeId = port.getNode(); + TopologyId topologyId = port.getTopology(); + Optional nodeOpt = MdsalUtils.readOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, getNodeIid(nodeId,topologyId)); + + if(nodeOpt.isPresent()) { + LoopbackAugmentation la = nodeOpt.get().getAugmentation(LoopbackAugmentation.class); - // TODO: implement real method to find neighbor's loopback - public static Ipv4AddressNoZone getIpv4Address(FcPort port) { - String hostname = port.getNode().getValue(); + if (la != null){ + loopback = la.getLoopbackAddress().getIpv4Address().getValue(); + } + } - String loopback = loopbackMap.get(hostname); if (loopback == null) { - LOG.warn("No loopback address found for {}", hostname); + LOG.warn("No loopback address found for {}", nodeId.getValue()); loopback = DEFAULT_LOOPBACK; } return new Ipv4AddressNoZone(loopback); } + + public static String getDefaultLoopback() { + return DEFAULT_LOOPBACK; + } + + public static InstanceIdentifier getNodeIid(NodeId nodeId, TopologyId topologyId){ + InstanceIdentifier nodeInstanceId = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(topologyId)) + .child(Node.class, new NodeKey(nodeId)) + .build(); + return nodeInstanceId; + } } diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/AbstractL2vpnActivator.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/AbstractL2vpnActivator.java index 2c98e985..e4f10046 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/AbstractL2vpnActivator.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/AbstractL2vpnActivator.java @@ -17,6 +17,7 @@ import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.InterfaceHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.L2vpnHelper; import org.opendaylight.unimgr.mef.nrp.common.MountPointHelper; import org.opendaylight.unimgr.mef.nrp.common.ResourceActivator; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.PolicyManager; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceActive; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations.InterfaceConfiguration; @@ -46,31 +47,41 @@ public abstract class AbstractL2vpnActivator implements ResourceActivator { private static final Logger LOG = LoggerFactory.getLogger(AbstractL2vpnActivator.class); + protected DataBroker dataBroker; + private MountPointService mountService; - protected AbstractL2vpnActivator(MountPointService mountService) { + protected AbstractL2vpnActivator(DataBroker dataBroker, MountPointService mountService) { + this.dataBroker = dataBroker; this.mountService = mountService; } @Override - public void activate(String nodeName, String outerName, String innerName, FcPort port, FcPort neighbor, long mtu) { + public void activate(String nodeName, String outerName, String innerName, FcPort port, FcPort neighbor, long mtu) throws TransactionCommitFailedException { + java.util.Optional qosConfig = activateQos(innerName, port); InterfaceConfigurations interfaceConfigurations = activateInterface(port, neighbor, mtu); Pseudowires pseudowires = activatePseudowire(neighbor); XconnectGroups xconnectGroups = activateXConnect(outerName, innerName, port, neighbor, pseudowires); L2vpn l2vpn = activateL2Vpn(xconnectGroups); - doActivate(nodeName, outerName, innerName, interfaceConfigurations, l2vpn); + doActivate(nodeName, outerName, innerName, interfaceConfigurations, l2vpn, qosConfig); } @Override - public void deactivate(String nodeName, String outerName, String innerName, FcPort port, FcPort neighbor, long mtu) { + public void deactivate(String nodeName, String outerName, String innerName, FcPort port, FcPort neighbor, long mtu) throws TransactionCommitFailedException { InstanceIdentifier xconnectId = deactivateXConnect(outerName, innerName); InstanceIdentifier interfaceConfigurationId = deactivateInterface(port); doDeactivate(nodeName, outerName, innerName, xconnectId, interfaceConfigurationId); } - protected void doActivate(String nodeName, String outerName, String innerName, InterfaceConfigurations interfaceConfigurations, L2vpn l2vpn) { + protected void doActivate(String nodeName, + String outerName, + String innerName, + InterfaceConfigurations interfaceConfigurations, + L2vpn l2vpn, + java.util.Optional qosConfig) throws TransactionCommitFailedException { + Optional optional = MountPointHelper.getDataBroker(mountService, nodeName); if (!optional.isPresent()) { LOG.error("Could not retrieve MountPoint for {}", nodeName); @@ -80,17 +91,15 @@ public abstract class AbstractL2vpnActivator implements ResourceActivator { WriteTransaction transaction = optional.get().newWriteOnlyTransaction(); transaction.merge(LogicalDatastoreType.CONFIGURATION, InterfaceHelper.getInterfaceConfigurationsId(), interfaceConfigurations); transaction.merge(LogicalDatastoreType.CONFIGURATION, L2vpnHelper.getL2vpnId(), l2vpn); - - try { - transaction.submit().checkedGet(); - LOG.info("Service activated: {} {} {}", nodeName, outerName, innerName); - } catch (TransactionCommitFailedException e) { - LOG.error("Transaction failed", e); - } + transaction.submit().checkedGet(); } - protected void doDeactivate(String nodeName, String outerName, String innerName, - InstanceIdentifier xconnectId, InstanceIdentifier interfaceConfigurationId) { + protected void doDeactivate(String nodeName, + String outerName, + String innerName, + InstanceIdentifier xconnectId, + InstanceIdentifier interfaceConfigurationId) throws TransactionCommitFailedException { + Optional optional = MountPointHelper.getDataBroker(mountService, nodeName); if (!optional.isPresent()) { LOG.error("Could not retrieve MountPoint for {}", nodeName); @@ -100,15 +109,11 @@ public abstract class AbstractL2vpnActivator implements ResourceActivator { WriteTransaction transaction = optional.get().newWriteOnlyTransaction(); transaction.delete(LogicalDatastoreType.CONFIGURATION, xconnectId); transaction.delete(LogicalDatastoreType.CONFIGURATION, interfaceConfigurationId); - - try { - transaction.submit().checkedGet(); - LOG.info("Service activated: {} {} {}", nodeName, outerName, innerName); - } catch (TransactionCommitFailedException e) { - LOG.error("Transaction failed", e); - } + transaction.submit().checkedGet(); } + protected abstract java.util.Optional activateQos(String name, FcPort port); + protected abstract InterfaceConfigurations activateInterface(FcPort portA, FcPort portZ, long mtu); protected abstract Pseudowires activatePseudowire(FcPort neighbor); @@ -119,16 +124,16 @@ public abstract class AbstractL2vpnActivator implements ResourceActivator { private InstanceIdentifier deactivateXConnect(String outerName, String innerName) { return InstanceIdentifier.builder(L2vpn.class) - .child(Database.class) - .child(XconnectGroups.class) - .child(XconnectGroup.class, new XconnectGroupKey(new CiscoIosXrString(outerName))) - .child(P2pXconnects.class).child(P2pXconnect.class, new P2pXconnectKey(new CiscoIosXrString(innerName))) - .build(); + .child(Database.class) + .child(XconnectGroups.class) + .child(XconnectGroup.class, new XconnectGroupKey(new CiscoIosXrString(outerName))) + .child(P2pXconnects.class).child(P2pXconnect.class, new P2pXconnectKey(new CiscoIosXrString(innerName))) + .build(); } private InstanceIdentifier deactivateInterface(FcPort port) { return InstanceIdentifier.builder(InterfaceConfigurations.class) - .child(InterfaceConfiguration.class, new InterfaceConfigurationKey(new InterfaceActive("act"), InterfaceHelper.getInterfaceName(port))) - .build(); + .child(InterfaceConfiguration.class, new InterfaceConfigurationKey(new InterfaceActive("act"), InterfaceHelper.getInterfaceName(port))) + .build(); } } \ No newline at end of file diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivator.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivator.java index a9c69319..88343a9d 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivator.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivator.java @@ -8,14 +8,15 @@ package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator; -import com.google.common.base.Optional; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.InterfaceHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.AttachmentCircuitHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.L2vpnHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.PseudowireHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.XConnectHelper; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.PolicyManager; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cfg.rev151109.L2vpn; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cfg.rev151109.l2vpn.database.XconnectGroups; @@ -24,6 +25,12 @@ import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cf import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cfg.rev151109.l2vpn.database.xconnect.groups.xconnect.group.p2p.xconnects.p2p.xconnect.Pseudowires; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import java.util.Optional; + +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpApplicability.UNI; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.EGRESS; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.INGRESS; + /** * Activator of VPLS-based L2 VPN using bridge connection on IOS-XR devices * @@ -32,14 +39,22 @@ import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forw public class L2vpnBridgeActivator extends AbstractL2vpnActivator { public L2vpnBridgeActivator(DataBroker dataBroker, MountPointService mountService) { - super(mountService); + super(dataBroker, mountService); + } + + @Override + protected Optional activateQos(String name, FcPort port) { + return new BandwidthProfileHelper(dataBroker, port) + .addPolicyMap(name, INGRESS, UNI) + .addPolicyMap(name, EGRESS, UNI) + .build(); } @Override protected InterfaceConfigurations activateInterface(FcPort port, FcPort neighbor, long mtu) { return new InterfaceHelper() - .addInterface(port, Optional.absent(), true) - .addInterface(neighbor, Optional.absent(), true) + .addInterface(port, Optional.empty(), true) + .addInterface(neighbor, Optional.empty(), true) .build(); } diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivator.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivator.java index 0d1a3770..40eb4a15 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivator.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivator.java @@ -7,9 +7,9 @@ */ package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator; -import com.google.common.base.Optional; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.InterfaceHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.util.LoopbackUtils; import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.util.MtuUtils; @@ -17,6 +17,7 @@ import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.AttachmentCircuitHe import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.L2vpnHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.PseudowireHelper; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.helper.XConnectHelper; +import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.asr9k.policymgr.cfg.rev150518.PolicyManager; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations._interface.configuration.Mtus; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cfg.rev151109.L2vpn; @@ -27,6 +28,13 @@ import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.l2vpn.cf import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.xr.types.rev150629.CiscoIosXrString; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import java.util.Optional; + +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpApplicability.UNI; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.EGRESS; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.INGRESS; + + /** * Activator of VPLS-based L2 VPN using cross connect connection on IOS-XR devices * @@ -35,12 +43,20 @@ import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forw public class L2vpnXconnectActivator extends AbstractL2vpnActivator { public L2vpnXconnectActivator(DataBroker dataBroker, MountPointService mountService) { - super(mountService); + super(dataBroker, mountService); + } + + @Override + protected Optional activateQos(String name, FcPort port) { + return new BandwidthProfileHelper(dataBroker, port) + .addPolicyMap(name, INGRESS, UNI) + .addPolicyMap(name, EGRESS, UNI) + .build(); } @Override public InterfaceConfigurations activateInterface(FcPort port, FcPort neighbor, long mtu) { - Mtus mtus = new MtuUtils().generateMtus(mtu, new CiscoIosXrString("GigabitEthernet")); //TODO remove hardcoded value + Mtus mtus = new MtuUtils().generateMtus(mtu, new CiscoIosXrString("GigabitEthernet")); return new InterfaceHelper() .addInterface(port, Optional.of(mtus), true) @@ -50,7 +66,7 @@ public class L2vpnXconnectActivator extends AbstractL2vpnActivator { @Override public Pseudowires activatePseudowire(FcPort neighbor) { return new PseudowireHelper() - .addPseudowire(LoopbackUtils.getIpv4Address(neighbor)) + .addPseudowire(LoopbackUtils.getIpv4Address(neighbor, dataBroker)) .build(); } diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilder.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilder.java index 7bc05e94..75104d75 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilder.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilder.java @@ -8,27 +8,35 @@ package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.driver; -import java.util.Optional; - import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver; import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder; +import org.opendaylight.unimgr.utils.CapabilitiesService; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator.L2vpnBridgeActivator; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import java.util.Optional; + +import static org.opendaylight.unimgr.utils.CapabilitiesService.Capability.Mode.AND; +import static org.opendaylight.unimgr.utils.CapabilitiesService.NodeContext.NodeCapability.*; + /** * Provides drivers for binding two ports on the same node. * @author bartosz.michalik@amartus.com */ public class L2vpnBridgeDriverBuilder implements ActivationDriverBuilder { + private final DataBroker dataBroker; + private L2vpnBridgeActivator activator; private static final String GROUP_NAME = "local"; public L2vpnBridgeDriverBuilder(DataBroker dataBroker, MountPointService mountPointService) { + this.dataBroker = dataBroker; activator = new L2vpnBridgeActivator(dataBroker, mountPointService); } @@ -39,7 +47,14 @@ public class L2vpnBridgeDriverBuilder implements ActivationDriverBuilder { @Override public Optional driverFor(FcPort aPort, FcPort zPort, BuilderContext context) { - return Optional.of(getDriver()); + CapabilitiesService capabilitiesService = new CapabilitiesService(dataBroker); + + if (capabilitiesService.nodeByPort(aPort).isSupporting(AND, NETCONF, NETCONF_CISCO_IOX_IFMGR, NETCONF_CISCO_IOX_L2VPN) && + capabilitiesService.nodeByPort(zPort).isSupporting(AND, NETCONF, NETCONF_CISCO_IOX_IFMGR, NETCONF_CISCO_IOX_L2VPN)) { + return Optional.of(getDriver()); + } + + return Optional.empty(); } protected ActivationDriver getDriver() { @@ -64,7 +79,7 @@ public class L2vpnBridgeDriverBuilder implements ActivationDriverBuilder { } @Override - public void activate() { + public void activate() throws TransactionCommitFailedException { long mtu = 1500; String aEndNodeName = aEnd.getNode().getValue(); @@ -72,7 +87,7 @@ public class L2vpnBridgeDriverBuilder implements ActivationDriverBuilder { } @Override - public void deactivate() { + public void deactivate() throws TransactionCommitFailedException { long mtu = 1500; String aEndNodeName = aEnd.getNode().getValue(); diff --git a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilder.java b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilder.java index ba15346f..bc1c2ae9 100644 --- a/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilder.java +++ b/cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilder.java @@ -8,34 +8,49 @@ package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.driver; -import java.util.Optional; - import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.MountPointService; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver; import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder; +import org.opendaylight.unimgr.utils.CapabilitiesService; import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator.L2vpnXconnectActivator; import org.opendaylight.unimgr.mef.nrp.common.FixedServiceNaming; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import java.util.Optional; + +import static org.opendaylight.unimgr.utils.CapabilitiesService.NodeContext.NodeCapability.NETCONF; +import static org.opendaylight.unimgr.utils.CapabilitiesService.Capability.Mode.AND; +import static org.opendaylight.unimgr.utils.CapabilitiesService.NodeContext.NodeCapability.NETCONF_CISCO_IOX_IFMGR; +import static org.opendaylight.unimgr.utils.CapabilitiesService.NodeContext.NodeCapability.NETCONF_CISCO_IOX_L2VPN; + /** - * Xconnect builder (FIXME no decision logic yet) + * Xconnect builder * @author bartosz.michalik@amartus.com */ public class L2vpnXconnectDriverBuilder implements ActivationDriverBuilder { + private final DataBroker dataBroker; + private final FixedServiceNaming namingProvider; + private L2vpnXconnectActivator xconnectActivator; public L2vpnXconnectDriverBuilder(DataBroker dataBroker, MountPointService mountPointService) { + this.dataBroker = dataBroker; xconnectActivator = new L2vpnXconnectActivator(dataBroker, mountPointService); namingProvider = new FixedServiceNaming(); } @Override - public Optional driverFor(FcPort port,BuilderContext _ctx) { - return Optional.of(getDriver()); + public Optional driverFor(FcPort port, BuilderContext _ctx) { + if (new CapabilitiesService(dataBroker).nodeByPort(port).isSupporting(AND, NETCONF, NETCONF_CISCO_IOX_IFMGR, NETCONF_CISCO_IOX_L2VPN)) { + return Optional.of(getDriver()); + } + + return Optional.empty(); } @Override @@ -67,7 +82,7 @@ public class L2vpnXconnectDriverBuilder implements ActivationDriverBuilder { } @Override - public void activate() { + public void activate() throws TransactionCommitFailedException { String id = ctx.getUuid(); long mtu = 1500; String outerName = namingProvider.getOuterName(id); @@ -79,7 +94,7 @@ public class L2vpnXconnectDriverBuilder implements ActivationDriverBuilder { } @Override - public void deactivate() { + public void deactivate() throws TransactionCommitFailedException { String id = ctx.getUuid(); long mtu = 1500; String outerName = namingProvider.getOuterName(id); diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileCompositionTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileCompositionTest.java new file mode 100644 index 00000000..c31c271d --- /dev/null +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileCompositionTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.bandwidth.profile.rev160630.GNRPBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.EgressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.IngressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.EgressBwpUni; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.IngressBwpUni; + +import java.util.Optional; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpApplicability.*; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.EGRESS; +import static org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper.BandwidthProfileComposition.BwpDirection.INGRESS; + +public class BandwidthProfileCompositionTest { + + private IngressBwpFlow defaultIngressBwProfileMock; + + private EgressBwpFlow defaultEgressBwProfileMock; + + private IngressBwpFlow ingressBwProfilePerEvcMock; + + private EgressBwpFlow egressBwProfilePerEvcMock; + + private IngressBwpUni ingressBwProfilePerUniMock; + + private EgressBwpUni egressBwProfilePerUniMock; + + @Before + public void setup() { + defaultIngressBwProfileMock = mock(IngressBwpFlow.class); + defaultEgressBwProfileMock = mock(EgressBwpFlow.class); + ingressBwProfilePerEvcMock = mock(IngressBwpFlow.class); + egressBwProfilePerEvcMock = mock(EgressBwpFlow.class); + ingressBwProfilePerUniMock = mock(IngressBwpUni.class); + egressBwProfilePerUniMock = mock(EgressBwpUni.class); + } + + @Test + public void testBuilder() { + //given + BandwidthProfileComposition.BandwidthProfileCompositionBuilder compositionBuilder = builderWithAllProfiles(); + + //when + BandwidthProfileComposition composition = compositionBuilder.build(); + + //then + assertTrue(composition.getDefaultIngressBwProfile().isPresent()); + assertTrue(composition.getDefaultEgressBwProfile().isPresent()); + assertTrue(composition.getIngressBwProfilePerEvc().isPresent()); + assertTrue(composition.getEgressBwProfilePerEvc().isPresent()); + assertTrue(composition.getIngressBwProfilePerUni().isPresent()); + assertTrue(composition.getEgressBwProfilePerUni().isPresent()); + + assertEquals(defaultIngressBwProfileMock, composition.getDefaultIngressBwProfile().get()); + assertEquals(defaultEgressBwProfileMock, composition.getDefaultEgressBwProfile().get()); + assertEquals(ingressBwProfilePerEvcMock, composition.getIngressBwProfilePerEvc().get()); + assertEquals(egressBwProfilePerEvcMock, composition.getEgressBwProfilePerEvc().get()); + assertEquals(ingressBwProfilePerUniMock, composition.getIngressBwProfilePerUni().get()); + assertEquals(egressBwProfilePerUniMock, composition.getEgressBwProfilePerUni().get()); + } + + @Test + public void testBuilderEmpty() { + //given + BandwidthProfileComposition.BandwidthProfileCompositionBuilder compositionBuilder = BandwidthProfileComposition.builder(); + + //when + BandwidthProfileComposition composition = compositionBuilder.build(); + + //then + assertNotNull(composition.getDefaultIngressBwProfile()); + assertNotNull(composition.getDefaultEgressBwProfile()); + assertNotNull(composition.getIngressBwProfilePerEvc()); + assertNotNull(composition.getEgressBwProfilePerEvc()); + assertNotNull(composition.getIngressBwProfilePerUni()); + assertNotNull(composition.getEgressBwProfilePerUni()); + + assertFalse(composition.getDefaultIngressBwProfile().isPresent()); + assertFalse(composition.getDefaultEgressBwProfile().isPresent()); + assertFalse(composition.getIngressBwProfilePerEvc().isPresent()); + assertFalse(composition.getEgressBwProfilePerEvc().isPresent()); + assertFalse(composition.getIngressBwProfilePerUni().isPresent()); + assertFalse(composition.getEgressBwProfilePerUni().isPresent()); + } + + @Test + public void testGet() { + //given + BandwidthProfileComposition composition = builderWithAllProfiles().build(); + + //when + Optional actualIngerssDefaultOptional = composition.get(INGRESS, DEFAULT); + Optional actualIngressEvcOptional = composition.get(INGRESS, EVC); + Optional actualIngerssUniOptional = composition.get(INGRESS, UNI); + Optional actualEgerssDefaultOptional = composition.get(EGRESS, DEFAULT); + Optional actualEgerssEvcOptional = composition.get(EGRESS, EVC); + Optional actualEgerssUniOptional = composition.get(EGRESS, UNI); + + //then + assertTrue(actualIngerssDefaultOptional.isPresent()); + assertTrue(actualIngressEvcOptional.isPresent()); + assertTrue(actualIngerssUniOptional.isPresent()); + assertTrue(actualEgerssDefaultOptional.isPresent()); + assertTrue(actualEgerssEvcOptional.isPresent()); + assertTrue(actualEgerssUniOptional.isPresent()); + + assertEquals(defaultIngressBwProfileMock, actualIngerssDefaultOptional.get()); + assertEquals(defaultEgressBwProfileMock, actualEgerssDefaultOptional.get()); + assertEquals(ingressBwProfilePerEvcMock, actualIngressEvcOptional.get()); + assertEquals(egressBwProfilePerEvcMock, actualEgerssEvcOptional.get()); + assertEquals(ingressBwProfilePerUniMock, actualIngerssUniOptional.get()); + assertEquals(egressBwProfilePerUniMock, actualEgerssUniOptional.get()); + } + + @Test + public void testHasAnyProfileDefinedPositive() { + //given + BandwidthProfileComposition composition = builderWithOneProfile().build(); + + //when + boolean actual = composition.hasAnyProfileDefined(); + + //then + assertTrue(actual); + } + + @Test + public void testHasAnyProfileDefinedNegative() { + //given + BandwidthProfileComposition composition = builderWithNoProfile().build(); + + //when + boolean actual = composition.hasAnyProfileDefined(); + + //then + assertFalse(actual); + } + + private BandwidthProfileComposition.BandwidthProfileCompositionBuilder builderWithAllProfiles() { + return BandwidthProfileComposition.builder() + .defaultIngressBwProfile(Optional.of(defaultIngressBwProfileMock)) + .defaultEgressBwProfile(Optional.of(defaultEgressBwProfileMock)) + .ingressBwProfilePerEvc(Optional.of(ingressBwProfilePerEvcMock)) + .egressBwProfilePerEvc(Optional.of(egressBwProfilePerEvcMock)) + .ingressBwProfilePerUni(Optional.of(ingressBwProfilePerUniMock)) + .egressBwProfilePerUni(Optional.of(egressBwProfilePerUniMock)); + } + + private BandwidthProfileComposition.BandwidthProfileCompositionBuilder builderWithOneProfile() { + return BandwidthProfileComposition.builder() + .defaultIngressBwProfile(Optional.empty()) + .defaultEgressBwProfile(Optional.empty()) + .ingressBwProfilePerEvc(Optional.empty()) + .egressBwProfilePerEvc(Optional.of(egressBwProfilePerEvcMock)) + .ingressBwProfilePerUni(Optional.empty()) + .egressBwProfilePerUni(Optional.empty()); + } + + private BandwidthProfileComposition.BandwidthProfileCompositionBuilder builderWithNoProfile() { + return BandwidthProfileComposition.builder() + .defaultIngressBwProfile(Optional.empty()) + .defaultEgressBwProfile(Optional.empty()) + .ingressBwProfilePerEvc(Optional.empty()) + .egressBwProfilePerEvc(Optional.empty()) + .ingressBwProfilePerUni(Optional.empty()) + .egressBwProfilePerUni(Optional.empty()); + } +} diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelperTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelperTest.java new file mode 100644 index 00000000..a98b606c --- /dev/null +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelperTest.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.unimgr.utils.MdsalUtils; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.AdapterSpec1; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.TerminationSpec1; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.EgressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_connadaptspec.IngressBwpFlow; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.EgressBwpUni; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.g_nrp_uni_terminationspec.IngressBwpUni; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.network.topology.topology.node.termination.point.ltp.attrs.lplist.lpspec.adapterspec.NrpConnAdaptSpecAttrs; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.network.topology.topology.node.termination.point.ltp.attrs.lplist.lpspec.adapterspec.NrpEvcEndpointConnAdaptSpecAttrs; +import org.opendaylight.yang.gen.v1.urn.mef.nrp.specs.rev160630.network.topology.topology.node.termination.point.ltp.attrs.lplist.lpspec.terminationspec.NrpUniTerminationAttrs; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.TerminationPoint1; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_layerprotocol.LpSpec; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_logicalterminationpoint.LpList; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.network.topology.topology.node.termination.point.LtpAttrs; +import org.opendaylight.yang.gen.v1.urn.onf.core.specs.rev160630.g_layerprotocolspec.AdapterSpec; +import org.opendaylight.yang.gen.v1.urn.onf.core.specs.rev160630.g_layerprotocolspec.TerminationSpec; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType.CONFIGURATION; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(MdsalUtils.class) +public class BandwidthProfileHelperTest { + + @Test + public void testRetrieveBandwidthProfiles() { + //given + FcPort fcPort = mock(FcPort.class); + + IngressBwpFlow expectedIngressDefaultBwp = mock(IngressBwpFlow.class); + EgressBwpFlow expectedEgressDefaultBwp = mock(EgressBwpFlow.class); + IngressBwpFlow expectedIngressEvcBwp = mock(IngressBwpFlow.class); + EgressBwpFlow expectedEgressEvcBwp = mock(EgressBwpFlow.class); + IngressBwpUni expectedIngressUniBwp = null; + EgressBwpUni expectedEgressUniBwp = null; + + DataBroker dataBroker = mockDatastore(fcPort, + Optional.ofNullable(expectedIngressDefaultBwp), + Optional.ofNullable(expectedEgressDefaultBwp), + Optional.ofNullable(expectedIngressEvcBwp), + Optional.ofNullable(expectedEgressEvcBwp), + Optional.ofNullable(expectedIngressUniBwp), + Optional.ofNullable(expectedEgressUniBwp)); + + //when + List actual = new BandwidthProfileHelper(dataBroker, fcPort).getBandwidthProfiles(); + + //then + assertNotNull(actual); + assertEquals(1, actual.size()); + + BandwidthProfileComposition actualBpc = actual.get(0); + assertTrue(actualBpc.hasAnyProfileDefined()); + + assertTrue(actualBpc.getDefaultIngressBwProfile().isPresent()); + assertEquals(expectedIngressDefaultBwp, actualBpc.getDefaultIngressBwProfile().get()); + + assertTrue(actualBpc.getDefaultEgressBwProfile().isPresent()); + assertEquals(expectedEgressDefaultBwp, actualBpc.getDefaultEgressBwProfile().get()); + + assertTrue(actualBpc.getIngressBwProfilePerEvc().isPresent()); + assertEquals(expectedIngressEvcBwp, actualBpc.getIngressBwProfilePerEvc().get()); + + assertTrue(actualBpc.getEgressBwProfilePerEvc().isPresent()); + assertEquals(expectedEgressEvcBwp, actualBpc.getEgressBwProfilePerEvc().get()); + + assertFalse(actualBpc.getIngressBwProfilePerUni().isPresent()); + assertFalse(actualBpc.getEgressBwProfilePerUni().isPresent()); + } + + @Test + public void testRetrieveBandwidthProfilesNoQos() { + //given + FcPort fcPort = mock(FcPort.class); + + DataBroker dataBroker = mockDatastore(fcPort, + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty(), + Optional.empty()); + + //when + List actual = new BandwidthProfileHelper(dataBroker, fcPort).getBandwidthProfiles(); + + //then + assertNotNull(actual); + assertEquals(1, actual.size()); + + BandwidthProfileComposition actualBpc = actual.get(0); + assertFalse(actualBpc.hasAnyProfileDefined()); + assertFalse(actualBpc.getDefaultIngressBwProfile().isPresent()); + assertFalse(actualBpc.getDefaultEgressBwProfile().isPresent()); + assertFalse(actualBpc.getIngressBwProfilePerEvc().isPresent()); + assertFalse(actualBpc.getEgressBwProfilePerEvc().isPresent()); + assertFalse(actualBpc.getIngressBwProfilePerUni().isPresent()); + assertFalse(actualBpc.getEgressBwProfilePerUni().isPresent()); + } + + @Test + public void testRetrieveBandwidthProfilesEmpty() { + //given + FcPort fcPort = mock(FcPort.class); + + DataBroker dataBroker = mockDatastoreEmpty(fcPort); + + //when + List actual = new BandwidthProfileHelper(dataBroker, fcPort).getBandwidthProfiles(); + + //then + assertNotNull(actual); + assertEquals(0, actual.size()); + } + + private DataBroker mockDatastore(FcPort fcPort, + Optional ingressDefaultBwp, + Optional egressDefaultBwp, + Optional ingressEvcBwp, + Optional egressEvcBwp, + Optional ingressUniBwp, + Optional egressUniBwp) { + DataBroker dataBroker = mock(DataBroker.class); + + TerminationPoint tp = mock(TerminationPoint.class); + TerminationPoint1 tp1 = mock(TerminationPoint1.class); + LtpAttrs ltpAttrs = mock(LtpAttrs.class); + LpList lpList = mock(LpList.class); + LpSpec lpSpec = mock(LpSpec.class); + List lpLists = new ArrayList<>(); + lpLists.add(lpList); + + when(tp.getAugmentation(TerminationPoint1.class)).thenReturn(tp1); + when(tp1.getLtpAttrs()).thenReturn(ltpAttrs); + when(ltpAttrs.getLpList()).thenReturn(lpLists); + when(lpList.getLpSpec()).thenReturn(lpSpec); + + AdapterSpec adapterSpec = mock(AdapterSpec.class); + AdapterSpec1 adapterSpec1 = mock(AdapterSpec1.class); + NrpEvcEndpointConnAdaptSpecAttrs evcAttrs = mock(NrpEvcEndpointConnAdaptSpecAttrs.class); + NrpConnAdaptSpecAttrs connAdaptSpecAttrs = mock(NrpConnAdaptSpecAttrs.class); + + when(lpSpec.getAdapterSpec()).thenReturn(adapterSpec); + when(adapterSpec.getAugmentation(AdapterSpec1.class)).thenReturn(adapterSpec1); + when(adapterSpec1.getNrpConnAdaptSpecAttrs()).thenReturn(connAdaptSpecAttrs); + when(adapterSpec1.getNrpEvcEndpointConnAdaptSpecAttrs()).thenReturn(evcAttrs); + + if(ingressDefaultBwp.isPresent()) { + when(connAdaptSpecAttrs.getIngressBwpFlow()).thenReturn(ingressDefaultBwp.get()); + } + + if(egressDefaultBwp.isPresent()) { + when(connAdaptSpecAttrs.getEgressBwpFlow()).thenReturn(egressDefaultBwp.get()); + } + + if(ingressEvcBwp.isPresent()) { + when(evcAttrs.getIngressBwpFlow()).thenReturn(ingressEvcBwp.get()); + } + + if(egressEvcBwp.isPresent()) { + when(evcAttrs.getEgressBwpFlow()).thenReturn(egressEvcBwp.get()); + } + + TerminationSpec terminationSpec = mock(TerminationSpec.class); + TerminationSpec1 terminationSpec1 = mock(TerminationSpec1.class); + NrpUniTerminationAttrs nrpUniTerminationAttrs = mock(NrpUniTerminationAttrs.class); + + when(lpSpec.getTerminationSpec()).thenReturn(terminationSpec); + when(terminationSpec.getAugmentation(TerminationSpec1.class)).thenReturn(terminationSpec1); + when(terminationSpec1.getNrpUniTerminationAttrs()).thenReturn(nrpUniTerminationAttrs); + + if(ingressUniBwp.isPresent()) { + when(nrpUniTerminationAttrs.getIngressBwpUni()).thenReturn(ingressUniBwp.get()); + } + + if(egressUniBwp.isPresent()) { + when(nrpUniTerminationAttrs.getEgressBwpUni()).thenReturn(egressUniBwp.get()); + } + + PowerMockito.mockStatic(MdsalUtils.class); + when(MdsalUtils.readTerminationPoint(eq(dataBroker), eq(CONFIGURATION), eq(fcPort))).thenReturn(com.google.common.base.Optional.of(tp)); + + return dataBroker; + } + + private DataBroker mockDatastoreEmpty(FcPort fcPort) { + DataBroker dataBroker = mock(DataBroker.class); + + PowerMockito.mockStatic(MdsalUtils.class); + when(MdsalUtils.readTerminationPoint(eq(dataBroker), eq(CONFIGURATION), eq(fcPort))).thenReturn(com.google.common.base.Optional.absent()); + + return dataBroker; + } +} diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelperTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelperTest.java index e921bc05..11824394 100644 --- a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelperTest.java +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelperTest.java @@ -7,7 +7,7 @@ */ package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.helper; -import com.google.common.base.Optional; +import java.util.Optional; import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.unimgr.mef.nrp.cisco.xr.common.util.MtuUtils; @@ -75,7 +75,7 @@ public class InterfaceHelperTest { //given String interfaceNameValue = "GigabitEthernet0/0/1"; InterfaceName interfaceName = new InterfaceName(interfaceNameValue); - Optional mtus = Optional.absent(); + Optional mtus = Optional.empty(); boolean setL2Transport = false; InterfaceHelper interfaceHelper = new InterfaceHelper(); @@ -150,7 +150,7 @@ public class InterfaceHelperTest { InterfaceName interfaceName1 = new InterfaceName(interfaceNameValue1); String interfaceNameValue2 = "GigabitEthernet0/0/2"; InterfaceName interfaceName2 = new InterfaceName(interfaceNameValue2); - Optional mtus = Optional.absent(); + Optional mtus = Optional.empty(); boolean setL2Transport = false; InterfaceHelper interfaceHelper = new InterfaceHelper(); diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtilsTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtilsTest.java new file mode 100644 index 00000000..09f6bcd7 --- /dev/null +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtilsTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.common.util; + +import com.google.common.util.concurrent.CheckedFuture; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator.L2vpnActivatorTestUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.LoopbackAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.LoopbackAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.junit.Assert.assertEquals; + +/** + * @author marek.ryznar@amartus.com + */ +public class LoopbackUtilsTest extends AbstractDataBrokerTest { + private static final Logger LOG = LoggerFactory.getLogger(LoopbackUtilsTest.class); + private DataBroker broker; + private static String nodeName = "192.168.2.1"; + private static String topoName = "topo://"; + private static String loopbackAddress = "192.168.2.20"; + private static String portNumber = "8080"; + + @Before + public void setUp(){ + broker = getDataBroker(); + } + + @After + public void clean(){ + deleteNode(LoopbackUtils.getNodeIid(new NodeId(nodeName),new TopologyId(topoName))); + } + + @Test + public void testLoopbackAddress(){ + //given + FcPort port = L2vpnActivatorTestUtils.port(topoName, nodeName, portNumber); + createAndPersistNode(true); + + //when + Ipv4AddressNoZone ipv4AddressNoZone = LoopbackUtils.getIpv4Address(port, broker); + + //then + assertEquals(loopbackAddress,ipv4AddressNoZone.getValue()); + } + + @Test + public void testAbsenceOfLoopbackAddress(){ + //given + FcPort port = L2vpnActivatorTestUtils.port(topoName, nodeName, portNumber); + createAndPersistNode(false); + + //when + Ipv4AddressNoZone ipv4AddressNoZone = LoopbackUtils.getIpv4Address(port, broker); + + //then + assertEquals(LoopbackUtils.getDefaultLoopback(),ipv4AddressNoZone.getValue()); + } + + private void createAndPersistNode(boolean ifLoopbackAddress){ + NodeId nodeId = new NodeId(nodeName); + Node node = createNode(nodeId,ifLoopbackAddress); + InstanceIdentifier nodeIid = writeNode(node); + } + + private Node createNode(NodeId nodeId,boolean ifLoopbackAddress){ + NodeBuilder nodeBuilder = new NodeBuilder(); + + NodeId nodeIdTopo = new NodeId(topoName); + NodeKey nodeKey = new NodeKey(nodeIdTopo); + + nodeBuilder.setNodeId(nodeId); + + if(ifLoopbackAddress){ + Ipv4Address ipv4Address = new Ipv4Address(loopbackAddress); + IpAddress ipAddress = new IpAddress(ipv4Address); + LoopbackAugmentationBuilder loopbackAugmentationBuilder = new LoopbackAugmentationBuilder(); + loopbackAugmentationBuilder.setLoopbackAddress(ipAddress); + nodeBuilder.addAugmentation(LoopbackAugmentation.class,loopbackAugmentationBuilder.build()); + } + + return nodeBuilder.build(); + } + + private InstanceIdentifier writeNode(Node node){ + InstanceIdentifier nodeInstanceId = LoopbackUtils.getNodeIid(node.getNodeId(),new TopologyId(topoName)); + WriteTransaction transaction = broker.newWriteOnlyTransaction(); + + transaction.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, node,true); + try { + CheckedFuture future = transaction.submit(); + future.checkedGet(); + return nodeInstanceId; + } catch (TransactionCommitFailedException e) { + LOG.error("Unable to write node with Iid {} to store {}.", nodeInstanceId, LogicalDatastoreType.CONFIGURATION); + e.printStackTrace(); + } + return null; + } + + private void deleteNode(InstanceIdentifier nodeIid){ + WriteTransaction transaction = broker.newWriteOnlyTransaction(); + transaction.delete(LogicalDatastoreType.CONFIGURATION, nodeIid); + try { + transaction.submit().checkedGet(); + } catch (TransactionCommitFailedException e) { + LOG.error("Unable to remove node with Iid {} from store {}.", nodeIid, LogicalDatastoreType.CONFIGURATION); + } + } +} diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnActivatorTestUtils.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnActivatorTestUtils.java index 1f0118b1..ba92712e 100644 --- a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnActivatorTestUtils.java +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnActivatorTestUtils.java @@ -37,6 +37,7 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.util.List; import java.util.concurrent.ExecutionException; import static org.junit.Assert.*; @@ -46,8 +47,6 @@ import static org.junit.Assert.*; * * @author marek.ryznar@amartus.com */ -@RunWith(PowerMockRunner.class) -@PrepareForTest(MountPointHelper.class) public class L2vpnActivatorTestUtils { public static MountPointService getMockedMountPointService(Optional optBroker){ @@ -85,22 +84,22 @@ public class L2vpnActivatorTestUtils { public static void checkPseudowire(Pseudowire pseudowire){ assertNotNull(pseudowire); - assertNotNull(pseudowire.getPseudowireId()); //getPseudowireId=PseudowireIdRange [_value=2000] (hardcoded value) + assertNotNull(pseudowire.getPseudowireId()); assertNotNull(pseudowire.getNeighbor()); assertNotNull(pseudowire.getNeighbor().get(0)); } public static void checkNeighbor(Neighbor neighbor){ assertNotNull(neighbor); - assertNotNull(neighbor.getXmlClass()); //getXmlClass=CiscoIosXrString [_value=static], (hardcoded value) - assertNotNull(neighbor.getNeighbor()); //getNeighbor=Ipv4Address [_value=127.0.0.1], (hardcoded value) + assertNotNull(neighbor.getXmlClass()); + assertNotNull(neighbor.getNeighbor()); assertNotNull(neighbor.getMplsStaticLabels()); } public static void checkMplsStaticLabels(MplsStaticLabels mplsStaticLabels){ assertNotNull(mplsStaticLabels); - assertNotNull(mplsStaticLabels.getLocalStaticLabel()); //getLocalStaticLabel=PseudowireLabelRange [_value=2000] (hardcoded value) - assertNotNull(mplsStaticLabels.getRemoteStaticLabel()); //getRemoteStaticLabel=PseudowireLabelRange [_value=2000], (hardcoded value) + assertNotNull(mplsStaticLabels.getLocalStaticLabel()); + assertNotNull(mplsStaticLabels.getRemoteStaticLabel()); } public static void checkInterfaceConfigurations(InterfaceConfigurations interfaceConfigurations){ @@ -110,8 +109,8 @@ public class L2vpnActivatorTestUtils { public static void checkInterfaceConfiguration(InterfaceConfiguration interfaceConfiguration, String portNo, boolean mtu){ assertNotNull(interfaceConfiguration); - assertNotNull(interfaceConfiguration.getActive()); //getActive=InterfaceActive [_value=act], (hardcoded value) - assertNotNull(interfaceConfiguration.getInterfaceModeNonPhysical()); //getInterfaceModeNonPhysical=Default (hardcoded value) + assertNotNull(interfaceConfiguration.getActive()); + assertNotNull(interfaceConfiguration.getInterfaceModeNonPhysical()); assertEquals(portNo,interfaceConfiguration.getInterfaceName().getValue()); assertTrue(interfaceConfiguration.isShutdown()); if(mtu){ @@ -122,31 +121,56 @@ public class L2vpnActivatorTestUtils { public static void checkMtu(Mtu mtu, Long mtuValue){ assertEquals(mtuValue,mtu.getMtu()); - assertNotNull(mtu.getOwner()); //getOwner=CiscoIosXrString [_value=GigabitEthernet], (hardcoded value) + assertNotNull(mtu.getOwner()); } - public static void checkDeactivation(Optional optBroker){ + public static FcPort port(String topo, String host, String port) { + return new FcPortBuilder() + .setTopology(new TopologyId(topo)) + .setNode(new NodeId(host)) + .setTp(new TpId(port)) + .build(); + } + + public static void checkDeactivated(Optional optBroker, String deactivatedPort) { ReadOnlyTransaction transaction = optBroker.get().newReadOnlyTransaction(); - InstanceIdentifier l2vpn = InstanceIdentifier.builder(L2vpn.class).build(); - InstanceIdentifier interfaceConfigurations = InstanceIdentifier.builder(InterfaceConfigurations.class).build(); + InstanceIdentifier l2vpnIid = InstanceIdentifier.builder(L2vpn.class).build(); + InstanceIdentifier interfaceConfigurationsIid = InstanceIdentifier.builder(InterfaceConfigurations.class).build(); - CheckedFuture, ReadFailedException> driverL2vpn = transaction.read(LogicalDatastoreType.CONFIGURATION, l2vpn); - CheckedFuture, ReadFailedException> driverInterfaceConfigurations = transaction.read(LogicalDatastoreType.CONFIGURATION, interfaceConfigurations); + CheckedFuture, ReadFailedException> driverL2vpn = transaction.read(LogicalDatastoreType.CONFIGURATION, l2vpnIid); + CheckedFuture, ReadFailedException> driverInterfaceConfigurations = transaction.read(LogicalDatastoreType.CONFIGURATION, interfaceConfigurationsIid); try { - assertFalse(driverL2vpn.get().isPresent()); - assertFalse(driverInterfaceConfigurations.get().isPresent()); - } catch (InterruptedException | ExecutionException e) { + checkL2vpnDeactivation(driverL2vpn); + checkInterfaceConfigurationDeactivation(driverInterfaceConfigurations,deactivatedPort); + } catch (Exception e) { fail(e.getMessage()); } + } - public static FcPort port(String topo, String host, String port) { - return new FcPortBuilder() - .setTopology(new TopologyId(topo)) - .setNode(new NodeId(host)) - .setTp(new TpId(port)) - .build(); + private static void checkL2vpnDeactivation(CheckedFuture, ReadFailedException>driverL2vpn) throws ExecutionException, InterruptedException { + if (driverL2vpn.get().isPresent()){ + L2vpn l2vpn = driverL2vpn.get().get(); + L2vpnActivatorTestUtils.checkL2vpn(l2vpn); + + XconnectGroup xconnectGroup = l2vpn.getDatabase().getXconnectGroups().getXconnectGroup().get(0); + assertTrue(xconnectGroup.getP2pXconnects().getP2pXconnect().isEmpty()); + } else { + fail("L2vpn was not found."); + } + } + + private static void checkInterfaceConfigurationDeactivation(CheckedFuture, ReadFailedException> driverInterfaceConfigurations, String deactivatedPort) throws InterruptedException, ExecutionException{ + if (driverInterfaceConfigurations.get().isPresent()){ + InterfaceConfigurations interfaceConfigurations = driverInterfaceConfigurations.get().get(); + L2vpnActivatorTestUtils.checkInterfaceConfigurations(interfaceConfigurations); + + List interfaceConfigurationList = interfaceConfigurations.getInterfaceConfiguration(); + assertFalse(interfaceConfigurationList.stream().anyMatch(x -> x.getInterfaceName().getValue().equals(deactivatedPort))); + } else { + fail("InterfaceConfigurations was not found."); + } } } \ No newline at end of file diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivatorTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivatorTest.java index 5a5e01e5..24e63d21 100644 --- a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivatorTest.java +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivatorTest.java @@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.unimgr.mef.nrp.common.MountPointHelper; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations.InterfaceConfiguration; @@ -29,14 +30,13 @@ import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forw import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.Collections; import java.util.List; import java.util.concurrent.ExecutionException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; +import static org.junit.Assert.*; /** * @author marek.ryznar@amartus.com @@ -44,6 +44,7 @@ import static org.junit.Assert.fail; @RunWith(PowerMockRunner.class) @PrepareForTest(MountPointHelper.class) public class L2vpnBridgeActivatorTest extends AbstractDataBrokerTest{ + private static final Logger log = LoggerFactory.getLogger(L2vpnBridgeActivatorTest.class); private L2vpnBridgeActivator l2vpnBridgeActivator; private MountPointService mountService; @@ -62,7 +63,6 @@ public class L2vpnBridgeActivatorTest extends AbstractDataBrokerTest{ //given DataBroker broker = getDataBroker(); optBroker = Optional.of(broker); - mountService = L2vpnActivatorTestUtils.getMockedMountPointService(optBroker); l2vpnBridgeActivator = new L2vpnBridgeActivator(broker,mountService); @@ -73,13 +73,13 @@ public class L2vpnBridgeActivatorTest extends AbstractDataBrokerTest{ portNo2 = "8080"; port = L2vpnActivatorTestUtils.port("a", "localhost", portNo1); neighbor = L2vpnActivatorTestUtils.port("z", "localhost", portNo2); - mtu = Long.valueOf(1500); + mtu = 1500L; } @Test - public void testActivate(){ + public void testActivateAndDeactivate(){ //when - l2vpnBridgeActivator.activate(nodeName, outerName, innerName, port, neighbor, mtu); + activate(); //then ReadOnlyTransaction transaction = optBroker.get().newReadOnlyTransaction(); @@ -96,41 +96,55 @@ public class L2vpnBridgeActivatorTest extends AbstractDataBrokerTest{ } catch (InterruptedException | ExecutionException e) { fail(e.getMessage()); } - } - @Test - public void testDeactivate(){ //when - l2vpnBridgeActivator.deactivate(nodeName,outerName,innerName,port,neighbor,mtu); + deactivate(); //then - L2vpnActivatorTestUtils.checkDeactivation(optBroker); + L2vpnActivatorTestUtils.checkDeactivated(optBroker,portNo1); + } + + private void deactivate(){ + try { + l2vpnBridgeActivator.deactivate(nodeName,outerName,innerName,port,neighbor,mtu); + } catch (TransactionCommitFailedException e) { + fail("Error during deactivation : " + e.getMessage()); + } + } + + private void activate(){ + log.debug("activate L2VPN"); + try { + l2vpnBridgeActivator.activate(nodeName, outerName, innerName, port, neighbor, mtu); + } catch (TransactionCommitFailedException e) { + fail("Error during activation : " + e.getMessage()); + } } private void checkL2vpnTree(CheckedFuture, ReadFailedException> driverL2vpn) throws InterruptedException, ExecutionException { - if (driverL2vpn.get().isPresent()){ - L2vpn l2vpn = driverL2vpn.get().get(); - L2vpnActivatorTestUtils.checkL2vpn(l2vpn); + if (driverL2vpn.get().isPresent()){ + L2vpn l2vpn = driverL2vpn.get().get(); + L2vpnActivatorTestUtils.checkL2vpn(l2vpn); - XconnectGroup xconnectGroup = l2vpn.getDatabase().getXconnectGroups().getXconnectGroup().get(0); - L2vpnActivatorTestUtils.checkXConnectGroup(xconnectGroup,outerName); + XconnectGroup xconnectGroup = l2vpn.getDatabase().getXconnectGroups().getXconnectGroup().get(0); + L2vpnActivatorTestUtils.checkXConnectGroup(xconnectGroup,outerName); - P2pXconnect p2pXconnect = xconnectGroup.getP2pXconnects().getP2pXconnect().get(0); - L2vpnActivatorTestUtils.checkP2pXconnect(p2pXconnect,innerName); + P2pXconnect p2pXconnect = xconnectGroup.getP2pXconnects().getP2pXconnect().get(0); + L2vpnActivatorTestUtils.checkP2pXconnect(p2pXconnect,innerName); - List attachmentCircuits = p2pXconnect.getAttachmentCircuits().getAttachmentCircuit(); - assertNotNull(attachmentCircuits); - assertEquals(2, attachmentCircuits.size()); + List attachmentCircuits = p2pXconnect.getAttachmentCircuits().getAttachmentCircuit(); + assertNotNull(attachmentCircuits); + assertEquals(2, attachmentCircuits.size()); - attachmentCircuits.sort( - (AttachmentCircuit ac1, AttachmentCircuit ac2) - -> ac1.getName().getValue().compareTo(ac2.getName().getValue())); + attachmentCircuits.sort( + (AttachmentCircuit ac1, AttachmentCircuit ac2) + -> ac1.getName().getValue().compareTo(ac2.getName().getValue())); - L2vpnActivatorTestUtils.checkAttachmentCircuit(attachmentCircuits.get(0), portNo1); - L2vpnActivatorTestUtils.checkAttachmentCircuit(attachmentCircuits.get(1), portNo2); - } else { - fail("L2vpn was not found."); - } + L2vpnActivatorTestUtils.checkAttachmentCircuit(attachmentCircuits.get(0), portNo1); + L2vpnActivatorTestUtils.checkAttachmentCircuit(attachmentCircuits.get(1), portNo2); + } else { + fail("L2vpn was not found."); + } } private void checkInterfaceConfigurationTree(CheckedFuture, ReadFailedException> driverInterfaceConfigurations) throws InterruptedException, ExecutionException{ @@ -149,4 +163,4 @@ public class L2vpnBridgeActivatorTest extends AbstractDataBrokerTest{ fail("InterfaceConfigurations was not found."); } } -} +} \ No newline at end of file diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivatorTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivatorTest.java index 6a0a6e7a..8c309aaf 100644 --- a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivatorTest.java +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivatorTest.java @@ -10,6 +10,7 @@ package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.activator; import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -18,6 +19,7 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.unimgr.mef.nrp.common.MountPointHelper; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730.InterfaceConfigurations; import org.opendaylight.yang.gen.v1.http.cisco.com.ns.yang.cisco.ios.xr.ifmgr.cfg.rev150730._interface.configurations.InterfaceConfiguration; @@ -76,9 +78,13 @@ public class L2vpnXconnectActivatorTest extends AbstractDataBrokerTest { } @Test - public void testActivate(){ + public void testActivateAndDeactivate(){ //when - l2vpnXconnectActivator.activate(nodeName, outerName, innerName, port, neighbor, mtu); + try { + l2vpnXconnectActivator.activate(nodeName, outerName, innerName, port, neighbor, mtu); + } catch (TransactionCommitFailedException e) { + fail("Error during activation : " + e.getMessage()); + } //then ReadOnlyTransaction transaction = optBroker.get().newReadOnlyTransaction(); @@ -95,15 +101,21 @@ public class L2vpnXconnectActivatorTest extends AbstractDataBrokerTest { } catch (InterruptedException | ExecutionException e) { fail(e.getMessage()); } - } - @Test - public void testDeactivate(){ //when - l2vpnXconnectActivator.deactivate(nodeName,outerName,innerName,port,neighbor,mtu); + deactivate(); //then - L2vpnActivatorTestUtils.checkDeactivation(optBroker); + L2vpnActivatorTestUtils.checkDeactivated(optBroker,portNo); + } + + private void deactivate(){ + //when + try { + l2vpnXconnectActivator.deactivate(nodeName,outerName,innerName,port,neighbor,mtu); + } catch (TransactionCommitFailedException e) { + fail("Error during deactivation : " + e.getMessage()); + } } private void checkL2vpnTree(CheckedFuture, ReadFailedException> driverL2vpn) throws InterruptedException, ExecutionException{ @@ -148,4 +160,4 @@ public class L2vpnXconnectActivatorTest extends AbstractDataBrokerTest { } } -} +} \ No newline at end of file diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilderTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilderTest.java new file mode 100644 index 00000000..f1867538 --- /dev/null +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilderTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.driver; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver; +import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.opendaylight.unimgr.utils.NodeTestUtils.*; + +public class L2vpnBridgeDriverBuilderTest { + + private ActivationDriverBuilder.BuilderContext context; + + @Before + public void setUp() { + context = new ActivationDriverBuilder.BuilderContext(); + } + + @Test + public void testDriverForSinglePortNoNode() { + //given + FcPort port = mockFcPort(); + //when + Optional result = new L2vpnBridgeDriverBuilder(mockDataBroker(com.google.common.base.Optional.absent()), null).driverFor(port, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForSinglePortNetconfNode() { + //given + FcPort port = mockFcPort(); + + //when + Optional result = new L2vpnBridgeDriverBuilder(mockDataBroker(mockNetconfNode(false)), null).driverFor(port, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForSinglePortNetconfNodeCapabilities() { + //given + FcPort port = mockFcPort(); + + //when + Optional result = new L2vpnBridgeDriverBuilder(mockDataBroker(mockNetconfNode(true)), null).driverFor(port, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForTwoPortsNoNode() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + Optional result = new L2vpnBridgeDriverBuilder(mockDataBroker(com.google.common.base.Optional.absent()), null).driverFor(portA, portZ, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForTwoPortsNetconfNode() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + Optional result = new L2vpnBridgeDriverBuilder(mockDataBroker(mockNetconfNode(false)), null).driverFor(portA, portZ, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForTwoPortsNetconfNodeCapabilities() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + L2vpnBridgeDriverBuilder driverBuilder = new L2vpnBridgeDriverBuilder(mockDataBroker(mockNetconfNode(true)), null); + Optional result = driverBuilder.driverFor(portA, portZ, context); + + //then + assertTrue(result.isPresent()); + assertEquals(driverBuilder.getDriver().getClass(), result.get().getClass()); + } +} diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilderTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilderTest.java new file mode 100644 index 00000000..3e14c4a6 --- /dev/null +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilderTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.cisco.xr.l2vpn.driver; + +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.unimgr.mef.nrp.api.ActivationDriver; +import org.opendaylight.unimgr.mef.nrp.api.ActivationDriverBuilder; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; + +import java.util.Optional; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.opendaylight.unimgr.utils.NodeTestUtils.*; + +public class L2vpnXconnectDriverBuilderTest { + + private ActivationDriverBuilder.BuilderContext context; + + @Before + public void setUp() { + context = new ActivationDriverBuilder.BuilderContext(); + } + + @Test + public void testDriverForSinglePortNoNode() { + //given + FcPort port = mockFcPort(); + + //when + Optional result = new L2vpnXconnectDriverBuilder(mockDataBroker(com.google.common.base.Optional.absent()), null).driverFor(port, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForSinglePortNetconfNode() { + //given + FcPort port = mockFcPort(); + + //when + Optional result = new L2vpnXconnectDriverBuilder(mockDataBroker(mockNetconfNode(false)), null).driverFor(port, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForSinglePortNetconfNodeCapabilities() { + //given + FcPort port = mockFcPort(); + + //when + L2vpnXconnectDriverBuilder driverBuilder = new L2vpnXconnectDriverBuilder(mockDataBroker(mockNetconfNode(true)), null); + Optional result = driverBuilder.driverFor(port, context); + + //then + assertTrue(result.isPresent()); + assertEquals(driverBuilder.getDriver().getClass(), result.get().getClass()); + } + + @Test + public void testDriverForTwoPortsNoNode() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + Optional result = new L2vpnXconnectDriverBuilder(mockDataBroker(com.google.common.base.Optional.absent()), null).driverFor(portA, portZ, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForTwoPortsNetconfNode() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + Optional result = new L2vpnXconnectDriverBuilder(mockDataBroker(mockNetconfNode(false)), null).driverFor(portA, portZ, context); + + //then + assertFalse(result.isPresent()); + } + + @Test + public void testDriverForTwoPortsNetconfNodeCapabilities() { + //given + FcPort portA = mockFcPort(1); + FcPort portZ = mockFcPort(2); + + //when + Optional result = new L2vpnXconnectDriverBuilder(mockDataBroker(mockNetconfNode(true)), null).driverFor(portA, portZ, context); + + //then + assertFalse(result.isPresent()); + } +} diff --git a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/helper/XConnectHelperTest.java b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/helper/XConnectHelperTest.java index 25e212c9..6d4d3df7 100644 --- a/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/helper/XConnectHelperTest.java +++ b/cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/helper/XConnectHelperTest.java @@ -64,7 +64,6 @@ public class XConnectHelperTest { @Test public void testBuild() { //given - //XConnectHelper xConnectHelper = String xConnectName = "ExampleXConnectName"; String xConnectGroupName = "ExampleXConnectGroupName"; AttachmentCircuits attachmentCircuits = Mockito.mock(AttachmentCircuits.class); diff --git a/impl/pom.xml b/impl/pom.xml index 6f4fbe51..f60e7cd4 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -35,16 +35,29 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL 1.8 + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + test-jar + + + + org.apache.felix maven-bundle-plugin - - - - - + + org.opendaylight.unimgr.mef.nrp.common, + org.opendaylight.unimgr.mef.nrp.api, + org.opendaylight.unimgr.api, + org.opendaylight.unimgr.utils + diff --git a/impl/src/main/java/org/opendaylight/unimgr/impl/ForwardingConstructActivatorService.java b/impl/src/main/java/org/opendaylight/unimgr/impl/ForwardingConstructActivatorService.java index 274a8661..5168388c 100644 --- a/impl/src/main/java/org/opendaylight/unimgr/impl/ForwardingConstructActivatorService.java +++ b/impl/src/main/java/org/opendaylight/unimgr/impl/ForwardingConstructActivatorService.java @@ -60,6 +60,7 @@ public class ForwardingConstructActivatorService { } } else { LOG.warn("No transaction for this activation request {}", forwardingConstruct); + stateTracker.activationFailed(forwardingConstruct); } } } @@ -83,6 +84,7 @@ public class ForwardingConstructActivatorService { } } else { LOG.warn("No transaction for this deactivation request {}", forwardingConstruct); + stateTracker.deactivationFailed(); } } } diff --git a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/api/ActivationDriver.java b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/api/ActivationDriver.java index 62de0f9d..7ef4f61d 100644 --- a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/api/ActivationDriver.java +++ b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/api/ActivationDriver.java @@ -7,6 +7,8 @@ */ package org.opendaylight.unimgr.mef.nrp.api; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.unimgr.mef.nrp.common.ResourceActivatorException; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; @@ -45,12 +47,12 @@ public interface ActivationDriver { /** * Performs the activation action. */ - void activate(); + void activate() throws TransactionCommitFailedException, ResourceActivatorException; /** * Performs the deactivation action. */ - void deactivate(); + void deactivate() throws TransactionCommitFailedException, ResourceActivatorException; /** diff --git a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivator.java b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivator.java index ec61d936..167859e4 100644 --- a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivator.java +++ b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivator.java @@ -8,6 +8,7 @@ package org.opendaylight.unimgr.mef.nrp.common; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; /** @@ -33,7 +34,7 @@ public interface ResourceActivator { * the desired MTU for this forwarding construct */ public void activate(String nodeName, String outerName, String innerName, FcPort flowPoint, FcPort neighbor, - long mtu); + long mtu) throws TransactionCommitFailedException, ResourceActivatorException; /** * Deactivate a service fragment on the node identified by nodeName. @@ -52,5 +53,5 @@ public interface ResourceActivator { * the desired MTU for this forwarding construct */ public void deactivate(String nodeName, String outerName, String innerName, FcPort flowPoint, FcPort neighbor, - long mtu); + long mtu) throws TransactionCommitFailedException, ResourceActivatorException; } diff --git a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivatorException.java b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivatorException.java new file mode 100644 index 00000000..31d6d8cf --- /dev/null +++ b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivatorException.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.common; + +public class ResourceActivatorException extends Exception{ + + private static final long serialVersionUID = 4242336212297338778L; + + public ResourceActivatorException() { + super(); + } + + public ResourceActivatorException(String message) { + super(message); + } + + public ResourceActivatorException(String message, Throwable cause) { + super(message, cause); + } + + +} diff --git a/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceNotAvailableException.java b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceNotAvailableException.java new file mode 100644 index 00000000..2a6213ab --- /dev/null +++ b/impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceNotAvailableException.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.mef.nrp.common; + +/** + * Created by marek.ryznar@amartus.com. + */ +public class ResourceNotAvailableException extends ResourceActivatorException { + public ResourceNotAvailableException(){ + super(); + } + + public ResourceNotAvailableException(String message){ + super(message); + } +} diff --git a/impl/src/main/java/org/opendaylight/unimgr/utils/CapabilitiesService.java b/impl/src/main/java/org/opendaylight/unimgr/utils/CapabilitiesService.java new file mode 100644 index 00000000..cb24738c --- /dev/null +++ b/impl/src/main/java/org/opendaylight/unimgr/utils/CapabilitiesService.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.unimgr.utils; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.BiFunction; + + +public class CapabilitiesService { + + public interface Capability { + enum Mode { + AND, + OR; + } + + BiFunction getCondition(); + } + + public interface Context { + boolean isSupporting(Capability capability); + } + + public static class NodeContext implements Context { + public enum NodeCapability implements Capability { + NETCONF((dbBroker, node) -> node.getAugmentation(NetconfNode.class) != null), + NETCONF_CISCO_IOX_L2VPN((dbBroker, node) -> + checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_L2VPN)), + NETCONF_CISCO_IOX_IFMGR((dbBroker, node) -> + checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_IFMGR)), + NETCONF_CISCO_IOX_POLICYMGR((dbBroker, node) -> + checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_ASR9K_POLICYMGR)), + OVSDB((dbBroker,node) -> node.getAugmentation(OvsdbBridgeAugmentation.class) != null); + + private BiFunction condition; + + NodeCapability(BiFunction condition) { + this.condition = condition; + } + + @Override + public BiFunction getCondition() { + return condition; + } + + private static boolean checkForNetconfCapability(Node node, String netconf_capability){ + return node.getAugmentation(NetconfNode.class) + .getAvailableCapabilities() + .getAvailableCapability() + .stream() + .anyMatch(capability -> capability.getCapability().equals(netconf_capability)); + } + } + + private CapabilitiesService service; + + private Optional nodeOpt; + + NodeContext(CapabilitiesService service, Optional nodeOpt) { + this.service = service; + this.nodeOpt = nodeOpt; + } + + public Optional getNode() { + return nodeOpt; + } + + public boolean isSupporting(Capability capability) { + if (!nodeOpt.isPresent()) { + return false; + } + + return service.checkCondition(capability, nodeOpt.get()); + } + + public boolean isSupporting(Capability.Mode mode, Capability... capabilities) { + boolean result = (mode == Capability.Mode.AND); + + for (Capability capability : capabilities) { + boolean isSupporting = isSupporting(capability); + result = (mode == Capability.Mode.AND ? result && isSupporting: result || isSupporting); + + if(result ^ (mode == Capability.Mode.AND)) { + break; + } + } + + return result; + } + } + + private static final Logger LOG = LoggerFactory.getLogger(CapabilitiesService.class); + + private DataBroker dataBroker; + + public CapabilitiesService(DataBroker dataBroker) { + this.dataBroker = dataBroker; + } + + public NodeContext node(Node node) { + return new NodeContext(this, Optional.of(node)); + } + + public NodeContext nodeByPort(FcPort port) { + return new NodeContext(this, readNode(port)); + } + + private Optional readNode(FcPort port) { + InstanceIdentifier nodeIid = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(port.getTopology())) + .child(Node.class, new NodeKey(port.getNode())) + .build(); + + final ReadTransaction tx = dataBroker.newReadOnlyTransaction(); + final CheckedFuture, ReadFailedException> nodeFuture = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIid); + Optional result = Optional.absent(); + + try { + result = nodeFuture.checkedGet(); + } catch (final ReadFailedException e) { + LOG.error("Unable to read node with Iid {}", nodeIid, e); + } + + return result; + } + + private boolean checkCondition(Capability capability, T data) { + return capability.getCondition().apply(dataBroker, data); + } +} \ No newline at end of file diff --git a/impl/src/main/java/org/opendaylight/unimgr/utils/MdsalUtils.java b/impl/src/main/java/org/opendaylight/unimgr/utils/MdsalUtils.java index c6e98f1f..39721add 100644 --- a/impl/src/main/java/org/opendaylight/unimgr/utils/MdsalUtils.java +++ b/impl/src/main/java/org/opendaylight/unimgr/utils/MdsalUtils.java @@ -15,8 +15,16 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -63,6 +71,31 @@ public class MdsalUtils { return result; } + /** + * Read a specific datastore type and return a optional of DataObject + * @param dataBroker The dataBroker instance to create transactions + * @param store The store type to query + * @param path The generic path to query + * @return Read object optional + */ + public static Optional readOptional( + DataBroker dataBroker, + final LogicalDatastoreType store, + final InstanceIdentifier path) { + + final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction(); + Optional optionalDataObject = Optional.absent(); + final CheckedFuture, ReadFailedException> future = transaction.read(store, path); + try { + optionalDataObject = future.checkedGet(); + } catch (final ReadFailedException e) { + LOG.warn("Failed to read {} ", path, e); + } + + transaction.close(); + return optionalDataObject; + } + /** * Read a specific node from the Operational Data store by default. * @param dataBroker The dataBroker instance to create transactions @@ -148,4 +181,47 @@ public class MdsalUtils { } return Optional.absent(); } + + /** + * Read a specific Link from a specific datastore + * @param dataBroker The dataBroker instance to create transactions + * @param store The datastore type. + * @param topologyName The topology name. + * @return An Optional Link instance + */ + public static final Optional readTopology(DataBroker dataBroker, + LogicalDatastoreType store, + String topologyName) { + final ReadTransaction read = dataBroker.newReadOnlyTransaction(); + final TopologyId topologyId = new TopologyId(topologyName); + InstanceIdentifier topologyInstanceId + = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(topologyId)) + .build(); + final CheckedFuture, ReadFailedException> topologyFuture = read.read(store, topologyInstanceId); + + try { + return topologyFuture.checkedGet(); + } catch (final ReadFailedException e) { + LOG.info("Unable to read topology with Iid {}", topologyInstanceId, e); + } + return Optional.absent(); + } + + /** + * Read a TerminationPoint from datastore used in given FcPort + * @param dataBroker The dataBroker instance to create transactions + * @param store The datastore type. + * @param port FcPort data + * @return An Optional TerminationPoint instance + */ + public static Optional readTerminationPoint(DataBroker dataBroker, LogicalDatastoreType store, FcPort port) { + InstanceIdentifier tpIid = InstanceIdentifier.builder(NetworkTopology.class) + .child(Topology.class, new TopologyKey(port.getTopology())) + .child(Node.class, new NodeKey(port.getNode())) + .child(TerminationPoint.class, new TerminationPointKey(port.getTp())) + .build(); + + return MdsalUtils.readOptional(dataBroker, store, tpIid); + } } diff --git a/impl/src/main/java/org/opendaylight/unimgr/utils/NetconfConstants.java b/impl/src/main/java/org/opendaylight/unimgr/utils/NetconfConstants.java new file mode 100644 index 00000000..59013678 --- /dev/null +++ b/impl/src/main/java/org/opendaylight/unimgr/utils/NetconfConstants.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.utils; + + +public interface NetconfConstants { + final String CAPABILITY_IOX_L2VPN = "(http://cisco.com/ns/yang/Cisco-IOS-XR-l2vpn-cfg?revision=2015-11-09)Cisco-IOS-XR-l2vpn-cfg"; + final String CAPABILITY_IOX_IFMGR = "(http://cisco.com/ns/yang/Cisco-IOS-XR-ifmgr-cfg?revision=2015-07-30)Cisco-IOS-XR-ifmgr-cfg"; + final String CAPABILITY_IOX_ASR9K_POLICYMGR = "(http://cisco.com/ns/yang/Cisco-IOS-XR-asr9k-policymgr-cfg?revision=2015-05-18)Cisco-IOS-XR-asr9k-policymgr-cfg"; +} diff --git a/impl/src/main/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetter.java b/impl/src/main/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetter.java new file mode 100644 index 00000000..1aeba880 --- /dev/null +++ b/impl/src/main/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetter.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.utils; + +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +public class NullAwareDatastoreGetter { + + private static final Logger LOG = LoggerFactory.getLogger(NullAwareDatastoreGetter.class); + + private Optional dataOptional; + + public NullAwareDatastoreGetter(T data) { + this.dataOptional = Optional.ofNullable(data); + } + + public NullAwareDatastoreGetter(Optional dataOptional) { + this.dataOptional = dataOptional; + } + + //TODO temporary, remove after java.util.Optional and com.google.common.base.Optional unification in ODL core + public NullAwareDatastoreGetter(com.google.common.base.Optional dataOptional) { + this.dataOptional = dataOptional.isPresent() ? Optional.ofNullable(dataOptional.get()) : Optional.empty(); + } + + public > NullAwareDatastoreGetter collect(Function> function) { + logDataOptionalStatus(function); + + return new NullAwareDatastoreGetter<>( + dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).get()) : Optional.empty() + ); + } + + public > NullAwareDatastoreGetter collect(Function, R>> function, Class cls) { + logDataOptionalStatus(function); + + return new NullAwareDatastoreGetter<>( + dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).apply(cls)) : Optional.empty() + ); + } + + public > List> collectMany(Function> function) { + logDataOptionalStatus(function); + + List> result = new ArrayList<>(); + + Optional dataCollectionOptional = dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).get()) : Optional.empty(); + + if(dataCollectionOptional.isPresent()) { + dataCollectionOptional.get().forEach(dataObject -> result.add(new NullAwareDatastoreGetter(dataObject))); + } + + return result; + } + + public Optional get() { + return dataOptional; + } + + private void logDataOptionalStatus(Function function) { + if(dataOptional.isPresent()) { + LOG.trace("Before collection of: " + function.toString() + ", currently collected data is non-null: " + dataOptional.get().toString()); + } else { + LOG.debug("Null value encountered during collection of: " + function.toString()); + } + } +} diff --git a/impl/src/test/java/org/opendaylight/unimgr/utils/CapabilitiesServiceTest.java b/impl/src/test/java/org/opendaylight/unimgr/utils/CapabilitiesServiceTest.java new file mode 100644 index 00000000..3f3714fc --- /dev/null +++ b/impl/src/test/java/org/opendaylight/unimgr/utils/CapabilitiesServiceTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.unimgr.utils; + +import com.google.common.base.Optional; +import org.junit.Test; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; +import org.opendaylight.unimgr.utils.CapabilitiesService; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; + +import static org.junit.Assert.*; +import static org.opendaylight.unimgr.utils.NodeTestUtils.*; +import static org.opendaylight.unimgr.utils.CapabilitiesService.Capability.Mode.AND; +import static org.opendaylight.unimgr.utils.CapabilitiesService.NodeContext.NodeCapability.*; + +public class CapabilitiesServiceTest extends AbstractDataBrokerTest { + + @Test + public void testNodeByPortPositive() { + //given + Optional mockedNodeOptional = mockNode(); + DataBroker mockedDataBrocker = mockDataBroker(mockedNodeOptional); + CapabilitiesService capabilitiesService = new CapabilitiesService(mockedDataBrocker); + FcPort mockedFcPort = mockFcPort(); + + //when + CapabilitiesService.NodeContext context = capabilitiesService.nodeByPort(mockedFcPort); + + //then + assertNotNull(context); + assertTrue(context.getNode().isPresent()); + assertEquals(mockedNodeOptional.get(), context.getNode().get()); + } + + @Test + public void testNodeByPortNegative() { + //given + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + CapabilitiesService capabilitiesService = new CapabilitiesService(mockedDataBrocker); + FcPort mockedFcPort = mockFcPort(); + + //when + CapabilitiesService.NodeContext context = capabilitiesService.nodeByPort(mockedFcPort); + + //then + assertNotNull(context); + assertFalse(context.getNode().isPresent()); + } + + + @Test + public void testNode() { + //given + Optional mockedNodeOptional = mockNode(); + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + CapabilitiesService capabilitiesService = new CapabilitiesService(mockedDataBrocker); + + //when + CapabilitiesService.NodeContext context = capabilitiesService.node(mockedNodeOptional.get()); + + //then + assertNotNull(context); + assertTrue(context.getNode().isPresent()); + assertEquals(mockedNodeOptional.get(), context.getNode().get()); + } + + @Test + public void testNodeIsSupportingSingleCapabilityPositive() { + //given + Optional mockedNodeOptional = mockNetconfNode(false); + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + + //when + boolean result = new CapabilitiesService(mockedDataBrocker) + .node(mockedNodeOptional.get()) + .isSupporting(NETCONF); + + //then + assertTrue(result); + } + + @Test + public void testNodeIsSupportingSingleCapabilityNegative() { + //given + Optional mockedNodeOptional = mockNode(); + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + + //when + boolean result = new CapabilitiesService(mockedDataBrocker) + .node(mockedNodeOptional.get()) + .isSupporting(NETCONF); + + //then + assertFalse(result); + } + + @Test + public void testNodeIsSupportingMultipleCapabilitiesPositive() { + //given + Optional mockedNodeOptional = mockNetconfNode(true); + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + + //when + boolean result = new CapabilitiesService(mockedDataBrocker) + .node(mockedNodeOptional.get()) + .isSupporting(AND, NETCONF, NETCONF_CISCO_IOX_L2VPN, NETCONF_CISCO_IOX_IFMGR); + + //then + assertTrue(result); + } + + @Test + public void testNodeIsSupportingMultipleCapabilitiesNegative() { + //given + Optional mockedNodeOptional = mockNode(); + DataBroker mockedDataBrocker = mockDataBroker(Optional.absent()); + + //when + boolean result = new CapabilitiesService(mockedDataBrocker) + .node(mockedNodeOptional.get()) + .isSupporting(AND, NETCONF, NETCONF_CISCO_IOX_L2VPN, NETCONF_CISCO_IOX_IFMGR); + + //then + assertFalse(result); + } +} diff --git a/impl/src/test/java/org/opendaylight/unimgr/utils/MdsalUtilsTest.java b/impl/src/test/java/org/opendaylight/unimgr/utils/MdsalUtilsTest.java index 9989f484..19f5a36e 100644 --- a/impl/src/test/java/org/opendaylight/unimgr/utils/MdsalUtilsTest.java +++ b/impl/src/test/java/org/opendaylight/unimgr/utils/MdsalUtilsTest.java @@ -8,8 +8,7 @@ package org.opendaylight.unimgr.utils; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Matchers.argThat; import static org.mockito.Mockito.doNothing; @@ -32,15 +31,15 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.unimgr.impl.UnimgrConstants; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.*; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; @@ -172,4 +171,90 @@ public class MdsalUtilsTest { assertNotNull(expectedOpt); assertEquals(expectedOpt, optNode); } + + @Test + public void testReadOptionalPositive() throws ReadFailedException { + //given + DataBroker dataBroker = mock(DataBroker.class); + InstanceIdentifier nodeIid = PowerMockito.mock(InstanceIdentifier.class); + ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class); + Optional optionalDataObject = mock(Optional.class); + CheckedFuture, ReadFailedException> future = mock(CheckedFuture.class); + Node exceptedNode = mock(Node.class); + + when(dataBroker.newReadOnlyTransaction()).thenReturn(transaction); + when(transaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(future); + when(future.checkedGet()).thenReturn(optionalDataObject); + when(optionalDataObject.isPresent()).thenReturn(true); + when(optionalDataObject.get()).thenReturn(exceptedNode); + + //when + Optional actualNodeOptional = MdsalUtils.readOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, nodeIid); + + //then + assertNotNull(actualNodeOptional); + assertTrue(actualNodeOptional.isPresent()); + + verify(transaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)); + verify(transaction).close(); + + assertEquals(actualNodeOptional.get(), exceptedNode); + } + + @Test + public void testReadOptionalNegative() throws ReadFailedException { + //given + DataBroker dataBroker = mock(DataBroker.class); + InstanceIdentifier nodeIid = PowerMockito.mock(InstanceIdentifier.class); + ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class); + Optional optionalDataObject = mock(Optional.class); + CheckedFuture, ReadFailedException> future = mock(CheckedFuture.class); + + when(dataBroker.newReadOnlyTransaction()).thenReturn(transaction); + when(transaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(future); + when(future.checkedGet()).thenReturn(optionalDataObject); + when(optionalDataObject.isPresent()).thenReturn(false); + + //when + Optional actualNodeOptional = MdsalUtils.readOptional(dataBroker, LogicalDatastoreType.CONFIGURATION, nodeIid); + + //then + assertNotNull(actualNodeOptional); + assertFalse(actualNodeOptional.isPresent()); + + verify(transaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)); + verify(transaction).close(); + } + + @Test + public void testReadTerminationPoint() throws ReadFailedException { + //given + TerminationPoint expectedTp = mock(TerminationPoint.class); + FcPort fcPort = mock(FcPort.class); + when(fcPort.getNode()).thenReturn(new NodeId("r1")); + when(fcPort.getTopology()).thenReturn(new TopologyId("topology-netconf")); + when(fcPort.getTp()).thenReturn(new TpId("tp1")); + + DataBroker dataBroker = mock(DataBroker.class); + ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class); + Optional optionalDataObject = mock(Optional.class); + CheckedFuture, ReadFailedException> future = mock(CheckedFuture.class); + + when(dataBroker.newReadOnlyTransaction()).thenReturn(transaction); + when(transaction.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(future); + when(future.checkedGet()).thenReturn(optionalDataObject); + when(optionalDataObject.isPresent()).thenReturn(true); + when(optionalDataObject.get()).thenReturn(expectedTp); + + //when + Optional actualTpOptional = MdsalUtils.readTerminationPoint(dataBroker, LogicalDatastoreType.CONFIGURATION, fcPort); + + //then + assertNotNull(actualTpOptional); + assertTrue(actualTpOptional.isPresent()); + assertEquals(expectedTp, actualTpOptional.get()); + + verify(transaction).read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class)); + verify(transaction).close(); + } } diff --git a/impl/src/test/java/org/opendaylight/unimgr/utils/NodeTestUtils.java b/impl/src/test/java/org/opendaylight/unimgr/utils/NodeTestUtils.java new file mode 100644 index 00000000..68167aaa --- /dev/null +++ b/impl/src/test/java/org/opendaylight/unimgr/utils/NodeTestUtils.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016 Cisco Systems Inc and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.utils; + + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import org.mockito.Mockito; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class NodeTestUtils { + public static final String DEVICE_ID = "device"; + + public static final String TOPOLOGY_ID = "topology"; + + public static DataBroker mockDataBroker(Optional nodeOptional) { + DataBroker dataBroker = mock(DataBroker.class); + final ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class); + final CheckedFuture transactionResult = mock(CheckedFuture.class); + + try { + when(transactionResult.checkedGet()).thenReturn(nodeOptional); + } catch (Exception e) { + fail("Cannot create mocks : " + e.getMessage()); + } + when(transaction.read(eq(LogicalDatastoreType.OPERATIONAL), any(InstanceIdentifier.class))).thenReturn(transactionResult); + when(dataBroker.newReadOnlyTransaction()).thenReturn(transaction); + + return dataBroker; + } + + public static FcPort mockFcPort(int nodeNo) { + FcPort mockedFcPort = mock(FcPort.class); + StringBuilder nodeIdBuilder = new StringBuilder(DEVICE_ID); + + if(nodeNo > 0) { + nodeIdBuilder.append("_").append(Integer.toString(nodeNo)); + } + + when(mockedFcPort.getNode()).thenReturn(new NodeId(nodeIdBuilder.toString())); + when(mockedFcPort.getTopology()).thenReturn(new TopologyId(TOPOLOGY_ID)); + + return mockedFcPort; + } + + public static FcPort mockFcPort() { + return mockFcPort(0); + } + + public static Optional mockNode() { + final Node node = mock(Node.class); + when(node.getNodeId()).thenReturn(new NodeId(DEVICE_ID)); + + return Optional.of(node); + } + + public static Optional mockNetconfNode(boolean withNetconfCapabilities) { + Optional mockedNodeOptional = mockNode(); + + List netconfCapabilityList = new ArrayList<>(); + if(withNetconfCapabilities) { + netconfCapabilityList = Arrays.asList(createAvailableCapability(NetconfConstants.CAPABILITY_IOX_L2VPN), + createAvailableCapability(NetconfConstants.CAPABILITY_IOX_IFMGR), + createAvailableCapability(NetconfConstants.CAPABILITY_IOX_ASR9K_POLICYMGR)); + } + + AvailableCapabilities availableCapabilities = Mockito.mock(AvailableCapabilities.class); + when(availableCapabilities.getAvailableCapability()).thenReturn(netconfCapabilityList); + + NetconfNode netconfNode = mock(NetconfNode.class); + when(netconfNode.getAvailableCapabilities()).thenReturn(availableCapabilities); + + Node mockedNode = mockedNodeOptional.get(); + when(mockedNode.getAugmentation(NetconfNode.class)).thenReturn(netconfNode); + + return mockedNodeOptional; + } + + private static AvailableCapability createAvailableCapability(String name){ + AvailableCapabilityBuilder availableCapabilityBuilder = new AvailableCapabilityBuilder(); + availableCapabilityBuilder.setCapability(name); + return availableCapabilityBuilder.build(); + } +} diff --git a/impl/src/test/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetterTest.java b/impl/src/test/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetterTest.java new file mode 100644 index 00000000..e760aee2 --- /dev/null +++ b/impl/src/test/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetterTest.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2016 CableLabs and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.unimgr.utils; + + +import org.junit.Test; +import org.opendaylight.yang.gen.v1.urn.mef.unimgr.ext.rev160725.ForwardingConstruct1; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.forwarding.constructs.ForwardingConstruct; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort; +import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcSpec; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class NullAwareDatastoreGetterTest { + + @Test + public void testCollectNotNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + FcSpec expected = mock(FcSpec.class); + + when(fc.getFcSpec()).thenReturn(expected); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fc) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertTrue(actualOptional.isPresent()); + assertEquals(expected, actualOptional.get()); + } + + @Test + public void testCollectNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + when(fc.getFcSpec()).thenReturn(null); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fc) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertFalse(actualOptional.isPresent()); + } + + @Test + public void testCollectInputNull() { + //given + ForwardingConstruct fc = null; + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fc) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertFalse(actualOptional.isPresent()); + } + + @Test + public void testCollectInputOptionalPresent() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + FcSpec expected = mock(FcSpec.class); + + when(fc.getFcSpec()).thenReturn(expected); + + Optional fcOptional = Optional.of(fc); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fcOptional) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertTrue(actualOptional.isPresent()); + assertEquals(expected, actualOptional.get()); + } + + @Test + public void testCollectInputOptionalAbsent() { + //given + Optional fcOptional = Optional.empty(); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fcOptional) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertFalse(actualOptional.isPresent()); + } + + @Test + public void testCollectInputGoogleOptionalPresent() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + FcSpec expected = mock(FcSpec.class); + + when(fc.getFcSpec()).thenReturn(expected); + + com.google.common.base.Optional fcOptional = com.google.common.base.Optional.of(fc); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fcOptional) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertTrue(actualOptional.isPresent()); + assertEquals(expected, actualOptional.get()); + } + + @Test + public void testCollectInputGoogleOptionalAbsent() { + //given + com.google.common.base.Optional fcOptional = com.google.common.base.Optional.absent(); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fcOptional) + .collect(x -> x::getFcSpec) + .get(); + + //then + assertNotNull(actualOptional); + assertFalse(actualOptional.isPresent()); + } + + @Test + public void testCollectAugmentationNotNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + ForwardingConstruct1 expected = mock(ForwardingConstruct1.class); + + when(fc.getAugmentation(eq(ForwardingConstruct1.class))).thenReturn(expected); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fc) + .collect(x -> x::getAugmentation, ForwardingConstruct1.class) + .get(); + + //then + assertNotNull(actualOptional); + assertTrue(actualOptional.isPresent()); + assertEquals(expected, actualOptional.get()); + } + + @Test + public void testCollectAugmentationNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + when(fc.getAugmentation(eq(ForwardingConstruct1.class))).thenReturn(null); + + //when + Optional actualOptional = new NullAwareDatastoreGetter<>(fc) + .collect(x -> x::getAugmentation, ForwardingConstruct1.class) + .get(); + + //then + assertNotNull(actualOptional); + assertFalse(actualOptional.isPresent()); + } + + @Test + public void testCollectManyNotNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + + FcPort fcPortA = mock(FcPort.class); + FcPort fcPortZ = mock(FcPort.class); + + List fcPorts = new ArrayList<>(); + fcPorts.add(fcPortA); + fcPorts.add(fcPortZ); + + when(fc.getFcPort()).thenReturn(fcPorts); + + //when + List> nullAwareDatastoreGetters = new NullAwareDatastoreGetter<>(fc) + .collectMany(x -> x::getFcPort); + + //then + assertNotNull(nullAwareDatastoreGetters); + assertEquals(2, nullAwareDatastoreGetters.size()); + + NullAwareDatastoreGetter fcPortNadg1 = nullAwareDatastoreGetters.get(0); + assertTrue(fcPortNadg1.get().isPresent()); + assertEquals(fcPortA, fcPortNadg1.get().get()); + + NullAwareDatastoreGetter fcPortNadg2 = nullAwareDatastoreGetters.get(1); + assertTrue(fcPortNadg2.get().isPresent()); + assertEquals(fcPortZ, fcPortNadg2.get().get()); + } + + @Test + public void testCollectManyNull() { + //given + ForwardingConstruct fc = mock(ForwardingConstruct.class); + List fcPorts = null; + + when(fc.getFcPort()).thenReturn(fcPorts); + + //when + List> nullAwareDatastoreGetters = new NullAwareDatastoreGetter<>(fc) + .collectMany(x -> x::getFcPort); + + //then + assertNotNull(nullAwareDatastoreGetters); + assertEquals(0, nullAwareDatastoreGetters.size()); + } +} -- 2.36.6