Refactoring of cisco-xr-driver and impl modules. 53/52353/2
authorMarek Ryznar <marek.ryznar@amartus.com>
Thu, 9 Feb 2017 14:57:17 +0000 (15:57 +0100)
committerMarek Ryznar <marek.ryznar@amartus.com>
Tue, 28 Feb 2017 13:13:19 +0000 (14:13 +0100)
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 <marek.ryznar@amartus.com>
Change-Id: I8c09e798d93bf29864025bfdd53e61e8bd2ef5c7

35 files changed:
api/src/main/yang/cl-unimgr-mef.yang
cisco-xr-driver/pom.xml
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileComposition.java [new file with mode: 0644]
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelper.java [new file with mode: 0644]
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelper.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtils.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/AbstractL2vpnActivator.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivator.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivator.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilder.java
cisco-xr-driver/src/main/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilder.java
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileCompositionTest.java [new file with mode: 0644]
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/BandwidthProfileHelperTest.java [new file with mode: 0644]
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/helper/InterfaceHelperTest.java
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/common/util/LoopbackUtilsTest.java [new file with mode: 0644]
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnActivatorTestUtils.java
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnBridgeActivatorTest.java
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/activator/L2vpnXconnectActivatorTest.java
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnBridgeDriverBuilderTest.java [new file with mode: 0644]
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/driver/L2vpnXconnectDriverBuilderTest.java [new file with mode: 0644]
cisco-xr-driver/src/test/java/org/opendaylight/unimgr/mef/nrp/cisco/xr/l2vpn/helper/XConnectHelperTest.java
impl/pom.xml
impl/src/main/java/org/opendaylight/unimgr/impl/ForwardingConstructActivatorService.java
impl/src/main/java/org/opendaylight/unimgr/mef/nrp/api/ActivationDriver.java
impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivator.java
impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceActivatorException.java [new file with mode: 0644]
impl/src/main/java/org/opendaylight/unimgr/mef/nrp/common/ResourceNotAvailableException.java [new file with mode: 0644]
impl/src/main/java/org/opendaylight/unimgr/utils/CapabilitiesService.java [new file with mode: 0644]
impl/src/main/java/org/opendaylight/unimgr/utils/MdsalUtils.java
impl/src/main/java/org/opendaylight/unimgr/utils/NetconfConstants.java [new file with mode: 0644]
impl/src/main/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetter.java [new file with mode: 0644]
impl/src/test/java/org/opendaylight/unimgr/utils/CapabilitiesServiceTest.java [new file with mode: 0644]
impl/src/test/java/org/opendaylight/unimgr/utils/MdsalUtilsTest.java
impl/src/test/java/org/opendaylight/unimgr/utils/NodeTestUtils.java [new file with mode: 0644]
impl/src/test/java/org/opendaylight/unimgr/utils/NullAwareDatastoreGetterTest.java [new file with mode: 0644]

index 2f6d84dffb6c776cf707b7545fe8acf72b0805e9..a2edb6597bd588b05f8a6bc928cff849f7c8986a 100755 (executable)
@@ -142,4 +142,12 @@ module cl-unimgr-mef {
         uses evc;\r
     }\r
 \r
+    augment "/topo:network-topology/topo:topology/topo:node" {\r
+        description "Augmentation for loopback address nodes under topology";\r
+        ext:augment-identifier "loopback-augmentation";\r
+        leaf loopback-address {\r
+         type inet:ip-address;\r
+        }\r
+    }\r
+\r
 }\r
index f1791d927597ceefb1a39faf1319f1eb3b041263..7dda412bf0185e364440d60e65239447c4df0c41 100644 (file)
@@ -46,6 +46,14 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
             <version>${project.version}</version>
         </dependency>
 
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>unimgr-impl</artifactId>
+            <version>${project.version}</version>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+
         <!-- Cisco -->
         <dependency>
             <groupId>${project.groupId}</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 (file)
index 0000000..22efeb4
--- /dev/null
@@ -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<GNRPBwpFlow> convert(Optional<? extends GNRPBwpFlow> input) {
+        if(input.isPresent()) {
+            return Optional.of(input.get());
+        }
+
+        return Optional.empty();
+    }
+
+    private Optional<IngressBwpFlow> ingressBwProfilePerEvc;
+
+    private Optional<EgressBwpFlow> egressBwProfilePerEvc;
+
+    private Optional<IngressBwpUni> ingressBwProfilePerUni;
+
+    private Optional<EgressBwpUni> egressBwProfilePerUni;
+
+    private Optional<IngressBwpFlow> defaultIngressBwProfile;
+
+    private Optional<EgressBwpFlow> 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<IngressBwpFlow> getIngressBwProfilePerEvc() {
+        return ingressBwProfilePerEvc;
+    }
+
+    public Optional<EgressBwpFlow> getEgressBwProfilePerEvc() {
+        return egressBwProfilePerEvc;
+    }
+
+    public Optional<IngressBwpUni> getIngressBwProfilePerUni() {
+        return ingressBwProfilePerUni;
+    }
+
+    public Optional<EgressBwpUni> getEgressBwProfilePerUni() {
+        return egressBwProfilePerUni;
+    }
+
+    public Optional<IngressBwpFlow> getDefaultIngressBwProfile() {
+        return defaultIngressBwProfile;
+    }
+
+    public Optional<EgressBwpFlow> getDefaultEgressBwProfile() {
+        return defaultEgressBwProfile;
+    }
+
+    public Optional<GNRPBwpFlow> 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<IngressBwpFlow> ingressBwProfilePerEvc;
+
+        private Optional<EgressBwpFlow> egressBwProfilePerEvc;
+
+        private Optional<IngressBwpUni> ingressBwProfilePerUni;
+
+        private Optional<EgressBwpUni> egressBwProfilePerUni;
+
+        private Optional<IngressBwpFlow> defaultIngressBwProfile;
+
+        private Optional<EgressBwpFlow> 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<IngressBwpFlow> ingressBwProfilePerEvc) {
+            this.ingressBwProfilePerEvc = ingressBwProfilePerEvc;
+            return this;
+        }
+
+        public BandwidthProfileCompositionBuilder egressBwProfilePerEvc(Optional<EgressBwpFlow> egressBwProfilePerEvc) {
+            this.egressBwProfilePerEvc = egressBwProfilePerEvc;
+            return this;
+        }
+
+        public BandwidthProfileCompositionBuilder ingressBwProfilePerUni(Optional<IngressBwpUni> ingressBwProfilePerUni) {
+            this.ingressBwProfilePerUni = ingressBwProfilePerUni;
+            return this;
+        }
+
+        public BandwidthProfileCompositionBuilder egressBwProfilePerUni(Optional<EgressBwpUni> egressBwProfilePerUni) {
+            this.egressBwProfilePerUni = egressBwProfilePerUni;
+            return this;
+        }
+
+        public BandwidthProfileCompositionBuilder defaultIngressBwProfile(Optional<IngressBwpFlow> defaultIngressBwProfile) {
+            this.defaultIngressBwProfile = defaultIngressBwProfile;
+            return this;
+        }
+
+        public BandwidthProfileCompositionBuilder defaultEgressBwProfile(Optional<EgressBwpFlow> 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 (file)
index 0000000..07e13e1
--- /dev/null
@@ -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<BandwidthProfileComposition> retrieveBandwidthProfiles(DataBroker dataBroker, FcPort port) {
+        List<BandwidthProfileComposition> bwCompositionList = new ArrayList<>();
+        List<NullAwareDatastoreGetter<LpSpec>> 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<LpSpec> lpSpecNadg : lpSpecNadgs) {
+            NullAwareDatastoreGetter<AdapterSpec1> adapterSpecNadg = lpSpecNadg
+                    .collect(x -> x::getAdapterSpec)
+                    .collect(x -> x::getAugmentation, AdapterSpec1.class);
+
+            NullAwareDatastoreGetter<TerminationSpec1> 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<BandwidthProfileComposition> bandwidthProfiles;
+
+    private List<PolicyMap> policyMaps;
+
+    public BandwidthProfileHelper(DataBroker dataBroker, FcPort port) {
+        bandwidthProfiles = BandwidthProfileHelper.retrieveBandwidthProfiles(dataBroker, port);
+        policyMaps = new ArrayList<>();
+    }
+
+    public List<BandwidthProfileComposition> 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<GNRPBwpFlow> bwProfileOptional = bandwidthProfiles.get(0).get(direction, applicability);
+
+            if (bwProfileOptional.isPresent()) {
+                List<PolicyMapRule> 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<PolicyManager> 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
index 9ff582f3bdb8348a37fd98f1c9c3384e5a5c66fd..83e4c93b97fa1e956046013599509fe2d3dfa127 100644 (file)
@@ -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
index 0bf002fce7f4d4d8cb7c41658840bc33c386d50e..6ceea565945588d73c53b335aa2625adb06902e2 100644 (file)
@@ -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<String, String> 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<Node> 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<Node> getNodeIid(NodeId nodeId, TopologyId topologyId){
+        InstanceIdentifier<Node> nodeInstanceId = InstanceIdentifier.builder(NetworkTopology.class)
+                .child(Topology.class, new TopologyKey(topologyId))
+                .child(Node.class, new NodeKey(nodeId))
+                .build();
+        return nodeInstanceId;
+    }
 }
index 2c98e9859ec19c765bcf0d663cb18031d22cc1d8..e4f10046cf3c43e22ae82a85668278edfece668b 100644 (file)
@@ -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<PolicyManager> 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<P2pXconnect> xconnectId = deactivateXConnect(outerName, innerName);
         InstanceIdentifier<InterfaceConfiguration> 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<PolicyManager> qosConfig) throws TransactionCommitFailedException {
+
         Optional<DataBroker> 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<P2pXconnect>  xconnectId, InstanceIdentifier<InterfaceConfiguration> interfaceConfigurationId) {
+    protected void doDeactivate(String nodeName,
+                                String outerName,
+                                String innerName,
+                                InstanceIdentifier<P2pXconnect> xconnectId,
+                                InstanceIdentifier<InterfaceConfiguration> interfaceConfigurationId) throws TransactionCommitFailedException {
+
         Optional<DataBroker> 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<PolicyManager> 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<P2pXconnect> 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<InterfaceConfiguration> 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
index a9c69319037297d64264fe863d55f025b397a8a7..88343a9d57642cd726cf4ed8a062213a3f88b465 100644 (file)
@@ -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<PolicyManager> 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();
     }
 
index 0d1a3770fc3e53ef34809b73ca56efa09afa1c50..40eb4a151b3390f1dd77c0a0844904d695574811 100644 (file)
@@ -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<PolicyManager> 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();
     }
 
index 7bc05e94e3aa5a611f1fc1ab382d80342fcfec5c..75104d750b92f3373afd1878efcca01a53025d6e 100644 (file)
@@ -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<ActivationDriver> 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();
index ba15346f64b4391a7a7956ae8cb39d25525db525..bc1c2ae9687238ffb0fdb0d2d66616003ede14c4 100644 (file)
@@ -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<ActivationDriver> driverFor(FcPort port,BuilderContext _ctx) {
-        return Optional.of(getDriver());
+    public Optional<ActivationDriver> 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 (file)
index 0000000..c31c271
--- /dev/null
@@ -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<GNRPBwpFlow> actualIngerssDefaultOptional = composition.get(INGRESS, DEFAULT);
+        Optional<GNRPBwpFlow> actualIngressEvcOptional = composition.get(INGRESS, EVC);
+        Optional<GNRPBwpFlow> actualIngerssUniOptional = composition.get(INGRESS, UNI);
+        Optional<GNRPBwpFlow> actualEgerssDefaultOptional = composition.get(EGRESS, DEFAULT);
+        Optional<GNRPBwpFlow> actualEgerssEvcOptional = composition.get(EGRESS, EVC);
+        Optional<GNRPBwpFlow> 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 (file)
index 0000000..a98b606
--- /dev/null
@@ -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<BandwidthProfileComposition> 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<BandwidthProfileComposition> 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<BandwidthProfileComposition> actual  = new BandwidthProfileHelper(dataBroker, fcPort).getBandwidthProfiles();
+
+        //then
+        assertNotNull(actual);
+        assertEquals(0, actual.size());
+    }
+
+    private DataBroker mockDatastore(FcPort fcPort,
+                                     Optional<IngressBwpFlow> ingressDefaultBwp,
+                                     Optional<EgressBwpFlow> egressDefaultBwp,
+                                     Optional<IngressBwpFlow> ingressEvcBwp,
+                                     Optional<EgressBwpFlow> egressEvcBwp,
+                                     Optional<IngressBwpUni> ingressUniBwp,
+                                     Optional<EgressBwpUni> 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<LpList> 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;
+    }
+}
index e921bc05044c9a0aeec735a60a0381ed8a0cad7a..118243943b8e31768e3710bd5a61c923647d7dc9 100644 (file)
@@ -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> mtus = Optional.absent();
+        Optional<Mtus> 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> mtus = Optional.absent();
+        Optional<Mtus> 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 (file)
index 0000000..09f6bcd
--- /dev/null
@@ -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<Node> 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<Node> writeNode(Node node){
+        InstanceIdentifier<Node> nodeInstanceId = LoopbackUtils.getNodeIid(node.getNodeId(),new TopologyId(topoName));
+        WriteTransaction transaction = broker.newWriteOnlyTransaction();
+
+        transaction.put(LogicalDatastoreType.CONFIGURATION, nodeInstanceId, node,true);
+        try {
+            CheckedFuture<Void, TransactionCommitFailedException> 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<Node> 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);
+        }
+    }
+}
index 1f0118b1e382b28cf7e789a59c087a15abc4fb5f..ba92712edeea78c7df19dad2b49ed2d825438263 100644 (file)
@@ -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<DataBroker> 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<DataBroker> 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<DataBroker> optBroker, String deactivatedPort)  {
         ReadOnlyTransaction transaction = optBroker.get().newReadOnlyTransaction();
 
-        InstanceIdentifier<L2vpn> l2vpn = InstanceIdentifier.builder(L2vpn.class).build();
-        InstanceIdentifier<InterfaceConfigurations> interfaceConfigurations = InstanceIdentifier.builder(InterfaceConfigurations.class).build();
+        InstanceIdentifier<L2vpn> l2vpnIid = InstanceIdentifier.builder(L2vpn.class).build();
+        InstanceIdentifier<InterfaceConfigurations> interfaceConfigurationsIid = InstanceIdentifier.builder(InterfaceConfigurations.class).build();
 
-        CheckedFuture<Optional<L2vpn>, ReadFailedException> driverL2vpn = transaction.read(LogicalDatastoreType.CONFIGURATION, l2vpn);
-        CheckedFuture<Optional<InterfaceConfigurations>, ReadFailedException> driverInterfaceConfigurations = transaction.read(LogicalDatastoreType.CONFIGURATION, interfaceConfigurations);
+        CheckedFuture<Optional<L2vpn>, ReadFailedException> driverL2vpn = transaction.read(LogicalDatastoreType.CONFIGURATION, l2vpnIid);
+        CheckedFuture<Optional<InterfaceConfigurations>, 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<Optional<L2vpn>, 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<Optional<InterfaceConfigurations>, ReadFailedException> driverInterfaceConfigurations, String deactivatedPort) throws InterruptedException, ExecutionException{
+        if (driverInterfaceConfigurations.get().isPresent()){
+            InterfaceConfigurations interfaceConfigurations = driverInterfaceConfigurations.get().get();
+            L2vpnActivatorTestUtils.checkInterfaceConfigurations(interfaceConfigurations);
+
+            List<InterfaceConfiguration> 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
index 5a5e01e574cab290b9d62093da69fe47cb8468cf..24e63d212869f15a72d27a4471856027b1cc77c7 100644 (file)
@@ -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<Optional<L2vpn>, 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<AttachmentCircuit> attachmentCircuits = p2pXconnect.getAttachmentCircuits().getAttachmentCircuit();
-           assertNotNull(attachmentCircuits);
-           assertEquals(2, attachmentCircuits.size());
+            List<AttachmentCircuit> 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<Optional<InterfaceConfigurations>, 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
index 6a0a6e7af69f4b7d73f11a6bb78695b78b260bb3..8c309aaf33d0247872e219ad1ed2f9bc80febf33 100644 (file)
@@ -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<Optional<L2vpn>, 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 (file)
index 0000000..f186753
--- /dev/null
@@ -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<ActivationDriver> 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<ActivationDriver> result =  new L2vpnBridgeDriverBuilder(mockDataBroker(mockNetconfNode(false)), null).driverFor(port, context);
+
+        //then
+        assertFalse(result.isPresent());
+    }
+
+    @Test
+    public void testDriverForSinglePortNetconfNodeCapabilities() {
+        //given
+        FcPort port = mockFcPort();
+
+        //when
+        Optional<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> 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 (file)
index 0000000..3e14c4a
--- /dev/null
@@ -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<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> 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<ActivationDriver> result =   new L2vpnXconnectDriverBuilder(mockDataBroker(mockNetconfNode(true)), null).driverFor(portA, portZ, context);
+
+        //then
+        assertFalse(result.isPresent());
+    }
+}
index 25e212c9f28516e39a6030676939f4b30b93252d..6d4d3df7eb4761463f79594521dabca5f35262d0 100644 (file)
@@ -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);
index 6f4fbe51d8a81dff2d61c997df71afc0a1da40ed..f60e7cd4d7144f42f55bb9757b3266cd7d215f53 100644 (file)
@@ -35,16 +35,29 @@ and is available at http://www.eclipse.org/legal/epl-v10.html INTERNAL
                     <target>1.8</target>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>3.0.2</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>test-jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                 <configuration>
                     <instructions>
-<!--                         <Export-Package> -->
-<!--                             org.opendaylight.unimgr.mef.nrp.common, -->
-<!--                             org.opendaylight.unimgr.mef.nrp.api, -->
-<!--                             org.opendaylight.unimgr.api -->
-<!--                         </Export-Package> -->
+                        <Export-Package>
+                            org.opendaylight.unimgr.mef.nrp.common,
+                            org.opendaylight.unimgr.mef.nrp.api,
+                            org.opendaylight.unimgr.api,
+                            org.opendaylight.unimgr.utils
+                        </Export-Package>
                     </instructions>
                 </configuration>
             </plugin>
index 274a8661581959d322deeb1dec782661dd76895a..5168388c4404a2f2b03ed8b755bd01c32ac6895e 100644 (file)
@@ -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();
             }
         }
     }
index 62de0f9deac3627bee7c84cb9970b7ada2309b97..7ef4f61d5942a06c839bfdc0e64a788858d2852b 100644 (file)
@@ -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;
 
 
     /**
index ec61d93691f85cc20da01fc8eb29a06c638cf39c..167859e4777f93ebd2c9a26eac0eacaae7e23f37 100644 (file)
@@ -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 (file)
index 0000000..31d6d8c
--- /dev/null
@@ -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 (file)
index 0000000..2a6213a
--- /dev/null
@@ -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 (file)
index 0000000..cb24738
--- /dev/null
@@ -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<T> {
+        enum Mode {
+            AND,
+            OR;
+        }
+
+        BiFunction<DataBroker, T, Boolean> getCondition();
+    }
+
+    public interface Context<T> {
+        boolean isSupporting(Capability<T> capability);
+    }
+
+    public static class NodeContext implements Context<Node> {
+        public enum NodeCapability implements Capability<Node> {
+            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<DataBroker, Node, Boolean> condition;
+
+            NodeCapability(BiFunction<DataBroker, Node, Boolean> condition) {
+                this.condition = condition;
+            }
+
+            @Override
+            public BiFunction<DataBroker, Node, Boolean> 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<Node> nodeOpt;
+
+        NodeContext(CapabilitiesService service, Optional<Node> nodeOpt) {
+            this.service = service;
+            this.nodeOpt = nodeOpt;
+        }
+
+        public Optional<Node> getNode() {
+            return nodeOpt;
+        }
+
+        public boolean isSupporting(Capability<Node> capability) {
+            if (!nodeOpt.isPresent()) {
+                return false;
+            }
+
+            return service.checkCondition(capability, nodeOpt.get());
+        }
+
+        public boolean isSupporting(Capability.Mode mode, Capability<Node>... 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<Node> readNode(FcPort port) {
+        InstanceIdentifier<Node> 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<Optional<Node>, ReadFailedException> nodeFuture = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIid);
+        Optional<Node> result = Optional.absent();
+
+        try {
+            result = nodeFuture.checkedGet();
+        } catch (final ReadFailedException e) {
+            LOG.error("Unable to read node with Iid {}", nodeIid, e);
+        }
+
+        return result;
+    }
+
+    private <T> boolean checkCondition(Capability<T> capability, T data) {
+        return capability.getCondition().apply(dataBroker, data);
+    }
+}
\ No newline at end of file
index c6e98f1f402f843fdd9ef6070c89401e0103d734..39721add2f9ceb667b8e5915dd77f0e4a0ad6fd6 100644 (file)
@@ -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 <D extends org.opendaylight.yangtools.yang.binding.DataObject> Optional<D> readOptional(
+            DataBroker dataBroker,
+            final LogicalDatastoreType store,
+            final InstanceIdentifier<D> path) {
+
+        final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
+        Optional<D> optionalDataObject = Optional.absent();
+        final CheckedFuture<Optional<D>, 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<Topology> readTopology(DataBroker dataBroker,
+                                                        LogicalDatastoreType store,
+                                                        String topologyName) {
+        final ReadTransaction read = dataBroker.newReadOnlyTransaction();
+        final TopologyId topologyId = new TopologyId(topologyName);
+        InstanceIdentifier<Topology> topologyInstanceId
+            = InstanceIdentifier.builder(NetworkTopology.class)
+                                .child(Topology.class, new TopologyKey(topologyId))
+                                .build();
+        final CheckedFuture<Optional<Topology>, 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<TerminationPoint> 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 (file)
index 0000000..5901367
--- /dev/null
@@ -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 (file)
index 0000000..1aeba88
--- /dev/null
@@ -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<T> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NullAwareDatastoreGetter.class);
+
+    private Optional<T> dataOptional;
+
+    public NullAwareDatastoreGetter(T data) {
+        this.dataOptional = Optional.ofNullable(data);
+    }
+
+    public NullAwareDatastoreGetter(Optional<T> 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<T> dataOptional) {
+        this.dataOptional = dataOptional.isPresent() ? Optional.ofNullable(dataOptional.get()) : Optional.empty();
+    }
+
+    public <R extends ChildOf<? super T>> NullAwareDatastoreGetter<R> collect(Function<T, Supplier<R>> function) {
+        logDataOptionalStatus(function);
+
+        return new NullAwareDatastoreGetter<>(
+                dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).get()) : Optional.empty()
+        );
+    }
+
+    public <R extends Augmentation<T>> NullAwareDatastoreGetter<R> collect(Function<T, Function<Class<R>, R>> function, Class<R> cls) {
+        logDataOptionalStatus(function);
+
+        return new NullAwareDatastoreGetter<>(
+                dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).apply(cls)) : Optional.empty()
+        );
+    }
+
+    public <R extends DataObject, C extends Collection<R>> List<NullAwareDatastoreGetter<R>> collectMany(Function<T, Supplier<C>> function) {
+        logDataOptionalStatus(function);
+
+        List<NullAwareDatastoreGetter<R>> result = new ArrayList<>();
+
+        Optional<C> dataCollectionOptional = dataOptional.isPresent() ? Optional.ofNullable(function.apply(dataOptional.get()).get()) : Optional.empty();
+
+        if(dataCollectionOptional.isPresent()) {
+            dataCollectionOptional.get().forEach(dataObject -> result.add(new NullAwareDatastoreGetter<R>(dataObject)));
+        }
+
+        return result;
+    }
+
+    public Optional<T> 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 (file)
index 0000000..3f3714f
--- /dev/null
@@ -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<Node> 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<Node> 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<Node> 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<Node> 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<Node> 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<Node> 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);
+    }
+}
index 9989f4846aff83651a4ee1b45b52a6cda2b002aa..19f5a36e83110149c23c2d8bac6f2b525e661504 100644 (file)
@@ -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<Node> nodeIid = PowerMockito.mock(InstanceIdentifier.class);
+        ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class);
+        Optional<Node> optionalDataObject = mock(Optional.class);
+        CheckedFuture<Optional<Node>, 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<Node> 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<Node> nodeIid = PowerMockito.mock(InstanceIdentifier.class);
+        ReadOnlyTransaction transaction = mock(ReadOnlyTransaction.class);
+        Optional<Node> optionalDataObject = mock(Optional.class);
+        CheckedFuture<Optional<Node>, 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<Node> 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<TerminationPoint> optionalDataObject = mock(Optional.class);
+        CheckedFuture<Optional<TerminationPoint>, 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<TerminationPoint> 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 (file)
index 0000000..68167aa
--- /dev/null
@@ -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<Node> 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<Node> mockNode() {
+        final Node node = mock(Node.class);
+        when(node.getNodeId()).thenReturn(new NodeId(DEVICE_ID));
+
+        return Optional.of(node);
+    }
+
+    public static Optional<Node> mockNetconfNode(boolean withNetconfCapabilities) {
+        Optional<Node> mockedNodeOptional = mockNode();
+
+        List<AvailableCapability> 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 (file)
index 0000000..e760aee
--- /dev/null
@@ -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<FcSpec> 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<FcSpec> 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<FcSpec> 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<ForwardingConstruct> fcOptional = Optional.of(fc);
+
+        //when
+        Optional<FcSpec> 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<ForwardingConstruct> fcOptional = Optional.empty();
+
+        //when
+        Optional<FcSpec> 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<ForwardingConstruct> fcOptional = com.google.common.base.Optional.of(fc);
+
+        //when
+        Optional<FcSpec> 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<ForwardingConstruct> fcOptional = com.google.common.base.Optional.absent();
+
+        //when
+        Optional<FcSpec> 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<ForwardingConstruct1> 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<ForwardingConstruct1> 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<FcPort> fcPorts = new ArrayList<>();
+        fcPorts.add(fcPortA);
+        fcPorts.add(fcPortZ);
+
+        when(fc.getFcPort()).thenReturn(fcPorts);
+
+        //when
+        List<NullAwareDatastoreGetter<FcPort>> 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<FcPort> fcPorts = null;
+
+        when(fc.getFcPort()).thenReturn(fcPorts);
+
+        //when
+        List<NullAwareDatastoreGetter<FcPort>> nullAwareDatastoreGetters = new NullAwareDatastoreGetter<>(fc)
+                .collectMany(x -> x::getFcPort);
+
+        //then
+        assertNotNull(nullAwareDatastoreGetters);
+        assertEquals(0, nullAwareDatastoreGetters.size());
+    }
+}